Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 10 additions & 11 deletions src/gc.c
Original file line number Diff line number Diff line change
Expand Up @@ -2644,13 +2644,12 @@ JL_DLLEXPORT void jl_gc_mark_queue_objarray(jl_ptls_t ptls, jl_value_t *parent,
gc_mark_objarray(ptls, parent, objs, objs + nobjs, 1, nptr);
}

// Enqueue and mark all outgoing references from `new_obj` which have not been marked
// yet. `meta_updated` is mostly used to make sure we don't update metadata twice for
// objects which have been enqueued into the `remset`
FORCE_INLINE void gc_mark_outrefs(jl_ptls_t ptls, jl_gc_markqueue_t *mq, void *_new_obj,
int meta_updated)
// Enqueue and mark all outgoing references from `new_obj` which have not been marked yet.
// `_new_obj` has its lowest bit tagged if it's in the remset (in which case we shouldn't update page metadata)
FORCE_INLINE void gc_mark_outrefs(jl_ptls_t ptls, jl_gc_markqueue_t *mq, void *_new_obj)
{
jl_value_t *new_obj = (jl_value_t *)_new_obj;
int meta_updated = (uintptr_t)_new_obj & GC_REMSET_PTR_TAG;
jl_value_t *new_obj = (jl_value_t *)((uintptr_t)_new_obj & ~(uintptr_t)GC_REMSET_PTR_TAG);
mark_obj: {
jl_taggedvalue_t *o = jl_astaggedvalue(new_obj);
uintptr_t vtag = o->header & ~(uintptr_t)0xf;
Expand Down Expand Up @@ -2948,7 +2947,7 @@ void gc_mark_loop_serial_(jl_ptls_t ptls, jl_gc_markqueue_t *mq)
if (__unlikely(new_obj == NULL)) {
return;
}
gc_mark_outrefs(ptls, mq, new_obj, 0);
gc_mark_outrefs(ptls, mq, new_obj);
}
}

Expand Down Expand Up @@ -2997,7 +2996,7 @@ void gc_mark_and_steal(jl_ptls_t ptls)
goto steal;
}
mark : {
gc_mark_outrefs(ptls, mq, new_obj, 0);
gc_mark_outrefs(ptls, mq, new_obj);
goto pop;
}
// Note that for the stealing heuristics, we try to
Expand Down Expand Up @@ -3260,9 +3259,9 @@ static void gc_queue_remset(jl_ptls_t ptls, jl_ptls_t ptls2)
size_t len = ptls2->heap.last_remset->len;
void **items = ptls2->heap.last_remset->items;
for (size_t i = 0; i < len; i++) {
// Objects in the `remset` are already marked,
// so a `gc_try_claim_and_push` wouldn't work here
gc_mark_outrefs(ptls, &ptls->mark_queue, (jl_value_t *)items[i], 1);
// Tag the pointer to indicate it's in the remset
jl_value_t *v = (jl_value_t *)((uintptr_t)items[i] | GC_REMSET_PTR_TAG);
gc_ptr_queue_push(&ptls->mark_queue, v);
}
}

Expand Down
2 changes: 2 additions & 0 deletions src/gc.h
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,8 @@ typedef struct _jl_gc_chunk_t {
#define GC_PTR_QUEUE_INIT_SIZE (1 << 18) // initial size of queue of `jl_value_t *`
#define GC_CHUNK_QUEUE_INIT_SIZE (1 << 14) // initial size of chunk-queue

#define GC_REMSET_PTR_TAG (0x1) // lowest bit of `jl_value_t *` is tagged if it's in the remset

// layout for big (>2k) objects

JL_EXTENSION typedef struct _bigval_t {
Expand Down