@@ -1655,6 +1655,18 @@ void gc_free_pages(void)
16551655 }
16561656}
16571657
1658+ void gc_move_to_global_page_pool (jl_gc_page_stack_t * pgstack )
1659+ {
1660+ while (1 ) {
1661+ jl_gc_pagemeta_t * pg = pop_lf_back (pgstack );
1662+ if (pg == NULL ) {
1663+ break ;
1664+ }
1665+ jl_gc_free_page (pg );
1666+ push_lf_back (& global_page_pool_freed , pg );
1667+ }
1668+ }
1669+
16581670// setup the data-structures for a sweep over all memory pools
16591671static void gc_sweep_pool (void )
16601672{
@@ -1667,7 +1679,7 @@ static void gc_sweep_pool(void)
16671679
16681680 // allocate enough space to hold the end of the free list chain
16691681 // for every thread and pool size
1670- jl_taggedvalue_t * * * pfl = (jl_taggedvalue_t * * * ) alloca (n_threads * JL_GC_N_POOLS * sizeof (jl_taggedvalue_t * * ));
1682+ jl_taggedvalue_t * * * pfl = (jl_taggedvalue_t * * * ) malloc (n_threads * JL_GC_N_POOLS * sizeof (jl_taggedvalue_t * * ));
16711683
16721684 // update metadata of pages that were pointed to by freelist or newpages from a pool
16731685 // i.e. pages being the current allocation target
@@ -1709,7 +1721,7 @@ static void gc_sweep_pool(void)
17091721 }
17101722
17111723 // the actual sweeping
1712- jl_gc_page_stack_t * tmp = (jl_gc_page_stack_t * )alloca (n_threads * sizeof (jl_gc_page_stack_t ));
1724+ jl_gc_page_stack_t * tmp = (jl_gc_page_stack_t * )malloc (n_threads * sizeof (jl_gc_page_stack_t ));
17131725 memset (tmp , 0 , n_threads * sizeof (jl_gc_page_stack_t ));
17141726 jl_atomic_store (& gc_allocd_scratch , tmp );
17151727 gc_sweep_wake_all ();
@@ -1726,6 +1738,7 @@ static void gc_sweep_pool(void)
17261738 }
17271739 }
17281740 }
1741+ free (tmp );
17291742
17301743 // merge free lists
17311744 for (int t_i = 0 ; t_i < n_threads ; t_i ++ ) {
@@ -1756,6 +1769,7 @@ static void gc_sweep_pool(void)
17561769 }
17571770 }
17581771 }
1772+ free (pfl );
17591773
17601774#ifdef _P64 // only enable concurrent sweeping on 64bit
17611775 // wake thread up to sweep concurrently
@@ -2980,11 +2994,13 @@ void gc_mark_clean_reclaim_sets(void)
29802994 // Clean up `reclaim-sets`
29812995 for (int i = 0 ; i < gc_n_threads ; i ++ ) {
29822996 jl_ptls_t ptls2 = gc_all_tls_states [i ];
2983- arraylist_t * reclaim_set2 = & ptls2 -> mark_queue .reclaim_set ;
2984- ws_array_t * a = NULL ;
2985- while ((a = (ws_array_t * )arraylist_pop (reclaim_set2 )) != NULL ) {
2986- free (a -> buffer );
2987- free (a );
2997+ if (ptls2 != NULL ) {
2998+ arraylist_t * reclaim_set2 = & ptls2 -> mark_queue .reclaim_set ;
2999+ ws_array_t * a = NULL ;
3000+ while ((a = (ws_array_t * )arraylist_pop (reclaim_set2 )) != NULL ) {
3001+ free (a -> buffer );
3002+ free (a );
3003+ }
29883004 }
29893005 }
29903006}
@@ -3500,7 +3516,7 @@ static int _jl_gc_collect(jl_ptls_t ptls, jl_gc_collection_t collection)
35003516 ptls2 -> heap .remset -> len = 0 ;
35013517 }
35023518 // free empty GC state for threads that have exited
3503- if (ptls2 -> current_task == NULL ) {
3519+ if (jl_atomic_load_relaxed ( & ptls2 -> current_task ) == NULL ) {
35043520 jl_thread_heap_t * heap = & ptls2 -> heap ;
35053521 if (heap -> weak_refs .len == 0 )
35063522 small_arraylist_free (& heap -> weak_refs );
@@ -3511,9 +3527,14 @@ static int _jl_gc_collect(jl_ptls_t ptls, jl_gc_collection_t collection)
35113527 if (heap -> last_remset -> len == 0 )
35123528 arraylist_free (heap -> last_remset );
35133529 if (ptls2 -> finalizers .len == 0 )
3514- arraylist_free (& ptls -> finalizers );
3530+ arraylist_free (& ptls2 -> finalizers );
35153531 if (ptls2 -> sweep_objs .len == 0 )
3516- arraylist_free (& ptls -> sweep_objs );
3532+ arraylist_free (& ptls2 -> sweep_objs );
3533+ gc_move_to_global_page_pool (& ptls2 -> page_metadata_buffered );
3534+ if (ptls2 -> page_metadata_allocd .bottom == NULL ) {
3535+ free (ptls2 );
3536+ gc_all_tls_states [t_i ] = NULL ;
3537+ }
35173538 }
35183539 }
35193540
0 commit comments