99#include "julia_atomics.h"
1010#include "julia_gcext.h"
1111#include "julia_assert.h"
12- #ifdef __GLIBC__
13- #include <malloc.h> // for malloc_trim
14- #endif
1512
1613#ifdef __cplusplus
1714extern "C" {
@@ -569,11 +566,6 @@ void jl_gc_count_allocd(size_t sz) JL_NOTSAFEPOINT
569566 jl_batch_accum_heap_size (ptls , sz );
570567}
571568
572- void jl_gc_count_freed (size_t sz ) JL_NOTSAFEPOINT
573- {
574- jl_batch_accum_free_size (jl_current_task -> ptls , sz );
575- }
576-
577569// Only safe to update the heap inside the GC
578570static void combine_thread_gc_counts (jl_gc_num_t * dest , int update_heap ) JL_NOTSAFEPOINT
579571{
@@ -643,13 +635,15 @@ static void jl_gc_free_memory(jl_value_t *v, int isaligned) JL_NOTSAFEPOINT
643635 jl_genericmemory_t * m = (jl_genericmemory_t * )v ;
644636 assert (jl_genericmemory_how (m ) == 1 || jl_genericmemory_how (m ) == 2 );
645637 char * d = (char * )m -> ptr ;
638+ size_t freed_bytes = memory_block_usable_size (d , isaligned );
639+ assert (freed_bytes != 0 );
646640 if (isaligned )
647641 jl_free_aligned (d );
648642 else
649643 free (d );
650644 jl_atomic_store_relaxed (& gc_heap_stats .heap_size ,
651- jl_atomic_load_relaxed (& gc_heap_stats .heap_size ) - jl_genericmemory_nbytes ( m ) );
652- gc_num .freed += jl_genericmemory_nbytes ( m ) ;
645+ jl_atomic_load_relaxed (& gc_heap_stats .heap_size ) - freed_bytes );
646+ gc_num .freed += freed_bytes ;
653647 gc_num .freecall ++ ;
654648}
655649
@@ -3652,14 +3646,69 @@ JL_DLLEXPORT uint64_t jl_gc_get_max_memory(void)
36523646 return max_total_memory ;
36533647}
36543648
3655- // allocation wrappers that track allocation and let collection run
3649+ // allocation wrappers that add to gc pressure
3650+
3651+ JL_DLLEXPORT void * jl_malloc (size_t sz )
3652+ {
3653+ return jl_gc_counted_malloc (sz );
3654+ }
3655+
3656+ //_unchecked_calloc does not check for potential overflow of nm*sz
3657+ STATIC_INLINE void * _unchecked_calloc (size_t nm , size_t sz ) {
3658+ size_t nmsz = nm * sz ;
3659+ return jl_gc_counted_calloc (nmsz , 1 );
3660+ }
3661+
3662+ JL_DLLEXPORT void * jl_calloc (size_t nm , size_t sz )
3663+ {
3664+ if (nm > SSIZE_MAX /sz )
3665+ return NULL ;
3666+ return _unchecked_calloc (nm , sz );
3667+ }
3668+
3669+ JL_DLLEXPORT void jl_free (void * p )
3670+ {
3671+ if (p != NULL ) {
3672+ size_t sz = memory_block_usable_size (p , 0 );
3673+ free (p );
3674+ jl_task_t * ct = jl_get_current_task ();
3675+ if (ct != NULL )
3676+ jl_batch_accum_free_size (ct -> ptls , sz );
3677+ }
3678+ }
3679+
3680+ JL_DLLEXPORT void * jl_realloc (void * p , size_t sz )
3681+ {
3682+ size_t old = p ? memory_block_usable_size (p , 0 ) : 0 ;
3683+ void * data = realloc (p , sz );
3684+ jl_task_t * ct = jl_get_current_task ();
3685+ if (data != NULL && ct != NULL ) {
3686+ sz = memory_block_usable_size (data , 0 );
3687+ jl_ptls_t ptls = ct -> ptls ;
3688+ maybe_collect (ptls );
3689+ if (!(sz < old ))
3690+ jl_atomic_store_relaxed (& ptls -> gc_tls_common .gc_num .allocd ,
3691+ jl_atomic_load_relaxed (& ptls -> gc_tls_common .gc_num .allocd ) + (sz - old ));
3692+ jl_atomic_store_relaxed (& ptls -> gc_tls_common .gc_num .realloc ,
3693+ jl_atomic_load_relaxed (& ptls -> gc_tls_common .gc_num .realloc ) + 1 );
3694+
3695+ int64_t diff = sz - old ;
3696+ if (diff < 0 ) {
3697+ jl_batch_accum_free_size (ptls , - diff );
3698+ }
3699+ else {
3700+ jl_batch_accum_heap_size (ptls , diff );
3701+ }
3702+ }
3703+ return data ;
3704+ }
36563705
36573706JL_DLLEXPORT void * jl_gc_counted_malloc (size_t sz )
36583707{
3659- jl_gcframe_t * * pgcstack = jl_get_pgcstack ();
3660- jl_task_t * ct = jl_current_task ;
36613708 void * data = malloc (sz );
3662- if (data != NULL && pgcstack != NULL && ct -> world_age ) {
3709+ jl_task_t * ct = jl_get_current_task ();
3710+ if (data != NULL && ct != NULL ) {
3711+ sz = memory_block_usable_size (data , 0 );
36633712 jl_ptls_t ptls = ct -> ptls ;
36643713 maybe_collect (ptls );
36653714 jl_atomic_store_relaxed (& ptls -> gc_tls_common .gc_num .allocd ,
@@ -3673,54 +3722,29 @@ JL_DLLEXPORT void *jl_gc_counted_malloc(size_t sz)
36733722
36743723JL_DLLEXPORT void * jl_gc_counted_calloc (size_t nm , size_t sz )
36753724{
3676- jl_gcframe_t * * pgcstack = jl_get_pgcstack ();
3677- jl_task_t * ct = jl_current_task ;
36783725 void * data = calloc (nm , sz );
3679- if (data != NULL && pgcstack != NULL && ct -> world_age ) {
3726+ jl_task_t * ct = jl_get_current_task ();
3727+ if (data != NULL && ct != NULL ) {
3728+ sz = memory_block_usable_size (data , 0 );
36803729 jl_ptls_t ptls = ct -> ptls ;
36813730 maybe_collect (ptls );
36823731 jl_atomic_store_relaxed (& ptls -> gc_tls_common .gc_num .allocd ,
3683- jl_atomic_load_relaxed (& ptls -> gc_tls_common .gc_num .allocd ) + nm * sz );
3732+ jl_atomic_load_relaxed (& ptls -> gc_tls_common .gc_num .allocd ) + sz );
36843733 jl_atomic_store_relaxed (& ptls -> gc_tls_common .gc_num .malloc ,
36853734 jl_atomic_load_relaxed (& ptls -> gc_tls_common .gc_num .malloc ) + 1 );
3686- jl_batch_accum_heap_size (ptls , sz * nm );
3735+ jl_batch_accum_heap_size (ptls , sz );
36873736 }
36883737 return data ;
36893738}
36903739
36913740JL_DLLEXPORT void jl_gc_counted_free_with_size (void * p , size_t sz )
36923741{
3693- jl_gcframe_t * * pgcstack = jl_get_pgcstack ();
3694- jl_task_t * ct = jl_current_task ;
3695- free (p );
3696- if (pgcstack != NULL && ct -> world_age ) {
3697- jl_batch_accum_free_size (ct -> ptls , sz );
3698- }
3742+ return jl_free (p );
36993743}
37003744
37013745JL_DLLEXPORT void * jl_gc_counted_realloc_with_old_size (void * p , size_t old , size_t sz )
37023746{
3703- jl_gcframe_t * * pgcstack = jl_get_pgcstack ();
3704- jl_task_t * ct = jl_current_task ;
3705- void * data = realloc (p , sz );
3706- if (data != NULL && pgcstack != NULL && ct -> world_age ) {
3707- jl_ptls_t ptls = ct -> ptls ;
3708- maybe_collect (ptls );
3709- if (!(sz < old ))
3710- jl_atomic_store_relaxed (& ptls -> gc_tls_common .gc_num .allocd ,
3711- jl_atomic_load_relaxed (& ptls -> gc_tls_common .gc_num .allocd ) + (sz - old ));
3712- jl_atomic_store_relaxed (& ptls -> gc_tls_common .gc_num .realloc ,
3713- jl_atomic_load_relaxed (& ptls -> gc_tls_common .gc_num .realloc ) + 1 );
3714-
3715- int64_t diff = sz - old ;
3716- if (diff < 0 ) {
3717- jl_batch_accum_free_size (ptls , - diff );
3718- }
3719- else {
3720- jl_batch_accum_heap_size (ptls , diff );
3721- }
3722- }
3723- return data ;
3747+ return jl_realloc (p , sz );
37243748}
37253749
37263750// allocating blocks for Arrays and Strings
@@ -3741,11 +3765,13 @@ JL_DLLEXPORT void *jl_gc_managed_malloc(size_t sz)
37413765 if (b == NULL )
37423766 jl_throw (jl_memory_exception );
37433767
3768+ size_t allocated_bytes = memory_block_usable_size (b , 1 );
3769+ assert (allocated_bytes >= allocsz );
37443770 jl_atomic_store_relaxed (& ptls -> gc_tls_common .gc_num .allocd ,
3745- jl_atomic_load_relaxed (& ptls -> gc_tls_common .gc_num .allocd ) + allocsz );
3771+ jl_atomic_load_relaxed (& ptls -> gc_tls_common .gc_num .allocd ) + allocated_bytes );
37463772 jl_atomic_store_relaxed (& ptls -> gc_tls_common .gc_num .malloc ,
37473773 jl_atomic_load_relaxed (& ptls -> gc_tls_common .gc_num .malloc ) + 1 );
3748- jl_batch_accum_heap_size (ptls , allocsz );
3774+ jl_batch_accum_heap_size (ptls , allocated_bytes );
37493775#ifdef _OS_WINDOWS_
37503776 SetLastError (last_error );
37513777#endif
0 commit comments