@@ -979,18 +979,18 @@ static inline void *__pool_alloc(pool_t* p, int osize, int end_offset)
979
979
jl_gc_collect ();
980
980
allocd_bytes += osize ;
981
981
}
982
-
983
- if (__unlikely (!p -> freelist )) {
982
+ v = p -> freelist ;
983
+ if (__unlikely (!v )) {
984
984
add_page (p );
985
+ v = p -> freelist ;
985
986
}
986
- v = p -> freelist ;
987
+ end = ( gcval_t * ) & ( GC_PAGE_DATA ( v )[ end_offset ]) ;
987
988
p -> nfree -- ;
988
989
p -> allocd = 1 ;
989
- end = (gcval_t * )& (GC_PAGE_DATA (v )[end_offset ]);
990
- if (__unlikely ((v == end ) | (!p -> linear ))) {
991
- _update_freelist (p , v -> next );
992
- } else {
990
+ if (p -> linear && v != end ) {
993
991
p -> freelist = (gcval_t * )((char * )v + osize );
992
+ } else {
993
+ _update_freelist (p , v -> next );
994
994
}
995
995
v -> flags = 0 ;
996
996
return v ;
@@ -1020,7 +1020,7 @@ static const int sizeclasses[N_POOLS] = {
1020
1020
1021
1021
static int szclass (size_t sz )
1022
1022
{
1023
- #ifndef _P64
1023
+ #ifndef _P64
1024
1024
if (sz <= 8 ) return 0 ;
1025
1025
#endif
1026
1026
if (sz <= 56 ) return ((sz + 3 )/4 ) - 2 ;
@@ -1102,29 +1102,29 @@ static gcval_t** sweep_page(pool_t* p, gcpage_t* pg, gcval_t **pfl, int sweep_ma
1102
1102
freedall = 1 ;
1103
1103
old_nfree += pg -> nfree ;
1104
1104
prev_pfl = pfl ;
1105
+ int pg_gc_bits = 0 ;
1105
1106
if (pg -> gc_bits == GC_MARKED ) {
1106
1107
// skip
1107
1108
if (prev_sweep_mask == GC_MARKED_NOESC && sweep_mask == GC_MARKED_NOESC && !pg -> allocd ) {
1108
- pg_skpd ++ ;
1109
- freedall = 0 ;
1110
1109
if (pg -> fl_begin_offset != (uint16_t )-1 ) {
1111
1110
* pfl = (gcval_t * )PAGE_PFL_BEG (pg );
1112
1111
pfl = prev_pfl = PAGE_PFL_END (pg );
1113
1112
}
1113
+ pg_skpd ++ ;
1114
+ freedall = 0 ;
1115
+ pg_gc_bits = GC_MARKED ;
1114
1116
goto free_page ;
1115
1117
}
1116
- pg -> allocd = 0 ;
1117
1118
}
1118
1119
else if (pg -> gc_bits == GC_CLEAN ) {
1119
- pg -> allocd = 0 ;
1120
1120
goto free_page ;
1121
1121
}
1122
1122
if (sweep_mask == GC_MARKED )
1123
1123
pg -> nmarked = 0 ;
1124
1124
int pg_nfree = 0 ;
1125
1125
gcval_t * * pfl_begin = NULL ;
1126
+ int obj_i = 0 ;
1126
1127
while ((char * )v <= lim ) {
1127
- int obj_i = ((uintptr_t )v - (uintptr_t )data )/8 ;
1128
1128
// we can encouter a queued value at this point
1129
1129
// if a write barrier was moved back between two
1130
1130
// sweeping increments TODO
@@ -1136,23 +1136,27 @@ static gcval_t** sweep_page(pool_t* p, gcpage_t* pg, gcval_t **pfl, int sweep_ma
1136
1136
pfl = & v -> next ;
1137
1137
pfl_begin = pfl_begin ? pfl_begin : pfl ;
1138
1138
pg_nfree ++ ;
1139
- ages [ obj_i / 4 ] &= ~( 3 << ( obj_i % 4 ) * 2 ) ;
1139
+ age = 0 ;
1140
1140
}
1141
1141
else {
1142
1142
if (age >= PROMOTE_AGE ) {
1143
1143
if (sweep_mask == GC_MARKED || bits == GC_MARKED_NOESC ) {
1144
1144
gc_bits (v ) = GC_QUEUED ;
1145
+ } else {
1146
+ pg_gc_bits = GC_MARKED ;
1145
1147
}
1146
1148
}
1147
1149
else if ((sweep_mask & bits ) == sweep_mask ) {
1148
1150
gc_bits (v ) = GC_CLEAN ;
1151
+ } else {
1152
+ pg_gc_bits = GC_MARKED ;
1149
1153
}
1150
-
1151
1154
inc_sat (age , PROMOTE_AGE );
1152
- ages [obj_i /4 ] &= ~(3 << sh );
1153
- ages [obj_i /4 ] |= age << sh ;
1154
1155
freedall = 0 ;
1155
1156
}
1157
+ ages [obj_i /4 ] &= ~(3 << sh );
1158
+ ages [obj_i /4 ] |= age << sh ;
1159
+ obj_i ++ ;
1156
1160
v = (gcval_t * )((char * )v + osize );
1157
1161
}
1158
1162
@@ -1161,6 +1165,7 @@ static gcval_t** sweep_page(pool_t* p, gcpage_t* pg, gcval_t **pfl, int sweep_ma
1161
1165
1162
1166
pg -> nfree = pg_nfree ;
1163
1167
page_done ++ ;
1168
+ pg -> allocd = 0 ;
1164
1169
free_page :
1165
1170
if (sweep_mask == GC_MARKED )
1166
1171
pg -> nmarked = 0 ;
@@ -1192,7 +1197,7 @@ static gcval_t** sweep_page(pool_t* p, gcpage_t* pg, gcval_t **pfl, int sweep_ma
1192
1197
nfree += obj_per_page ;
1193
1198
}
1194
1199
else {
1195
- pg -> gc_bits = GC_MARKED ;
1200
+ pg -> gc_bits = pg_gc_bits ;
1196
1201
pg -> linear = 0 ;
1197
1202
nfree += pg -> nfree ;
1198
1203
}
@@ -1831,7 +1836,6 @@ static void clear_mark(int bits)
1831
1836
{
1832
1837
size_t i ;
1833
1838
pool_t * pool ;
1834
- gcpage_t * pg ;
1835
1839
gcval_t * pv ;
1836
1840
if (!verifying ) {
1837
1841
for (int i = 0 ; i < 4 ; i ++ )
@@ -2040,7 +2044,7 @@ void jl_gc_collect(void)
2040
2044
JL_SIGATOMIC_BEGIN ();
2041
2045
uint64_t t0 = jl_hrtime ();
2042
2046
int recollect = 0 ;
2043
- #if defined(GC_TIME ) || defined( GC_FINAL_STATS )
2047
+ #if defined(GC_TIME )
2044
2048
int wb_activations = mark_sp - saved_mark_sp ;
2045
2049
#endif
2046
2050
if (!sweeping ) {
@@ -2111,9 +2115,10 @@ void jl_gc_collect(void)
2111
2115
total_mark_time += mark_pause ;
2112
2116
#endif
2113
2117
}
2114
- //#ifdef GC_TIME
2115
- int64_t bonus = -1 , SAVE = -1 , SAVE2 = -1 , SAVE3 = -1 , pct = -1 , est_fb = -1 ;
2116
- //#endif
2118
+ #ifdef GC_TIME
2119
+ int64_t bonus = -1 , SAVE = -1 , SAVE2 = -1 , SAVE3 = -1 , pct = -1 ;
2120
+ #endif
2121
+ int64_t estimate_freed = -1 ;
2117
2122
2118
2123
#if defined(GC_TIME ) || defined(GC_FINAL_STATS )
2119
2124
uint64_t post_time = 0 , finalize_time = 0 ;
@@ -2133,7 +2138,7 @@ void jl_gc_collect(void)
2133
2138
#ifdef GC_TIME
2134
2139
post_time = jl_hrtime () - post_time ;
2135
2140
#endif
2136
- est_fb = live_bytes - scanned_bytes - perm_scanned_bytes + actual_allocd ;
2141
+ estimate_freed = live_bytes - scanned_bytes - perm_scanned_bytes + actual_allocd ;
2137
2142
2138
2143
#ifdef GC_VERIFY
2139
2144
//gc_verify_track();
@@ -2151,15 +2156,13 @@ void jl_gc_collect(void)
2151
2156
total_allocd_bytes += allocd_bytes_since_sweep ;
2152
2157
2153
2158
// 5. next collection decision
2154
- if ((est_fb <= 1024 || est_fb < (7 * (actual_allocd /10 ))) && n_pause > 1 ) {
2155
- if (prev_sweep_mask == GC_MARKED ) {
2156
- if (collect_interval <= 2 * (max_collect_interval /5 )) {
2157
- collect_interval = 5 * (collect_interval /2 );
2158
- }
2159
- sweep_mask = GC_MARKED ;
2160
- } else {
2161
- sweep_mask = GC_MARKED ;
2162
- recollect = 1 ;
2159
+ if ((estimate_freed <= 1024 || estimate_freed < (7 * (actual_allocd /10 ))) && n_pause > 1 ) {
2160
+ if (collect_interval <= 2 * (max_collect_interval /5 )) {
2161
+ collect_interval = 5 * (collect_interval /2 );
2162
+ }
2163
+ sweep_mask = GC_MARKED ;
2164
+ if (prev_sweep_mask != GC_MARKED ) {
2165
+ //recollect = 1; // TODO enable this
2163
2166
}
2164
2167
} else {
2165
2168
collect_interval = default_collect_interval ;
@@ -2177,7 +2180,6 @@ void jl_gc_collect(void)
2177
2180
// sweeping is over
2178
2181
// 6. if it is a quick sweep, put back the remembered objects in queued state
2179
2182
// so that we don't trigger the barrier again on them.
2180
- //jl_printf(JL_STDOUT, "SSB PSB %d %d\n", S_sb, S_psb);
2181
2183
if (sweep_mask == GC_MARKED_NOESC ) {
2182
2184
for (int i = 0 ; i < remset -> len ; i ++ ) {
2183
2185
gc_bits (((uintptr_t )remset -> items [i ] & ~(uintptr_t )1 )) = GC_QUEUED ;
@@ -2198,8 +2200,8 @@ void jl_gc_collect(void)
2198
2200
if (sweep_mask == GC_MARKED ) {
2199
2201
tasks .len = 0 ;
2200
2202
}
2201
- SAVE2 = freed_bytes ;
2202
2203
#ifdef GC_TIME
2204
+ SAVE2 = freed_bytes ;
2203
2205
SAVE3 = allocd_bytes_since_sweep ;
2204
2206
pct = actual_allocd ? (freed_bytes * 100 )/actual_allocd : -1 ;
2205
2207
#endif
@@ -2228,7 +2230,7 @@ void jl_gc_collect(void)
2228
2230
total_fin_time += finalize_time + post_time ;
2229
2231
#endif
2230
2232
#ifdef GC_TIME
2231
- JL_PRINTF (JL_STDOUT , "GC sweep pause %.2f ms live %ld kB (freed %d kB EST %d kB [error %d] = %d%% of allocd %d kB b/r %ld/%ld) (%.2f ms in post_mark, %.2f ms in %d fin) (marked in %d inc) mask %d | next in %d kB\n" , NS2MS (sweep_pause ), live_bytes /1024 , SAVE2 /1024 , est_fb /1024 , (SAVE2 - est_fb ), pct , SAVE3 /1024 , bonus /1024 , SAVE /1024 , NS2MS (post_time ), NS2MS (finalize_time ), n_finalized , inc_count , sweep_mask , - allocd_bytes /1024 );
2233
+ JL_PRINTF (JL_STDOUT , "GC sweep pause %.2f ms live %ld kB (freed %d kB EST %d kB [error %d] = %d%% of allocd %d kB b/r %ld/%ld) (%.2f ms in post_mark, %.2f ms in %d fin) (marked in %d inc) mask %d | next in %d kB\n" , NS2MS (sweep_pause ), live_bytes /1024 , SAVE2 /1024 , estimate_freed /1024 , (SAVE2 - estimate_freed ), pct , SAVE3 /1024 , bonus /1024 , SAVE /1024 , NS2MS (post_time ), NS2MS (finalize_time ), n_finalized , inc_count , sweep_mask , - allocd_bytes /1024 );
2232
2234
#endif
2233
2235
}
2234
2236
n_pause ++ ;
@@ -2239,10 +2241,12 @@ void jl_gc_collect(void)
2239
2241
#endif
2240
2242
JL_SIGATOMIC_END ();
2241
2243
jl_in_gc = 0 ;
2242
- if (est_fb != SAVE2 ) {
2244
+ #ifdef GC_TIME
2245
+ if (estimate_freed != SAVE2 ) {
2243
2246
// this should not happen but it does
2244
2247
// mostly because of gc_counted_* allocations
2245
2248
}
2249
+ #endif
2246
2250
if (recollect )
2247
2251
jl_gc_collect ();
2248
2252
}
0 commit comments