@@ -33,7 +33,24 @@ JL_DLLEXPORT void jl_gc_set_cb_notify_external_free(jl_gc_cb_notify_external_fre
3333
3434inline void maybe_collect (jl_ptls_t ptls )
3535{
36- mmtk_gc_poll (ptls );
36+ // Just do a safe point for general maybe_collect
37+ jl_gc_safepoint_ (ptls );
38+ }
39+
40+ // This is only used for malloc. We need to know if we need to do GC. However, keeping checking with MMTk (mmtk_gc_poll),
41+ // is expensive. So we only check for every few allocations.
42+ static inline void malloc_maybe_collect (jl_ptls_t ptls , size_t sz )
43+ {
44+ // We do not need to carefully maintain malloc_sz_since_last_poll. We just need to
45+ // avoid using mmtk_gc_poll too frequently, and try to be precise on our heap usage
46+ // as much as we can.
47+ if (ptls -> malloc_sz_since_last_poll > 4096 ) {
48+ jl_atomic_store_relaxed (& ptls -> malloc_sz_since_last_poll , 0 );
49+ mmtk_gc_poll (ptls );
50+ } else {
51+ jl_atomic_fetch_add_relaxed (& ptls -> malloc_sz_since_last_poll , sz );
52+ jl_gc_safepoint_ (ptls );
53+ }
3754}
3855
3956
@@ -266,6 +283,9 @@ void jl_init_thread_heap(jl_ptls_t ptls)
266283 memset (& ptls -> gc_num , 0 , sizeof (ptls -> gc_num ));
267284 jl_atomic_store_relaxed (& ptls -> gc_num .allocd , - (int64_t )gc_num .interval );
268285
286+ // Clear the malloc sz count
287+ jl_atomic_store_relaxed (& ptls -> malloc_sz_since_last_poll , 0 );
288+
269289 // Create mutator
270290 MMTk_Mutator mmtk_mutator = mmtk_bind_mutator ((void * )ptls , ptls -> tid );
271291 // Copy the mutator to the thread local storage
@@ -363,7 +383,7 @@ JL_DLLEXPORT void *jl_gc_counted_malloc(size_t sz)
363383 jl_task_t * ct = jl_current_task ;
364384 if (pgcstack && ct -> world_age ) {
365385 jl_ptls_t ptls = ct -> ptls ;
366- maybe_collect (ptls );
386+ malloc_maybe_collect (ptls , sz );
367387 jl_atomic_store_relaxed (& ptls -> gc_num .allocd ,
368388 jl_atomic_load_relaxed (& ptls -> gc_num .allocd ) + sz );
369389 jl_atomic_store_relaxed (& ptls -> gc_num .malloc ,
@@ -379,7 +399,7 @@ JL_DLLEXPORT void *jl_gc_counted_calloc(size_t nm, size_t sz)
379399 jl_task_t * ct = jl_current_task ;
380400 if (pgcstack && ct -> world_age ) {
381401 jl_ptls_t ptls = ct -> ptls ;
382- maybe_collect (ptls );
402+ malloc_maybe_collect (ptls , sz );
383403 jl_atomic_store_relaxed (& ptls -> gc_num .allocd ,
384404 jl_atomic_load_relaxed (& ptls -> gc_num .allocd ) + nm * sz );
385405 jl_atomic_store_relaxed (& ptls -> gc_num .malloc ,
@@ -411,7 +431,7 @@ JL_DLLEXPORT void *jl_gc_counted_realloc_with_old_size(void *p, size_t old, size
411431 jl_task_t * ct = jl_current_task ;
412432 if (pgcstack && ct -> world_age ) {
413433 jl_ptls_t ptls = ct -> ptls ;
414- maybe_collect (ptls );
434+ malloc_maybe_collect (ptls , sz );
415435 if (sz < old )
416436 jl_atomic_store_relaxed (& ptls -> gc_num .freed ,
417437 jl_atomic_load_relaxed (& ptls -> gc_num .freed ) + (old - sz ));
0 commit comments