void GC_Mark(struct GC* gc) { if (gc is NULL or gc->nitems is 0) { return; } /* Mark Thread Local Storage */ mark(current(Thread), gc, (void(*)(var,void*))GC_Mark_Item); /* Mark Roots */ for (size_t i = 0; i < gc->nslots; i++) { if (gc->entries[i].hash is 0) { continue; } if (gc->entries[i].marked) { continue; } if (gc->entries[i].root) { gc->entries[i].marked = true; GC_Recurse(gc, gc->entries[i].ptr); } } volatile int noinline = 1; /* Flush Registers to Stack */ if (noinline) { jmp_buf env; memset(&env, 0, sizeof(jmp_buf)); setjmp(env); } /* Avoid Inlining function call */ void (*mark_stack)(struct GC* gc) = noinline ? GC_Mark_Stack : (void(*)(struct GC* gc))(NULL); /* Mark Stack */ mark_stack(gc); }
static void tgc_mark(tgc_t *gc) { size_t i, k; jmp_buf env; void (*volatile mark_stack)(tgc_t*) = tgc_mark_stack; if (gc->nitems == 0) { return; } for (i = 0; i < gc->nslots; i++) { if (gc->items[i].hash == 0) { continue; } if (gc->items[i].flags & TGC_MARK) { continue; } if (gc->items[i].flags & TGC_ROOT) { gc->items[i].flags |= TGC_MARK; if (gc->items[i].flags & TGC_LEAF) { continue; } for (k = 0; k < gc->items[i].size/sizeof(void*); k++) { tgc_mark_ptr(gc, ((void**)gc->items[i].ptr)[k]); } continue; } } memset(&env, 0, sizeof(jmp_buf)); setjmp(env); mark_stack(gc); }
void garbage_collect (void) { mark_stack (); }
void gc_mark(void) { fprintf(stderr, "marking objects...\n"); mark_env(); mark_stack(); fprintf(stderr, "finished mark\n"); }