Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[rfc] parallel marking #45639

Closed
wants to merge 84 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
84 commits
Select commit Hold shift + click to select a range
59fc823
single gc queue
Jun 7, 2022
871bd2e
only two gc bits
Jun 7, 2022
f98429b
debugging infra
Jun 26, 2022
0815f90
docstrings
Jun 26, 2022
2a6fa8b
1 outref opt
Jul 3, 2022
f01e90a
compiler warning
Jul 3, 2022
e71cc48
deleted tmp files
Jul 3, 2022
8d41596
spacing
Jul 3, 2022
27aca87
fmt
Jul 5, 2022
99a767c
fmt
Jul 5, 2022
c85f362
gc-debug
Jul 5, 2022
2c703f0
ws
Jul 5, 2022
58d3de3
finlist
Jul 5, 2022
8dae1bb
fl
Jul 5, 2022
ea83f4c
init_size
Jul 10, 2022
69b1856
Merge branch 'master' into dcn/ml
d-netto Jul 11, 2022
494947c
passing diffeq benchmark
Jul 14, 2022
6cbe454
added spin master
Jul 14, 2022
beb1f73
pmark
Jul 14, 2022
8c6ce19
pmark in partr
Jul 14, 2022
ad4ce8a
squash
Jul 14, 2022
99e9b03
Merge branch 'dcn/pmark-staging' into dcn/pmark2
Jul 14, 2022
eddbf05
minor fix
Jul 14, 2022
d4dfb11
fmt
Jul 14, 2022
e7eb52e
whitespace fix
Jul 14, 2022
456f363
record time after marking
Jul 14, 2022
cec4bf6
removed tmp files
Jul 14, 2022
0007ba9
debugging infra
Jul 15, 2022
5d35a01
queue functions shouldn't safepoint
Jul 15, 2022
aaed2ce
merge
Jul 15, 2022
13af1c3
include opts
Jul 15, 2022
8cc755e
locked or hack
Jul 16, 2022
01c24f7
Merge branch 'dcn/pmark-staging' of https://github.com/d-netto/julia …
Jul 16, 2022
3aa5fdb
Merge branch 'dcn/pmark-staging' into dcn/pmark2
Jul 16, 2022
199d00a
minor angc fix
Jul 16, 2022
d2b0165
spacing
Jul 16, 2022
694807f
qsize
Jul 16, 2022
6fd68a3
changed ws_queue push
Jul 16, 2022
9d09741
asan fix
Jul 16, 2022
b84c421
asan fix
Jul 16, 2022
ea4fdd1
timeout
Jul 16, 2022
ee0ca0f
changed wait_sweep
Jul 17, 2022
8c7b324
moved barrier
Jul 17, 2022
719cda8
enqueing locally
Jul 18, 2022
dcd6f40
description fixup
Jul 19, 2022
32a43c7
cond wait on wait sweep
Jul 19, 2022
1095550
Merge branch 'dcn/pmark2' of https://github.com/d-netto/julia into dc…
Jul 19, 2022
9ddb89f
fmt
Jul 19, 2022
f7a8766
batching
Jul 20, 2022
580750c
squash
Jul 20, 2022
33c2be6
re-enabled single outref opt
Jul 20, 2022
0517786
single ml call
Jul 20, 2022
323e07d
chunking as ifdef
Jul 21, 2022
80cbc19
chunk fix
Jul 21, 2022
5d0683d
disabled chunking for now
Jul 21, 2022
2880d15
enqueing in single worker
Jul 21, 2022
1fb43e6
single rand n
Jul 21, 2022
71c7bbd
started idemp wsq
Jul 22, 2022
4d060a0
idemp wsq
Jul 22, 2022
8e75983
started ws in chunking
Jul 22, 2022
0741095
work-stealing in chunk-queue
Jul 22, 2022
209e0cc
cl queue as primary
Jul 22, 2022
571c4dd
removed tmp files
Jul 22, 2022
a564b32
angc fix
Jul 22, 2022
b1a6617
small reorganize
Jul 22, 2022
fbf46a6
asan fix
Jul 22, 2022
8f3f6f6
decreased max_refs
Jul 22, 2022
b54a270
pass chunk by ref
Jul 22, 2022
2c77c95
idemp wsq
Jul 24, 2022
638f0a3
chaselev q
Jul 24, 2022
e1c1383
whitespace
Jul 24, 2022
ec63b23
check before cond-wait
Jul 24, 2022
a734158
lifo q
Jul 24, 2022
de0b229
moved few files
Jul 24, 2022
d193d25
fmt
Jul 25, 2022
be19d93
fmt2
Jul 25, 2022
74df322
increased MAX_REFS_AT_ONCE
Jul 25, 2022
9c5b100
minor fmt
Jul 30, 2022
ef220a2
chunking finlist
Aug 3, 2022
0dbb1b1
unroll last iter of marking
Aug 4, 2022
5d5dadc
avoid duplicates in remset
Aug 12, 2022
04e3187
rm useless files
Aug 12, 2022
6be3776
pmark as flag
Sep 8, 2022
23e2e60
passing chunk by ref
Sep 14, 2022
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
1 change: 1 addition & 0 deletions base/options.jl
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ struct JLOptions
nthreads_per_pool::Ptr{Int16}
nprocs::Int32
machine_file::Ptr{UInt8}
parallel_marking::UInt8;
project::Ptr{UInt8}
isinteractive::Int8
color::Int8
Expand Down
6 changes: 3 additions & 3 deletions src/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -44,8 +44,8 @@ SRCS := \
jltypes gf typemap smallintset ast builtins module interpreter symbol \
dlload sys init task array dump staticdata toplevel jl_uv datatype \
simplevector runtime_intrinsics precompile jloptions \
threading partr stackwalk gc gc-debug gc-pages gc-stacks gc-alloc-profiler method \
jlapi signal-handling safepoint timing subtype rtutils \
threading partr stackwalk gc gc-debug gc-pages gc-stacks gc-alloc-profiler wsqueue \
method jlapi signal-handling safepoint timing subtype rtutils \
crc32c APInt-C processor ircode opaque_closure codegen-stubs coverage runtime_ccall

RT_LLVMLINK :=
Expand Down Expand Up @@ -98,7 +98,7 @@ ifeq ($(USE_SYSTEM_LIBUV),0)
UV_HEADERS += uv.h
UV_HEADERS += uv/*.h
endif
PUBLIC_HEADERS := $(BUILDDIR)/julia_version.h $(wildcard $(SRCDIR)/support/*.h) $(addprefix $(SRCDIR)/,julia.h julia_assert.h julia_threads.h julia_fasttls.h julia_locks.h julia_atomics.h jloptions.h)
PUBLIC_HEADERS := $(BUILDDIR)/julia_version.h $(wildcard $(SRCDIR)/support/*.h) $(addprefix $(SRCDIR)/,julia.h julia_assert.h julia_threads.h julia_fasttls.h julia_locks.h julia_atomics.h jloptions.h options.h wsqueue.h)
ifeq ($(OS),WINNT)
PUBLIC_HEADERS += $(addprefix $(SRCDIR)/,win32_ucontext.h)
endif
Expand Down
166 changes: 29 additions & 137 deletions src/gc-debug.c
Original file line number Diff line number Diff line change
Expand Up @@ -198,21 +198,21 @@ static void restore(void)

static void gc_verify_track(jl_ptls_t ptls)
{
jl_gc_mark_cache_t *gc_cache = &ptls->gc_cache;
do {
jl_gc_mark_sp_t sp;
gc_mark_sp_init(gc_cache, &sp);
jl_gc_markqueue_t mq;
mq.current = mq.start = (ptls->mark_queue).start;
mq.end = (ptls->mark_queue).end;
arraylist_push(&lostval_parents_done, lostval);
jl_safe_printf("Now looking for %p =======\n", lostval);
clear_mark(GC_CLEAN);
gc_mark_queue_all_roots(ptls, &sp);
gc_mark_queue_finlist(gc_cache, &sp, &to_finalize, 0);
gc_mark_queue_all_roots(ptls, &mq);
gc_mark_finlist(&mq, &to_finalize, 0);
for (int i = 0;i < jl_n_threads;i++) {
jl_ptls_t ptls2 = jl_all_tls_states[i];
gc_mark_queue_finlist(gc_cache, &sp, &ptls2->finalizers, 0);
gc_mark_finlist(&mq, &ptls2->finalizers, 0);
}
gc_mark_queue_finlist(gc_cache, &sp, &finalizer_list_marked, 0);
gc_mark_loop(ptls, sp);
gc_mark_finlist(&mq, &finalizer_list_marked, 0);
gc_mark_loop_(ptls, &mq);
if (lostval_parents.len == 0) {
jl_safe_printf("Could not find the missing link. We missed a toplevel root. This is odd.\n");
break;
Expand Down Expand Up @@ -246,22 +246,22 @@ static void gc_verify_track(jl_ptls_t ptls)

void gc_verify(jl_ptls_t ptls)
{
jl_gc_mark_cache_t *gc_cache = &ptls->gc_cache;
jl_gc_mark_sp_t sp;
gc_mark_sp_init(gc_cache, &sp);
jl_gc_markqueue_t mq;
mq.current = mq.start = (ptls->mark_queue).start;
mq.end = (ptls->mark_queue).end;
lostval = NULL;
lostval_parents.len = 0;
lostval_parents_done.len = 0;
clear_mark(GC_CLEAN);
gc_verifying = 1;
gc_mark_queue_all_roots(ptls, &sp);
gc_mark_queue_finlist(gc_cache, &sp, &to_finalize, 0);
gc_mark_queue_all_roots(ptls, &mq);
gc_mark_finlist(&mq, &to_finalize, 0);
for (int i = 0;i < jl_n_threads;i++) {
jl_ptls_t ptls2 = jl_all_tls_states[i];
gc_mark_queue_finlist(gc_cache, &sp, &ptls2->finalizers, 0);
gc_mark_finlist(&mq, &ptls2->finalizers, 0);
}
gc_mark_queue_finlist(gc_cache, &sp, &finalizer_list_marked, 0);
gc_mark_loop(ptls, sp);
gc_mark_finlist(&mq, &finalizer_list_marked, 0);
gc_mark_loop_(ptls, &mq);
int clean_len = bits_save[GC_CLEAN].len;
for(int i = 0; i < clean_len + bits_save[GC_OLD].len; i++) {
jl_taggedvalue_t *v = (jl_taggedvalue_t*)bits_save[i >= clean_len ? GC_OLD : GC_CLEAN].items[i >= clean_len ? i - clean_len : i];
Expand Down Expand Up @@ -537,7 +537,6 @@ void gc_scrub_record_task(jl_task_t *t)

static void gc_scrub_range(char *low, char *high)
{
jl_ptls_t ptls = jl_current_task->ptls;
jl_jmp_buf *old_buf = jl_get_safe_restore();
jl_jmp_buf buf;
if (jl_setjmp(buf, 0)) {
Expand Down Expand Up @@ -1269,10 +1268,11 @@ int gc_slot_to_arrayidx(void *obj, void *_slot)
return (slot - start) / elsize;
}

// Print a backtrace from the bottom (start) of the mark stack up to `sp`
// `pc_offset` will be added to `sp` for convenience in the debugger.
NOINLINE void gc_mark_loop_unwind(jl_ptls_t ptls, jl_gc_mark_sp_t sp, int pc_offset)
// Print a backtrace from the `mq->start` of the mark queue up to `mq->current`
// `offset` will be added to `mq->current` for convenience in the debugger.
NOINLINE void gc_mark_loop_unwind(jl_ptls_t ptls, jl_gc_markqueue_t *mq, int offset)
{
#ifdef GC_VERIFY
jl_jmp_buf *old_buf = jl_get_safe_restore();
jl_jmp_buf buf;
jl_set_safe_restore(&buf);
Expand All @@ -1281,125 +1281,17 @@ NOINLINE void gc_mark_loop_unwind(jl_ptls_t ptls, jl_gc_mark_sp_t sp, int pc_off
jl_set_safe_restore(old_buf);
return;
}
void **top = sp.pc + pc_offset;
jl_gc_mark_data_t *data_top = sp.data;
sp.data = ptls->gc_cache.data_stack;
sp.pc = ptls->gc_cache.pc_stack;
int isroot = 1;
while (sp.pc < top) {
void *pc = *sp.pc;
const char *prefix = isroot ? "r--" : " `-";
isroot = 0;
if (pc == gc_mark_label_addrs[GC_MARK_L_marked_obj]) {
gc_mark_marked_obj_t *data = gc_repush_markdata(&sp, gc_mark_marked_obj_t);
if ((jl_gc_mark_data_t *)data > data_top) {
jl_safe_printf("Mark stack unwind overflow -- ABORTING !!!\n");
break;
}
jl_safe_printf("%p: Root object: %p :: %p (bits: %d)\n of type ",
(void*)data, (void*)data->obj, (void*)data->tag, (int)data->bits);
jl_((void*)data->tag);
isroot = 1;
}
else if (pc == gc_mark_label_addrs[GC_MARK_L_scan_only]) {
gc_mark_marked_obj_t *data = gc_repush_markdata(&sp, gc_mark_marked_obj_t);
if ((jl_gc_mark_data_t *)data > data_top) {
jl_safe_printf("Mark stack unwind overflow -- ABORTING !!!\n");
break;
}
jl_safe_printf("%p: Queued root: %p :: %p (bits: %d)\n of type ",
(void*)data, (void*)data->obj, (void*)data->tag, (int)data->bits);
jl_((void*)data->tag);
isroot = 1;
}
else if (pc == gc_mark_label_addrs[GC_MARK_L_finlist]) {
gc_mark_finlist_t *data = gc_repush_markdata(&sp, gc_mark_finlist_t);
if ((jl_gc_mark_data_t *)data > data_top) {
jl_safe_printf("Mark stack unwind overflow -- ABORTING !!!\n");
break;
}
jl_safe_printf("%p: Finalizer list from %p to %p\n",
(void*)data, (void*)data->begin, (void*)data->end);
isroot = 1;
}
else if (pc == gc_mark_label_addrs[GC_MARK_L_objarray]) {
gc_mark_objarray_t *data = gc_repush_markdata(&sp, gc_mark_objarray_t);
if ((jl_gc_mark_data_t *)data > data_top) {
jl_safe_printf("Mark stack unwind overflow -- ABORTING !!!\n");
break;
}
jl_safe_printf("%p: %s Array in object %p :: %p -- [%p, %p)\n of type ",
(void*)data, prefix, (void*)data->parent, ((void**)data->parent)[-1],
(void*)data->begin, (void*)data->end);
jl_(jl_typeof(data->parent));
}
else if (pc == gc_mark_label_addrs[GC_MARK_L_obj8]) {
gc_mark_obj8_t *data = gc_repush_markdata(&sp, gc_mark_obj8_t);
if ((jl_gc_mark_data_t *)data > data_top) {
jl_safe_printf("Mark stack unwind overflow -- ABORTING !!!\n");
break;
}
jl_datatype_t *vt = (jl_datatype_t*)jl_typeof(data->parent);
uint8_t *desc = (uint8_t*)jl_dt_layout_ptrs(vt->layout);
jl_safe_printf("%p: %s Object (8bit) %p :: %p -- [%d, %d)\n of type ",
(void*)data, prefix, (void*)data->parent, ((void**)data->parent)[-1],
(int)(data->begin - desc), (int)(data->end - desc));
jl_(jl_typeof(data->parent));
}
else if (pc == gc_mark_label_addrs[GC_MARK_L_obj16]) {
gc_mark_obj16_t *data = gc_repush_markdata(&sp, gc_mark_obj16_t);
if ((jl_gc_mark_data_t *)data > data_top) {
jl_safe_printf("Mark stack unwind overflow -- ABORTING !!!\n");
break;
}
jl_datatype_t *vt = (jl_datatype_t*)jl_typeof(data->parent);
uint16_t *desc = (uint16_t*)jl_dt_layout_ptrs(vt->layout);
jl_safe_printf("%p: %s Object (16bit) %p :: %p -- [%d, %d)\n of type ",
(void*)data, prefix, (void*)data->parent, ((void**)data->parent)[-1],
(int)(data->begin - desc), (int)(data->end - desc));
jl_(jl_typeof(data->parent));
}
else if (pc == gc_mark_label_addrs[GC_MARK_L_obj32]) {
gc_mark_obj32_t *data = gc_repush_markdata(&sp, gc_mark_obj32_t);
if ((jl_gc_mark_data_t *)data > data_top) {
jl_safe_printf("Mark stack unwind overflow -- ABORTING !!!\n");
break;
}
jl_datatype_t *vt = (jl_datatype_t*)jl_typeof(data->parent);
uint32_t *desc = (uint32_t*)jl_dt_layout_ptrs(vt->layout);
jl_safe_printf("%p: %s Object (32bit) %p :: %p -- [%d, %d)\n of type ",
(void*)data, prefix, (void*)data->parent, ((void**)data->parent)[-1],
(int)(data->begin - desc), (int)(data->end - desc));
jl_(jl_typeof(data->parent));
}
else if (pc == gc_mark_label_addrs[GC_MARK_L_stack]) {
gc_mark_stackframe_t *data = gc_repush_markdata(&sp, gc_mark_stackframe_t);
if ((jl_gc_mark_data_t *)data > data_top) {
jl_safe_printf("Mark stack unwind overflow -- ABORTING !!!\n");
break;
}
jl_safe_printf("%p: %s Stack frame %p -- %d of %d (%s)\n",
(void*)data, prefix, (void*)data->s, (int)data->i,
(int)data->nroots >> 1,
(data->nroots & 1) ? "indirect" : "direct");
}
else if (pc == gc_mark_label_addrs[GC_MARK_L_module_binding]) {
// module_binding
gc_mark_binding_t *data = gc_repush_markdata(&sp, gc_mark_binding_t);
if ((jl_gc_mark_data_t *)data > data_top) {
jl_safe_printf("Mark stack unwind overflow -- ABORTING !!!\n");
break;
}
jl_safe_printf("%p: %s Module (bindings) %p (bits %d) -- [%p, %p)\n",
(void*)data, prefix, (void*)data->parent, (int)data->bits,
(void*)data->begin, (void*)data->end);
}
else {
jl_safe_printf("Unknown pc %p --- ABORTING !!!\n", pc);
break;
}
jl_value_t **start = mq->start;
jl_value_t **end = mq->current + offset;
for (; start < end; start++) {
jl_value_t *obj = *start;
jl_taggedvalue_t *o = jl_astaggedvalue(obj);
jl_safe_printf("Queued object: %p :: (header: %zu) (bits: %zu)\n", obj, (uintptr_t)o->header,
((uintptr_t)o->header & 3));
jl_((void*)(jl_datatype_t *)(o->header & ~(uintptr_t)0xf));
}
jl_set_safe_restore(old_buf);
#endif
}

static int gc_logging_enabled = 0;
Expand Down
Loading