@@ -697,7 +697,7 @@ static uint64_t old_heap_size = 0;
697
697
static uint64_t old_alloc_diff = 0 ;
698
698
static uint64_t old_freed_diff = 0 ;
699
699
static uint64_t gc_end_time = 0 ;
700
-
700
+ static int thrash_counter = 0 ;
701
701
702
702
// global variables for GC stats
703
703
@@ -3324,7 +3324,7 @@ static int _jl_gc_collect(jl_ptls_t ptls, jl_gc_collection_t collection)
3324
3324
gc_num .last_incremental_sweep = gc_end_time ;
3325
3325
}
3326
3326
3327
- int thrashing = 0 ; // maybe we should report this to the user or error out?
3327
+ int thrashing = thrash_counter > 4 ; // maybe we should report this to the user or error out?
3328
3328
size_t heap_size = jl_atomic_load_relaxed (& gc_heap_stats .heap_size );
3329
3329
double target_allocs = 0.0 ;
3330
3330
double min_interval = default_collect_interval ;
@@ -3343,7 +3343,10 @@ static int _jl_gc_collect(jl_ptls_t ptls, jl_gc_collection_t collection)
3343
3343
old_freed_diff = freed_diff ;
3344
3344
old_pause_time = pause ;
3345
3345
old_heap_size = heap_size ; // TODO: Update these values dynamically instead of just during the GC
3346
- thrashing = gc_time > mutator_time * 98 ? 1 : 0 ;
3346
+ if (gc_time > alloc_time * 95 )
3347
+ thrash_counter += 1 ;
3348
+ else
3349
+ thrash_counter = 0 ;
3347
3350
if (alloc_mem != 0 && alloc_time != 0 && gc_mem != 0 && gc_time != 0 ) {
3348
3351
double alloc_rate = alloc_mem /alloc_time ;
3349
3352
double gc_rate = gc_mem /gc_time ;
@@ -3723,6 +3726,26 @@ JL_DLLEXPORT void *jl_gc_counted_realloc_with_old_size(void *p, size_t old, size
3723
3726
jl_atomic_store_relaxed (& ptls -> gc_num .realloc ,
3724
3727
jl_atomic_load_relaxed (& ptls -> gc_num .realloc ) + 1 );
3725
3728
jl_atomic_fetch_add_relaxed (& gc_heap_stats .heap_size , sz - old );
3729
+
3730
+ int64_t diff = sz - old ;
3731
+ if (diff < 0 ) {
3732
+ uint64_t free_acc = jl_atomic_load_relaxed (& ptls -> gc_num .free_acc );
3733
+ if (free_acc + diff < 16 * 1024 )
3734
+ jl_atomic_store_relaxed (& ptls -> gc_num .free_acc , free_acc + sz );
3735
+ else {
3736
+ jl_atomic_fetch_add_relaxed (& gc_heap_stats .heap_size , - (free_acc + sz ));
3737
+ jl_atomic_store_relaxed (& ptls -> gc_num .free_acc , 0 );
3738
+ }
3739
+ }
3740
+ else {
3741
+ uint64_t alloc_acc = jl_atomic_load_relaxed (& ptls -> gc_num .alloc_acc );
3742
+ if (alloc_acc + diff < 16 * 1024 )
3743
+ jl_atomic_store_relaxed (& ptls -> gc_num .alloc_acc , alloc_acc + diff );
3744
+ else {
3745
+ jl_atomic_fetch_add_relaxed (& gc_heap_stats .heap_size , alloc_acc + diff );
3746
+ jl_atomic_store_relaxed (& ptls -> gc_num .alloc_acc , 0 );
3747
+ }
3748
+ }
3726
3749
}
3727
3750
return realloc (p , sz );
3728
3751
}
@@ -3839,6 +3862,27 @@ static void *gc_managed_realloc_(jl_ptls_t ptls, void *d, size_t sz, size_t olds
3839
3862
jl_atomic_load_relaxed (& ptls -> gc_num .allocd ) + (allocsz - oldsz ));
3840
3863
jl_atomic_store_relaxed (& ptls -> gc_num .realloc ,
3841
3864
jl_atomic_load_relaxed (& ptls -> gc_num .realloc ) + 1 );
3865
+
3866
+ int64_t diff = allocsz - oldsz ;
3867
+ if (diff < 0 ) {
3868
+ uint64_t free_acc = jl_atomic_load_relaxed (& ptls -> gc_num .free_acc );
3869
+ if (free_acc + diff < 16 * 1024 )
3870
+ jl_atomic_store_relaxed (& ptls -> gc_num .free_acc , free_acc + sz );
3871
+ else {
3872
+ jl_atomic_fetch_add_relaxed (& gc_heap_stats .heap_size , - (free_acc + sz ));
3873
+ jl_atomic_store_relaxed (& ptls -> gc_num .free_acc , 0 );
3874
+ }
3875
+ }
3876
+ else {
3877
+ uint64_t alloc_acc = jl_atomic_load_relaxed (& ptls -> gc_num .alloc_acc );
3878
+ if (alloc_acc + diff < 16 * 1024 )
3879
+ jl_atomic_store_relaxed (& ptls -> gc_num .alloc_acc , alloc_acc + diff );
3880
+ else {
3881
+ jl_atomic_fetch_add_relaxed (& gc_heap_stats .heap_size , alloc_acc + diff );
3882
+ jl_atomic_store_relaxed (& ptls -> gc_num .alloc_acc , 0 );
3883
+ }
3884
+ }
3885
+
3842
3886
jl_atomic_fetch_add_relaxed (& gc_heap_stats .heap_size , allocsz - oldsz );
3843
3887
int last_errno = errno ;
3844
3888
#ifdef _OS_WINDOWS_
0 commit comments