static void gc_mark(void) { // mark all roots // active tasks GC_Markval(jl_root_task); GC_Markval(jl_current_task); // modules GC_Markval(jl_core_module); GC_Markval(jl_current_module); // invisible builtin values if (jl_an_empty_cell) GC_Markval(jl_an_empty_cell); GC_Markval(jl_exception_in_transit); GC_Markval(jl_task_arg_in_transit); GC_Markval(jl_unprotect_stack_func); GC_Markval(jl_bottom_func); GC_Markval(jl_typetype_type); // constants GC_Markval(jl_null); GC_Markval(jl_true); GC_Markval(jl_false); jl_mark_box_caches(); size_t i; // stuff randomly preserved for(i=0; i < preserved_values.len; i++) { GC_Markval((jl_value_t*)preserved_values.items[i]); } // objects currently being finalized for(i=0; i < to_finalize.len; i++) { GC_Markval(to_finalize.items[i]); } // find unmarked objects that need to be finalized. // this must happen last. for(i=0; i < finalizer_table.size; i+=2) { if (finalizer_table.table[i+1] != HT_NOTFOUND) { jl_value_t *v = finalizer_table.table[i]; if (!gc_marked_obj(v)) { GC_Markval(v); schedule_finalization(v); } GC_Markval(finalizer_table.table[i+1]); } } }
static void sweep_weak_refs(void) { size_t n=0, ndel=0, l=weak_refs.len; jl_weakref_t *wr; void **lst = weak_refs.items; void *tmp; #define SWAP_wr(a,b) (tmp=a,a=b,b=tmp,1) if (l == 0) return; do { wr = (jl_weakref_t*)lst[n]; if (gc_marked_obj(wr)) { // weakref itself is alive if (!gc_marked_obj(wr->value)) wr->value = (jl_value_t*)jl_nothing; n++; } else { ndel++; } } while ((n < l-ndel) && SWAP_wr(lst[n],lst[n+ndel])); weak_refs.len -= ndel; }
static void gc_markval_(jl_value_t *v) { assert(v != NULL); //assert(v != lookforme); if (gc_marked_obj(v)) return; jl_value_t *vt = (jl_value_t*)jl_typeof(v); #ifdef OBJPROFILE void **bp = ptrhash_bp(&obj_counts, vt); if (*bp == HT_NOTFOUND) *bp = (void*)2; else (*((ptrint_t*)bp))++; #endif jl_value_t *vtt = gc_typeof(vt); gc_setmark_obj(v); if (vtt==(jl_value_t*)jl_bits_kind) return; // some values have special representations if (vt == (jl_value_t*)jl_tuple_type) { size_t i; for(i=0; i < ((jl_tuple_t*)v)->length; i++) { jl_value_t *elt = ((jl_tuple_t*)v)->data[i]; if (elt != NULL) GC_Markval(elt); } } else if (((jl_struct_type_t*)(vt))->name == jl_array_typename) { jl_array_t *a = (jl_array_t*)v; int ndims = jl_array_ndims(a); int ndimwords = (ndims > 2 ? (ndims-2) : 0); #ifndef __LP64__ // on 32-bit, ndimwords must be odd to preserve 8-byte alignment ndimwords += (~ndimwords)&1; #endif void *data_area = &a->_space[0] + ndimwords*sizeof(size_t); if (a->reshaped) { GC_Markval(*((jl_value_t**)data_area)); } else if (a->data) { char *data = a->data; if (ndims == 1) data -= a->offset*a->elsize; if (data != data_area) { gc_setmark(data); } } jl_value_t *elty = jl_tparam0(vt); if (gc_typeof(elty) != (jl_value_t*)jl_bits_kind) { size_t i; for(i=0; i < a->length; i++) { jl_value_t *elt = ((jl_value_t**)a->data)[i]; if (elt != NULL) GC_Markval(elt); } } } else if (vt == (jl_value_t*)jl_module_type) { gc_mark_module((jl_module_t*)v); } else if (vt == (jl_value_t*)jl_task_type) { jl_task_t *ta = (jl_task_t*)v; GC_Markval(ta->on_exit); GC_Markval(ta->tls); if (ta->start) GC_Markval(ta->start); if (ta->result) GC_Markval(ta->result); GC_Markval(ta->state.eh_task); if (ta->stkbuf != NULL) gc_setmark(ta->stkbuf); #ifdef COPY_STACKS ptrint_t offset; if (ta == jl_current_task) { offset = 0; gc_mark_stack(jl_pgcstack, offset); } else { offset = ta->stkbuf - (ta->stackbase-ta->ssize); gc_mark_stack(ta->state.gcstack, offset); } jl_savestate_t *ss = &ta->state; while (ss != NULL) { GC_Markval(ss->ostream_obj); ss = ss->prev; if (ss != NULL) ss = (jl_savestate_t*)((char*)ss + offset); } #else gc_mark_stack(ta->state.gcstack, 0); jl_savestate_t *ss = &ta->state; while (ss != NULL) { GC_Markval(ss->ostream_obj); ss = ss->prev; } #endif } else if (vt == (jl_value_t*)jl_weakref_type) { // don't mark contents } else { assert(vtt == (jl_value_t*)jl_struct_kind); size_t nf = ((jl_struct_type_t*)vt)->names->length; size_t i=0; if (vt == (jl_value_t*)jl_struct_kind || vt == (jl_value_t*)jl_function_type) { i++; // skip fptr field } for(; i < nf; i++) { jl_value_t *fld = ((jl_value_t**)v)[i+1]; if (fld) GC_Markval(fld); } } }