@@ -3102,13 +3102,11 @@ static int _jl_gc_collect(jl_ptls_t ptls, jl_gc_collection_t collection)
3102
3102
if (!prev_sweep_full )
3103
3103
promoted_bytes += perm_scanned_bytes - last_perm_scanned_bytes ;
3104
3104
// 5. next collection decision
3105
- int not_freed_enough = estimate_freed < (7 * (actual_allocd /10 ));
3105
+ int not_freed_enough = ( collection == JL_GC_AUTO ) && estimate_freed < (7 * (actual_allocd /10 ));
3106
3106
int nptr = 0 ;
3107
3107
for (int i = 0 ;i < jl_n_threads ;i ++ )
3108
3108
nptr += jl_all_tls_states [i ]-> heap .remset_nptr ;
3109
3109
int large_frontier = nptr * sizeof (void * ) >= default_collect_interval ; // many pointers in the intergen frontier => "quick" mark is not quick
3110
- int sweep_full ;
3111
- int recollect = 0 ;
3112
3110
// trigger a full collection if the number of live bytes doubles since the last full
3113
3111
// collection and then remains at least that high for a while.
3114
3112
if (grown_heap_age == 0 ) {
@@ -3118,36 +3116,48 @@ static int _jl_gc_collect(jl_ptls_t ptls, jl_gc_collection_t collection)
3118
3116
else if (live_bytes >= last_live_bytes ) {
3119
3117
grown_heap_age ++ ;
3120
3118
}
3121
- if ( collection == JL_GC_INCREMENTAL ) {
3122
- sweep_full = 0 ;
3123
- } else if ((collection == JL_GC_FULL || large_frontier ||
3119
+ int sweep_full = 0 ;
3120
+ int recollect = 0 ;
3121
+ if ((large_frontier ||
3124
3122
((not_freed_enough || promoted_bytes >= gc_num .interval ) &&
3125
3123
(promoted_bytes >= default_collect_interval || prev_sweep_full )) ||
3126
- grown_heap_age > 1 ) &&
3127
- gc_num .pause > 1 ) {
3128
- recollect = (collection == JL_GC_FULL );
3129
- if (large_frontier )
3130
- gc_num .interval = last_long_collect_interval ;
3131
- if (not_freed_enough || large_frontier ) {
3132
- if (gc_num .interval <= 2 * (max_collect_interval /5 )) {
3133
- gc_num .interval = 5 * (gc_num .interval / 2 );
3124
+ grown_heap_age > 1 ) && gc_num .pause > 1 ) {
3125
+ sweep_full = 1 ;
3126
+ }
3127
+ // update heuristics only if this GC was automatically triggered
3128
+ if (collection == JL_GC_AUTO ) {
3129
+ if (sweep_full ) {
3130
+ if (large_frontier )
3131
+ gc_num .interval = last_long_collect_interval ;
3132
+ if (not_freed_enough || large_frontier ) {
3133
+ if (gc_num .interval <= 2 * (max_collect_interval /5 )) {
3134
+ gc_num .interval = 5 * (gc_num .interval / 2 );
3135
+ }
3134
3136
}
3137
+ last_long_collect_interval = gc_num .interval ;
3138
+ }
3139
+ else {
3140
+ // reset interval to default, or at least half of live_bytes
3141
+ int64_t half = live_bytes /2 ;
3142
+ if (default_collect_interval < half && half <= max_collect_interval )
3143
+ gc_num .interval = half ;
3144
+ else
3145
+ gc_num .interval = default_collect_interval ;
3135
3146
}
3136
- last_long_collect_interval = gc_num .interval ;
3147
+ }
3148
+ if (gc_sweep_always_full ) {
3137
3149
sweep_full = 1 ;
3138
- promoted_bytes = 0 ;
3139
3150
}
3140
- else {
3141
- // reset interval to default, or at least half of live_bytes
3142
- int64_t half = live_bytes /2 ;
3143
- if (default_collect_interval < half && half <= max_collect_interval )
3144
- gc_num .interval = half ;
3145
- else
3146
- gc_num .interval = default_collect_interval ;
3147
- sweep_full = gc_sweep_always_full ;
3151
+ if (collection == JL_GC_FULL ) {
3152
+ sweep_full = 1 ;
3153
+ recollect = 1 ;
3148
3154
}
3149
- if (sweep_full )
3155
+ if (sweep_full ) {
3156
+ // these are the difference between the number of gc-perm bytes scanned
3157
+ // on the first collection after sweep_full, and the current scan
3150
3158
perm_scanned_bytes = 0 ;
3159
+ promoted_bytes = 0 ;
3160
+ }
3151
3161
scanned_bytes = 0 ;
3152
3162
// 5. start sweeping
3153
3163
JL_PROBE_GC_SWEEP_BEGIN (sweep_full );
0 commit comments