namespace factor { /* Set by the -securegc command line argument */ extern bool secure_gc; /* generational copying GC divides memory into zones */ struct zone { /* allocation pointer is 'here'; its offset is hardcoded in the compiler backends */ cell start; cell here; cell size; cell end; }; struct data_heap { segment *seg; cell young_size; cell aging_size; cell tenured_size; cell gen_count; zone *generations; zone *semispaces; cell *allot_markers; cell *allot_markers_end; cell *cards; cell *cards_end; cell *decks; cell *decks_end; /* the 0th generation is where new objects are allocated. */ cell nursery() { return 0; } /* where objects hang around */ cell aging() { return gen_count - 2; } /* the oldest generation */ cell tenured() { return gen_count - 1; } bool have_aging_p() { return gen_count > 2; } }; extern data_heap *data; static const cell max_gen_count = 3; inline static bool in_zone(zone *z, object *pointer) { return (cell)pointer >= z->start && (cell)pointer < z->end; } cell init_zone(zone *z, cell size, cell base); void init_card_decks(); data_heap *grow_data_heap(data_heap *data, cell requested_bytes); void dealloc_data_heap(data_heap *data); void clear_cards(cell from, cell to); void clear_decks(cell from, cell to); void clear_allot_markers(cell from, cell to); void reset_generation(cell i); void reset_generations(cell from, cell to); void set_data_heap(data_heap *data_heap_); void init_data_heap(cell gens, cell young_size, cell aging_size, cell tenured_size, bool secure_gc_); /* set up guard pages to check for under/overflow. size must be a multiple of the page size */ segment *alloc_segment(cell size); void dealloc_segment(segment *block); cell untagged_object_size(object *pointer); cell unaligned_object_size(object *pointer); cell binary_payload_start(object *pointer); cell object_size(cell tagged); void begin_scan(); void end_scan(); cell next_object(); PRIMITIVE(data_room); PRIMITIVE(size); PRIMITIVE(begin_scan); PRIMITIVE(next_object); PRIMITIVE(end_scan); /* GC is off during heap walking */ extern bool gc_off; cell find_all_words(); /* Every object has a regular representation in the runtime, which makes GC much simpler. Every slot of the object until binary_payload_start is a pointer to some other object. */ inline static void do_slots(cell obj, void (* iter)(cell *)) { cell scan = obj; cell payload_start = binary_payload_start((object *)obj); cell end = obj + payload_start; scan += sizeof(cell); while(scan < end) { iter((cell *)scan); scan += sizeof(cell); } } } /* new objects are allocated here */ VM_C_API factor::zone nursery;