static int BTC_ephemeron_mark(void *p, struct NewGC *gc) { if (gc->doing_memory_accounting) { GC_Ephemeron *eph = (GC_Ephemeron *)p; gcMARK2(eph->key, gc); gcMARK2(eph->val, gc); return gcBYTES_TO_WORDS(sizeof(GC_Ephemeron)); } return mark_ephemeron(p, gc); }
static int mark_ready_ephemerons(GCTYPE *gc, int inc_gen1) { GC_Ephemeron *waiting, *next, *eph; int did_one = 0, j; GC_mark_no_recur(gc, 1); for (j = 0; j < (inc_gen1 ? 1 : 2); j++) { if (inc_gen1) eph = gc->inc_ephemerons; else if (j == 0) eph = gc->ephemerons; else eph = gc->bp_ephemerons; waiting = NULL; for (; eph; eph = next) { if (inc_gen1) next = eph->inc_next; else next = eph->next; if (is_marked(gc, eph->key)) { if (!inc_gen1) eph->key = GC_resolve2(eph->key, gc); gcMARK2(eph->val, gc); gc->num_last_seen_ephemerons++; did_one = 1; if (!inc_gen1 && (j == 0) && !gc->gc_full && gc->started_incremental) { /* Need to preserve the ephemeron in the incremental list, unless it's kept in generation 1/2 nistead of promoted to generation 1. */ if (!is_in_generation_half(gc, eph)) { eph->inc_next = gc->inc_ephemerons; gc->inc_ephemerons = eph; } } } else { if (inc_gen1) { /* Ensure that we can write to the page containing the emphemeron: */ check_incremental_unprotect(gc, pagemap_find_page(gc->page_maps, eph)); eph->inc_next = waiting; } else eph->next = waiting; waiting = eph; } } if (inc_gen1) gc->inc_ephemerons = waiting; else if (j == 0) gc->ephemerons = waiting; else gc->bp_ephemerons = waiting; } GC_mark_no_recur(gc, 0); return did_one; }
static int mark_weak_array(void *p, struct NewGC *gc) { GC_Weak_Array *a = (GC_Weak_Array *)p; gcMARK2(a->replace_val, gc); a->next = gc->weak_arrays; gc->weak_arrays = a; #if CHECKS /* For now, weak arrays only used for symbols, keywords, and falses: */ { void **data; int i; data = a->data; for (i = a->count; i--; ) { if (data[i] && (*(short *)(data[i]) != 48) && (*(short *)(data[i]) != 49) && (*(short *)(data[i]) != 58)) { CRASH(1); } } } #endif return gcBYTES_TO_WORDS(sizeof(GC_Weak_Array) + ((a->count - 1) * sizeof(void *))); }
static void MARK_jmpup(Scheme_Jumpup_Buf *buf, struct NewGC *gc) { gcMARK2(buf->stack_copy, gc); gcMARK2(buf->cont, gc); gcMARK2(buf->external_stack, gc); /* IMPORTANT: the buf->stack_copy pointer must be the only instance of this stack to be traversed. If you copy a jmpup buffer (as in fun.c), don't let a GC happen until the old copy is zeroed out. */ if (buf->stack_copy) GC_mark2_variable_stack(buf->gc_var_stack, (intptr_t)buf->stack_copy - (intptr_t)buf->stack_from, /* FIXME: stack direction */ (char *)buf->stack_copy + buf->stack_size, buf->stack_copy, gc); }
static int mark_weak_array(void *p, struct NewGC *gc) { GC_Weak_Array *a = (GC_Weak_Array *)p; gcMARK2(a->replace_val, gc); if (gc->doing_memory_accounting) { /* skip */ } else if (gc->inc_gen1) { /* inc_next field is at the end of the `data` array: */ a->data[a->count] = gc->inc_weak_arrays; gc->inc_weak_arrays = a; } else if (gc->during_backpointer) { if (!gc->gc_full || (gc->started_incremental /* `a` must have been marked and must be in the old generation, or we wouldn't get here; `a` may have been fully processed in incremental mode, though */ && (a->data[a->count] == gc->weak_incremental_done))) { /* Keep backpointered weak arrays separate, because we should not merge them to the incremental list in incremental mode. */ a->next = gc->bp_weak_arrays; gc->bp_weak_arrays = a; } } else { a->next = gc->weak_arrays; gc->weak_arrays = a; if (gc->gc_full) a->data[a->count] = NULL; /* ensure not a future weak_incremental_done */ } #if CHECKS /* For now, weak arrays only used for symbols, keywords, and falses: */ { void **data; int i; data = a->data; for (i = a->count; i--; ) { if (data[i] && (*(short *)(data[i]) != 48) && (*(short *)(data[i]) != 49) && (*(short *)(data[i]) != 58)) { CRASH(1); } } } #endif return gcBYTES_TO_WORDS(sizeof(GC_Weak_Array) + ((a->count - 1 + 1) * sizeof(void *))); }
static int mark_weak_box(void *p, struct NewGC *gc) { GC_Weak_Box *wb = (GC_Weak_Box *)p; gcMARK2(wb->secondary_erase, gc); if (wb->val) { wb->next = gc->weak_boxes[wb->is_late]; gc->weak_boxes[wb->is_late] = wb; } return gcBYTES_TO_WORDS(sizeof(GC_Weak_Box)); }
static int shape_mark(void *p, struct NewGC *gc) { #ifndef GC_NO_MARK_PROCEDURE_NEEDED intptr_t *shape_str = shape_strs[*(Scheme_Type *)p]; while (*shape_str != SCHEME_GC_SHAPE_TERM) { if (shape_str[0] == SCHEME_GC_SHAPE_PTR_OFFSET) { gcMARK2(*(void **)((char *)p + shape_str[1]), gc); } shape_str += 2; } # ifdef GC_NO_SIZE_NEEDED_FROM_PROCS return 0; # else return shape_size(p, gc); # endif #endif }
static int mark_ready_ephemerons(GCTYPE *gc) { GC_Ephemeron *waiting = NULL, *next, *eph; int did_one = 0; for (eph = gc->ephemerons; eph; eph = next) { next = eph->next; if (is_marked(gc, eph->key)) { gcMARK2(eph->val, gc); gc->num_last_seen_ephemerons++; did_one = 1; } else { eph->next = waiting; waiting = eph; } } gc->ephemerons = waiting; return did_one; }
static int mark_weak_box(void *p, struct NewGC *gc) { GC_Weak_Box *wb = (GC_Weak_Box *)p; gcMARK2(wb->secondary_erase, gc); if (gc->doing_memory_accounting) { /* skip */ } else if (gc->inc_gen1) { check_weak_box_not_already_in_inc_chain(wb, gc->inc_weak_boxes[wb->is_late]); wb->inc_next = gc->inc_weak_boxes[wb->is_late]; gc->inc_weak_boxes[wb->is_late] = wb; } else if (gc->during_backpointer) { if ((!gc->gc_full || (gc->started_incremental /* see note with `gc->weak_incremental_done` for weak arrays */ && (wb->inc_next == gc->weak_incremental_done) && wb->val)) && (wb->val || gc->started_incremental)) { /* Keep backpointered weak arrays separate, because we should not merge them to the incremental list in incremental mode. */ check_weak_box_not_already_in_chain(wb, gc->bp_weak_boxes[wb->is_late]); check_weak_box_not_already_in_chain(wb, gc->weak_boxes[wb->is_late]); wb->next = gc->bp_weak_boxes[wb->is_late]; gc->bp_weak_boxes[wb->is_late] = wb; } } else if (wb->val || gc->started_incremental) { check_weak_box_not_already_in_chain(wb, gc->weak_boxes[wb->is_late]); check_weak_box_not_already_in_chain(wb, gc->bp_weak_boxes[wb->is_late]); wb->next = gc->weak_boxes[wb->is_late]; gc->weak_boxes[wb->is_late] = wb; if (gc->gc_full) wb->inc_next = NULL; /* ensure not a future weak_incremental_done */ } return gcBYTES_TO_WORDS(sizeof(GC_Weak_Box)); }
static void MARK_cjs(Scheme_Continuation_Jump_State *cjs, struct NewGC *gc) { gcMARK2(cjs->jumping_to_continuation, gc); gcMARK2(cjs->alt_full_continuation, gc); gcMARK2(cjs->val, gc); }