Skip to content

Commit

Permalink
optimize remset marking
Browse files Browse the repository at this point in the history
  • Loading branch information
d-netto committed Mar 8, 2024
1 parent e618369 commit 3e91c69
Show file tree
Hide file tree
Showing 2 changed files with 12 additions and 11 deletions.
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

0 comments on commit 3e91c69

Please sign in to comment.