static void gc_walk_roots(struct RootSet *root) { LOG("gc_walk_roots\n"); LOG("walk registers\n"); root->cp |= proc_tag; /* cp is untagged. tag it temporarily. */ gc_copy_forward(&root->cp); root->cp = UNTAG(root->cp); if (root->usedregs & ac_bit) gc_copy_forward(&root->ac); if (root->usedregs & t1_bit) gc_copy_forward(&root->t1); if (root->usedregs & t2_bit) gc_copy_forward(&root->t2); if (root->usedregs & t3_bit) gc_copy_forward(&root->t3); LOG("\n"); LOG("walk stack\n"); Ptr *fp = (Ptr *)stack_bottom+1; while (fp <= root->fp) { unsigned int size = *(fp-1) / ws; Ptr *p = fp+1; /* skip return code pointer */ for (; p<fp+size; p++) gc_copy_forward(p); fp = fp+size+1; } LOG("\n"); LOG("walk global references\n"); gc_copy_forward(&global_refs); LOG("\n"); LOG("end gc_walk_roots\n"); }
Type *untagged() const { #ifdef FACTOR_DEBUG assert(type_p()); #endif return (Type *)(UNTAG(value_)); }
/* Cheney collector */ static void gc_copy_forward(Ptr *p) { unsigned int tag = TAG(*p); if (tag == number_tag || tag == immed_tag || tag == float_tag) { return; } /* number or immediate or float -> ignore */ Ptr *obj = OBJ(*p); if (obj == 0) { return; } /* null pointer -> ignore */ if (forwarded(obj)) { /* update pointer with forwarding info */ LOG("U%x", tag); *p = UNTAG(*obj) | tag; } else { /* copy and forward object */ LOG("C%x", tag); unsigned int size = object_size(obj); memcpy(gc_free, obj, size); set_forward(obj, PTR(gc_free)); *p = PTR(gc_free) | tag; gc_free += size; } }
void operator()(instruction_operand op) { cell old_offset = op.rel_offset() + (cell)old_address->entry_point(); switch(op.rel_type()) { case RT_LITERAL: { cell value = op.load_value(old_offset); if(immediate_p(value)) op.store_value(value); else op.store_value(RETAG(fixup.fixup_data(untag<object>(value)),TAG(value))); break; } case RT_ENTRY_POINT: case RT_ENTRY_POINT_PIC: case RT_ENTRY_POINT_PIC_TAIL: case RT_HERE: { cell value = op.load_value(old_offset); cell offset = TAG(value); code_block *compiled = (code_block *)UNTAG(value); op.store_value((cell)fixup.fixup_code(compiled) + offset); break; } case RT_THIS: case RT_CARDS_OFFSET: case RT_DECKS_OFFSET: parent->store_external_address(op); break; default: op.store_value(op.load_value(old_offset)); break; } }
TYPE *untagged() const { return (TYPE *)(UNTAG(value_)); }
void callback_heap::update(code_block* stub) { word* w = (word*)UNTAG(stub->owner); store_callback_operand(stub, 1, w->entry_point); stub->flush_icache(); }
static inline cell tuple_size_with_fixup(cell offset, object *obj) { tuple_layout *layout = (tuple_layout *)((char *)UNTAG(((tuple *)obj)->layout) + offset); return tuple_size(layout); }
object *forwarding_pointer() const { return (object *)UNTAG(header); }
void *callback_entry_point(code_block *stub) { word *w = (word *)UNTAG(stub->owner); return w->entry_point; }
Type* untagged() const { FACTOR_ASSERT(type_p()); return (Type*)(UNTAG(value_)); }
static void print(Ptr ptr) { switch (TAG(ptr)) { case number_tag: printf("%ld", ptr/(mask+1)); break; case immed_tag: switch (IMMTAG(ptr)) { case bool_tag: printf((ptr>>imm_tag_len) ? "#t" : "#f"); break; case null_tag: printf("()"); break; case char_tag: switch (ptr>>imm_tag_len) { case '\n': printf("#\\newline"); break; case ' ': printf("#\\space"); break; case 9: printf("#\\tab"); break; default: printf("#\\%c", (char)(ptr>>imm_tag_len)); break; } break; } break; case pair_tag: printf("("); print(CAR(ptr)); ptr = CDR(ptr); while (TAG(ptr) == pair_tag) { printf(" "); print(CAR(ptr)); ptr = CDR(ptr); } if (IMMTAG(ptr) != null_tag) { printf(" . "); print(ptr); } printf(")"); break; case string_tag: printf("\""); print_string(ptr); printf("\""); break; case symbol_tag: print_string(SYMBOLNAME(ptr)); break; case vector_tag: { int n; Ptr *p; printf("#("); n = OBJLENGTH(ptr); p = VECTORDATA(ptr); if (n != 0) { print(*p); while (--n) { printf(" "); print(*++p); } } printf(")"); break; } case proc_tag: printf("<procedure>"); break; case float_tag: { Ptr x = UNTAG(ptr); printf("%f", *(float *)&x); break; } default: printf("#<garbage %x>", (unsigned int)ptr); break; } }