Skip to content

Commit

Permalink
Merge pull request #21590 from JuliaLang/yyc/gc/mark2
Browse files Browse the repository at this point in the history
Implement GC mark loop
  • Loading branch information
yuyichao authored May 7, 2017
2 parents f4cd98b + 96d23d9 commit 38417ec
Show file tree
Hide file tree
Showing 6 changed files with 1,209 additions and 399 deletions.
197 changes: 187 additions & 10 deletions src/gc-debug.c
Original file line number Diff line number Diff line change
Expand Up @@ -198,18 +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 {
gc_mark_sp_t sp;
gc_mark_sp_init(gc_cache, &sp);
arraylist_push(&lostval_parents_done, lostval);
jl_printf(JL_STDERR, "Now looking for %p =======\n", lostval);
clear_mark(GC_CLEAN);
mark_all_roots(ptls);
gc_mark_object_list(ptls, &to_finalize, 0);
gc_mark_queue_all_roots(ptls, &sp);
gc_mark_queue_finlist(gc_cache, &sp, &to_finalize, 0);
for (int i = 0;i < jl_n_threads;i++) {
jl_ptls_t ptls2 = jl_all_tls_states[i];
gc_mark_object_list(ptls, &ptls2->finalizers, 0);
gc_mark_queue_finlist(gc_cache, &sp, &ptls2->finalizers, 0);
}
gc_mark_object_list(ptls, &finalizer_list_marked, 0);
visit_mark_stack(ptls);
gc_mark_queue_finlist(gc_cache, &sp, &finalizer_list_marked, 0);
gc_mark_loop(ptls, sp);
if (lostval_parents.len == 0) {
jl_printf(JL_STDERR, "Could not find the missing link. We missed a toplevel root. This is odd.\n");
break;
Expand Down Expand Up @@ -243,19 +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;
gc_mark_sp_t sp;
gc_mark_sp_init(gc_cache, &sp);
lostval = NULL;
lostval_parents.len = 0;
lostval_parents_done.len = 0;
clear_mark(GC_CLEAN);
gc_verifying = 1;
mark_all_roots(ptls);
gc_mark_object_list(ptls, &to_finalize, 0);
gc_mark_queue_all_roots(ptls, &sp);
gc_mark_queue_finlist(gc_cache, &sp, &to_finalize, 0);
for (int i = 0;i < jl_n_threads;i++) {
jl_ptls_t ptls2 = jl_all_tls_states[i];
gc_mark_object_list(ptls, &ptls2->finalizers, 0);
gc_mark_queue_finlist(gc_cache, &sp, &ptls2->finalizers, 0);
}
gc_mark_object_list(ptls, &finalizer_list_marked, 0);
visit_mark_stack(ptls);
gc_mark_queue_finlist(gc_cache, &sp, &finalizer_list_marked, 0);
gc_mark_loop(ptls, sp);
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 @@ -1186,6 +1192,177 @@ void gc_count_pool(void)
jl_safe_printf("************************\n");
}

int gc_slot_to_fieldidx(void *obj, void *slot)
{
jl_datatype_t *vt = (jl_datatype_t*)jl_typeof(obj);
int nf = (int)jl_datatype_nfields(vt);
for (int i = 0; i < nf; i++) {
void *fieldaddr = (char*)obj + jl_field_offset(vt, i);
if (fieldaddr >= slot) {
return i;
}
}
return -1;
}

int gc_slot_to_arrayidx(void *obj, void *_slot)
{
char *slot = (char*)_slot;
jl_datatype_t *vt = (jl_datatype_t*)jl_typeof(obj);
char *start = NULL;
size_t len = 0;
if (vt == jl_module_type) {
jl_module_t *m = (jl_module_t*)obj;
start = (char*)m->usings.items;
len = m->usings.len;
}
else if (vt == jl_simplevector_type) {
start = (char*)jl_svec_data(obj);
len = jl_svec_len(obj);
}
else if (vt->name == jl_array_typename) {
jl_array_t *a = (jl_array_t*)obj;
if (!a->flags.ptrarray)
return -1;
start = (char*)a->data;
len = jl_array_len(a);
}
if (slot < start || slot >= start + sizeof(void*) * len)
return -1;
return (slot - start) / sizeof(void*);
}

// 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, gc_mark_sp_t sp, int pc_offset)
{
jl_jmp_buf *old_buf = ptls->safe_restore;
jl_jmp_buf buf;
ptls->safe_restore = &buf;
if (jl_setjmp(buf, 0) != 0) {
jl_printf((JL_STREAM*)STDERR_FILENO,
"\n!!! ERROR when unwinding gc mark loop -- ABORTING !!!\n");
ptls->safe_restore = old_buf;
return;
}
void **top = sp.pc + pc_offset;
char *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 ((char*)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 ",
data, 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 ((char*)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 ",
data, 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 ((char*)data > data_top) {
jl_safe_printf("Mark stack unwind overflow -- ABORTING !!!\n");
break;
}
jl_safe_printf("%p: Finalizer list from %p to %p\n", data, data->begin, 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 ((char*)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 ",
data, prefix, data->parent, ((void**)data->parent)[-1],
data->begin, 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 ((char*)data > data_top) {
jl_safe_printf("Mark stack unwind overflow -- ABORTING !!!\n");
break;
}
jl_datatype_t *vt = (jl_datatype_t*)jl_typeof(data->parent);
jl_fielddesc8_t *desc = (jl_fielddesc8_t*)jl_dt_layout_fields(vt->layout);
jl_safe_printf("%p: %s Object (8bit) %p :: %p -- [%d, %d)\n of type ",
data, prefix, 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 ((char*)data > data_top) {
jl_safe_printf("Mark stack unwind overflow -- ABORTING !!!\n");
break;
}
jl_datatype_t *vt = (jl_datatype_t*)jl_typeof(data->parent);
jl_fielddesc16_t *desc = (jl_fielddesc16_t*)jl_dt_layout_fields(vt->layout);
jl_safe_printf("%p: %s Object (16bit) %p :: %p -- [%d, %d)\n of type ",
data, prefix, 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 ((char*)data > data_top) {
jl_safe_printf("Mark stack unwind overflow -- ABORTING !!!\n");
break;
}
jl_datatype_t *vt = (jl_datatype_t*)jl_typeof(data->parent);
jl_fielddesc32_t *desc = (jl_fielddesc32_t*)jl_dt_layout_fields(vt->layout);
jl_safe_printf("%p: %s Object (32bit) %p :: %p -- [%d, %d)\n of type ",
data, prefix, 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 ((char*)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",
data, prefix, 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 ((char*)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",
data, prefix, data->parent, (int)data->bits, data->begin, data->end);
}
else {
jl_safe_printf("Unknown pc %p --- ABORTING !!!\n", pc);
break;
}
}
ptls->safe_restore = old_buf;
}

#ifdef __cplusplus
}
#endif
Loading

0 comments on commit 38417ec

Please sign in to comment.