@@ -198,21 +198,32 @@ static void restore(void)
198198
199199static void gc_verify_track (jl_ptls_t ptls )
200200{
201- jl_gc_mark_cache_t * gc_cache = & ptls -> gc_cache ;
201+ // `gc_verify_track` is limited to single-threaded GC
202+ if (jl_n_gcthreads != 0 )
203+ return ;
202204 do {
203- jl_gc_mark_sp_t sp ;
204- gc_mark_sp_init (gc_cache , & sp );
205+ jl_gc_markqueue_t mq ;
206+ jl_gc_markqueue_t * mq2 = & ptls -> mark_queue ;
207+ ws_queue_t * cq = & mq .chunk_queue ;
208+ ws_queue_t * q = & mq .ptr_queue ;
209+ jl_atomic_store_relaxed (& cq -> top , 0 );
210+ jl_atomic_store_relaxed (& cq -> bottom , 0 );
211+ jl_atomic_store_relaxed (& cq -> array , jl_atomic_load_relaxed (& mq2 -> chunk_queue .array ));
212+ jl_atomic_store_relaxed (& q -> top , 0 );
213+ jl_atomic_store_relaxed (& q -> bottom , 0 );
214+ jl_atomic_store_relaxed (& q -> array , jl_atomic_load_relaxed (& mq2 -> ptr_queue .array ));
215+ arraylist_new (& mq .reclaim_set , 32 );
205216 arraylist_push (& lostval_parents_done , lostval );
206217 jl_safe_printf ("Now looking for %p =======\n" , lostval );
207218 clear_mark (GC_CLEAN );
208- gc_mark_queue_all_roots (ptls , & sp );
209- gc_mark_queue_finlist ( gc_cache , & sp , & to_finalize , 0 );
210- for (int i = 0 ; i < gc_n_threads ; i ++ ) {
219+ gc_mark_queue_all_roots (ptls , & mq );
220+ gc_mark_finlist ( & mq , & to_finalize , 0 );
221+ for (int i = 0 ; i < gc_n_threads ;i ++ ) {
211222 jl_ptls_t ptls2 = gc_all_tls_states [i ];
212- gc_mark_queue_finlist ( gc_cache , & sp , & ptls2 -> finalizers , 0 );
223+ gc_mark_finlist ( & mq , & ptls2 -> finalizers , 0 );
213224 }
214- gc_mark_queue_finlist ( gc_cache , & sp , & finalizer_list_marked , 0 );
215- gc_mark_loop (ptls , sp );
225+ gc_mark_finlist ( & mq , & finalizer_list_marked , 0 );
226+ gc_mark_loop_serial_ (ptls , & mq );
216227 if (lostval_parents .len == 0 ) {
217228 jl_safe_printf ("Could not find the missing link. We missed a toplevel root. This is odd.\n" );
218229 break ;
@@ -246,22 +257,35 @@ static void gc_verify_track(jl_ptls_t ptls)
246257
247258void gc_verify (jl_ptls_t ptls )
248259{
249- jl_gc_mark_cache_t * gc_cache = & ptls -> gc_cache ;
250- jl_gc_mark_sp_t sp ;
251- gc_mark_sp_init (gc_cache , & sp );
260+ // `gc_verify` is limited to single-threaded GC
261+ if (jl_n_gcthreads != 0 ) {
262+ jl_safe_printf ("Warn. GC verify disabled in multi-threaded GC\n" );
263+ return ;
264+ }
265+ jl_gc_markqueue_t mq ;
266+ jl_gc_markqueue_t * mq2 = & ptls -> mark_queue ;
267+ ws_queue_t * cq = & mq .chunk_queue ;
268+ ws_queue_t * q = & mq .ptr_queue ;
269+ jl_atomic_store_relaxed (& cq -> top , 0 );
270+ jl_atomic_store_relaxed (& cq -> bottom , 0 );
271+ jl_atomic_store_relaxed (& cq -> array , jl_atomic_load_relaxed (& mq2 -> chunk_queue .array ));
272+ jl_atomic_store_relaxed (& q -> top , 0 );
273+ jl_atomic_store_relaxed (& q -> bottom , 0 );
274+ jl_atomic_store_relaxed (& q -> array , jl_atomic_load_relaxed (& mq2 -> ptr_queue .array ));
275+ arraylist_new (& mq .reclaim_set , 32 );
252276 lostval = NULL ;
253277 lostval_parents .len = 0 ;
254278 lostval_parents_done .len = 0 ;
255279 clear_mark (GC_CLEAN );
256280 gc_verifying = 1 ;
257- gc_mark_queue_all_roots (ptls , & sp );
258- gc_mark_queue_finlist ( gc_cache , & sp , & to_finalize , 0 );
259- for (int i = 0 ; i < gc_n_threads ; i ++ ) {
281+ gc_mark_queue_all_roots (ptls , & mq );
282+ gc_mark_finlist ( & mq , & to_finalize , 0 );
283+ for (int i = 0 ; i < gc_n_threads ;i ++ ) {
260284 jl_ptls_t ptls2 = gc_all_tls_states [i ];
261- gc_mark_queue_finlist ( gc_cache , & sp , & ptls2 -> finalizers , 0 );
285+ gc_mark_finlist ( & mq , & ptls2 -> finalizers , 0 );
262286 }
263- gc_mark_queue_finlist ( gc_cache , & sp , & finalizer_list_marked , 0 );
264- gc_mark_loop (ptls , sp );
287+ gc_mark_finlist ( & mq , & finalizer_list_marked , 0 );
288+ gc_mark_loop_serial_ (ptls , & mq );
265289 int clean_len = bits_save [GC_CLEAN ].len ;
266290 for (int i = 0 ; i < clean_len + bits_save [GC_OLD ].len ; i ++ ) {
267291 jl_taggedvalue_t * v = (jl_taggedvalue_t * )bits_save [i >= clean_len ? GC_OLD : GC_CLEAN ].items [i >= clean_len ? i - clean_len : i ];
@@ -500,7 +524,7 @@ int jl_gc_debug_check_other(void)
500524 return gc_debug_alloc_check (& jl_gc_debug_env .other );
501525}
502526
503- void jl_gc_debug_print_status (void )
527+ void jl_gc_debug_print_status (void ) JL_NOTSAFEPOINT
504528{
505529 uint64_t pool_count = jl_gc_debug_env .pool .num ;
506530 uint64_t other_count = jl_gc_debug_env .other .num ;
@@ -509,7 +533,7 @@ void jl_gc_debug_print_status(void)
509533 pool_count + other_count , pool_count , other_count , gc_num .pause );
510534}
511535
512- void jl_gc_debug_critical_error (void )
536+ void jl_gc_debug_critical_error (void ) JL_NOTSAFEPOINT
513537{
514538 jl_gc_debug_print_status ();
515539 if (!jl_gc_debug_env .wait_for_debugger )
@@ -1264,139 +1288,6 @@ int gc_slot_to_arrayidx(void *obj, void *_slot) JL_NOTSAFEPOINT
12641288 return (slot - start ) / elsize ;
12651289}
12661290
1267- // Print a backtrace from the bottom (start) of the mark stack up to `sp`
1268- // `pc_offset` will be added to `sp` for convenience in the debugger.
1269- NOINLINE void gc_mark_loop_unwind (jl_ptls_t ptls , jl_gc_mark_sp_t sp , int pc_offset )
1270- {
1271- jl_jmp_buf * old_buf = jl_get_safe_restore ();
1272- jl_jmp_buf buf ;
1273- jl_set_safe_restore (& buf );
1274- if (jl_setjmp (buf , 0 ) != 0 ) {
1275- jl_safe_printf ("\n!!! ERROR when unwinding gc mark loop -- ABORTING !!!\n" );
1276- jl_set_safe_restore (old_buf );
1277- return ;
1278- }
1279- void * * top = sp .pc + pc_offset ;
1280- jl_gc_mark_data_t * data_top = sp .data ;
1281- sp .data = ptls -> gc_cache .data_stack ;
1282- sp .pc = ptls -> gc_cache .pc_stack ;
1283- int isroot = 1 ;
1284- while (sp .pc < top ) {
1285- void * pc = * sp .pc ;
1286- const char * prefix = isroot ? "r--" : " `-" ;
1287- isroot = 0 ;
1288- if (pc == gc_mark_label_addrs [GC_MARK_L_marked_obj ]) {
1289- gc_mark_marked_obj_t * data = gc_repush_markdata (& sp , gc_mark_marked_obj_t );
1290- if ((jl_gc_mark_data_t * )data > data_top ) {
1291- jl_safe_printf ("Mark stack unwind overflow -- ABORTING !!!\n" );
1292- break ;
1293- }
1294- jl_safe_printf ("%p: Root object: %p :: %p (bits: %d)\n of type " ,
1295- (void * )data , (void * )data -> obj , (void * )data -> tag , (int )data -> bits );
1296- jl_ ((void * )data -> tag );
1297- isroot = 1 ;
1298- }
1299- else if (pc == gc_mark_label_addrs [GC_MARK_L_scan_only ]) {
1300- gc_mark_marked_obj_t * data = gc_repush_markdata (& sp , gc_mark_marked_obj_t );
1301- if ((jl_gc_mark_data_t * )data > data_top ) {
1302- jl_safe_printf ("Mark stack unwind overflow -- ABORTING !!!\n" );
1303- break ;
1304- }
1305- jl_safe_printf ("%p: Queued root: %p :: %p (bits: %d)\n of type " ,
1306- (void * )data , (void * )data -> obj , (void * )data -> tag , (int )data -> bits );
1307- jl_ ((void * )data -> tag );
1308- isroot = 1 ;
1309- }
1310- else if (pc == gc_mark_label_addrs [GC_MARK_L_finlist ]) {
1311- gc_mark_finlist_t * data = gc_repush_markdata (& sp , gc_mark_finlist_t );
1312- if ((jl_gc_mark_data_t * )data > data_top ) {
1313- jl_safe_printf ("Mark stack unwind overflow -- ABORTING !!!\n" );
1314- break ;
1315- }
1316- jl_safe_printf ("%p: Finalizer list from %p to %p\n" ,
1317- (void * )data , (void * )data -> begin , (void * )data -> end );
1318- isroot = 1 ;
1319- }
1320- else if (pc == gc_mark_label_addrs [GC_MARK_L_objarray ]) {
1321- gc_mark_objarray_t * data = gc_repush_markdata (& sp , gc_mark_objarray_t );
1322- if ((jl_gc_mark_data_t * )data > data_top ) {
1323- jl_safe_printf ("Mark stack unwind overflow -- ABORTING !!!\n" );
1324- break ;
1325- }
1326- jl_safe_printf ("%p: %s Array in object %p :: %p -- [%p, %p)\n of type " ,
1327- (void * )data , prefix , (void * )data -> parent , ((void * * )data -> parent )[-1 ],
1328- (void * )data -> begin , (void * )data -> end );
1329- jl_ (jl_typeof (data -> parent ));
1330- }
1331- else if (pc == gc_mark_label_addrs [GC_MARK_L_obj8 ]) {
1332- gc_mark_obj8_t * data = gc_repush_markdata (& sp , gc_mark_obj8_t );
1333- if ((jl_gc_mark_data_t * )data > data_top ) {
1334- jl_safe_printf ("Mark stack unwind overflow -- ABORTING !!!\n" );
1335- break ;
1336- }
1337- jl_datatype_t * vt = (jl_datatype_t * )jl_typeof (data -> parent );
1338- uint8_t * desc = (uint8_t * )jl_dt_layout_ptrs (vt -> layout );
1339- jl_safe_printf ("%p: %s Object (8bit) %p :: %p -- [%d, %d)\n of type " ,
1340- (void * )data , prefix , (void * )data -> parent , ((void * * )data -> parent )[-1 ],
1341- (int )(data -> begin - desc ), (int )(data -> end - desc ));
1342- jl_ (jl_typeof (data -> parent ));
1343- }
1344- else if (pc == gc_mark_label_addrs [GC_MARK_L_obj16 ]) {
1345- gc_mark_obj16_t * data = gc_repush_markdata (& sp , gc_mark_obj16_t );
1346- if ((jl_gc_mark_data_t * )data > data_top ) {
1347- jl_safe_printf ("Mark stack unwind overflow -- ABORTING !!!\n" );
1348- break ;
1349- }
1350- jl_datatype_t * vt = (jl_datatype_t * )jl_typeof (data -> parent );
1351- uint16_t * desc = (uint16_t * )jl_dt_layout_ptrs (vt -> layout );
1352- jl_safe_printf ("%p: %s Object (16bit) %p :: %p -- [%d, %d)\n of type " ,
1353- (void * )data , prefix , (void * )data -> parent , ((void * * )data -> parent )[-1 ],
1354- (int )(data -> begin - desc ), (int )(data -> end - desc ));
1355- jl_ (jl_typeof (data -> parent ));
1356- }
1357- else if (pc == gc_mark_label_addrs [GC_MARK_L_obj32 ]) {
1358- gc_mark_obj32_t * data = gc_repush_markdata (& sp , gc_mark_obj32_t );
1359- if ((jl_gc_mark_data_t * )data > data_top ) {
1360- jl_safe_printf ("Mark stack unwind overflow -- ABORTING !!!\n" );
1361- break ;
1362- }
1363- jl_datatype_t * vt = (jl_datatype_t * )jl_typeof (data -> parent );
1364- uint32_t * desc = (uint32_t * )jl_dt_layout_ptrs (vt -> layout );
1365- jl_safe_printf ("%p: %s Object (32bit) %p :: %p -- [%d, %d)\n of type " ,
1366- (void * )data , prefix , (void * )data -> parent , ((void * * )data -> parent )[-1 ],
1367- (int )(data -> begin - desc ), (int )(data -> end - desc ));
1368- jl_ (jl_typeof (data -> parent ));
1369- }
1370- else if (pc == gc_mark_label_addrs [GC_MARK_L_stack ]) {
1371- gc_mark_stackframe_t * data = gc_repush_markdata (& sp , gc_mark_stackframe_t );
1372- if ((jl_gc_mark_data_t * )data > data_top ) {
1373- jl_safe_printf ("Mark stack unwind overflow -- ABORTING !!!\n" );
1374- break ;
1375- }
1376- jl_safe_printf ("%p: %s Stack frame %p -- %d of %d (%s)\n" ,
1377- (void * )data , prefix , (void * )data -> s , (int )data -> i ,
1378- (int )data -> nroots >> 1 ,
1379- (data -> nroots & 1 ) ? "indirect" : "direct" );
1380- }
1381- else if (pc == gc_mark_label_addrs [GC_MARK_L_module_binding ]) {
1382- // module_binding
1383- gc_mark_binding_t * data = gc_repush_markdata (& sp , gc_mark_binding_t );
1384- if ((jl_gc_mark_data_t * )data > data_top ) {
1385- jl_safe_printf ("Mark stack unwind overflow -- ABORTING !!!\n" );
1386- break ;
1387- }
1388- jl_safe_printf ("%p: %s Module (bindings) %p (bits %d) -- [%p, %p)\n" ,
1389- (void * )data , prefix , (void * )data -> parent , (int )data -> bits ,
1390- (void * )data -> begin , (void * )data -> end );
1391- }
1392- else {
1393- jl_safe_printf ("Unknown pc %p --- ABORTING !!!\n" , pc );
1394- break ;
1395- }
1396- }
1397- jl_set_safe_restore (old_buf );
1398- }
1399-
14001291static int gc_logging_enabled = 0 ;
14011292
14021293JL_DLLEXPORT void jl_enable_gc_logging (int enable ) {
0 commit comments