@@ -2644,13 +2644,12 @@ JL_DLLEXPORT void jl_gc_mark_queue_objarray(jl_ptls_t ptls, jl_value_t *parent,
2644
2644
gc_mark_objarray (ptls , parent , objs , objs + nobjs , 1 , nptr );
2645
2645
}
2646
2646
2647
- // Enqueue and mark all outgoing references from `new_obj` which have not been marked
2648
- // yet. `meta_updated` is mostly used to make sure we don't update metadata twice for
2649
- // objects which have been enqueued into the `remset`
2650
- FORCE_INLINE void gc_mark_outrefs (jl_ptls_t ptls , jl_gc_markqueue_t * mq , void * _new_obj ,
2651
- int meta_updated )
2647
+ // Enqueue and mark all outgoing references from `new_obj` which have not been marked yet.
2648
+ // `_new_obj` has its lowest bit tagged if it's in the remset (in which case we shouldn't update page metadata)
2649
+ FORCE_INLINE void gc_mark_outrefs (jl_ptls_t ptls , jl_gc_markqueue_t * mq , void * _new_obj )
2652
2650
{
2653
- jl_value_t * new_obj = (jl_value_t * )_new_obj ;
2651
+ int meta_updated = (uintptr_t )_new_obj & GC_REMSET_PTR_TAG ;
2652
+ jl_value_t * new_obj = (jl_value_t * )((uintptr_t )_new_obj & ~(uintptr_t )GC_REMSET_PTR_TAG );
2654
2653
mark_obj : {
2655
2654
jl_taggedvalue_t * o = jl_astaggedvalue (new_obj );
2656
2655
uintptr_t vtag = o -> header & ~(uintptr_t )0xf ;
@@ -2948,7 +2947,7 @@ void gc_mark_loop_serial_(jl_ptls_t ptls, jl_gc_markqueue_t *mq)
2948
2947
if (__unlikely (new_obj == NULL )) {
2949
2948
return ;
2950
2949
}
2951
- gc_mark_outrefs (ptls , mq , new_obj , 0 );
2950
+ gc_mark_outrefs (ptls , mq , new_obj );
2952
2951
}
2953
2952
}
2954
2953
@@ -2997,7 +2996,7 @@ void gc_mark_and_steal(jl_ptls_t ptls)
2997
2996
goto steal ;
2998
2997
}
2999
2998
mark : {
3000
- gc_mark_outrefs (ptls , mq , new_obj , 0 );
2999
+ gc_mark_outrefs (ptls , mq , new_obj );
3001
3000
goto pop ;
3002
3001
}
3003
3002
// Note that for the stealing heuristics, we try to
@@ -3260,9 +3259,9 @@ static void gc_queue_remset(jl_ptls_t ptls, jl_ptls_t ptls2)
3260
3259
size_t len = ptls2 -> heap .last_remset -> len ;
3261
3260
void * * items = ptls2 -> heap .last_remset -> items ;
3262
3261
for (size_t i = 0 ; i < len ; i ++ ) {
3263
- // Objects in the `remset` are already marked,
3264
- // so a `gc_try_claim_and_push` wouldn't work here
3265
- gc_mark_outrefs ( ptls , & ptls -> mark_queue , ( jl_value_t * ) items [ i ], 1 );
3262
+ // Tag the pointer to indicate it's in the remset
3263
+ jl_value_t * v = ( jl_value_t * )(( uintptr_t ) items [ i ] | GC_REMSET_PTR_TAG );
3264
+ gc_ptr_queue_push ( & ptls -> mark_queue , v );
3266
3265
}
3267
3266
}
3268
3267
0 commit comments