factor/vm/data_heap.hpp

129 lines
2.7 KiB
C++

/* Set by the -securegc command line argument */
extern bool secure_gc;
/* generational copying GC divides memory into zones */
struct F_ZONE {
/* allocation pointer is 'here'; its offset is hardcoded in the
compiler backends */
CELL start;
CELL here;
CELL size;
CELL end;
};
struct F_DATA_HEAP {
F_SEGMENT *segment;
CELL young_size;
CELL aging_size;
CELL tenured_size;
CELL gen_count;
F_ZONE *generations;
F_ZONE* semispaces;
CELL *allot_markers;
CELL *allot_markers_end;
CELL *cards;
CELL *cards_end;
CELL *decks;
CELL *decks_end;
};
extern F_DATA_HEAP *data_heap;
/* the 0th generation is where new objects are allocated. */
#define NURSERY 0
/* where objects hang around */
#define AGING (data_heap->gen_count-2)
#define HAVE_AGING_P (data_heap->gen_count>2)
/* the oldest generation */
#define TENURED (data_heap->gen_count-1)
#define MIN_GEN_COUNT 1
#define MAX_GEN_COUNT 3
/* new objects are allocated here */
extern F_ZONE nursery;
INLINE bool in_zone(F_ZONE *z, CELL pointer)
{
return pointer >= z->start && pointer < z->end;
}
CELL init_zone(F_ZONE *z, CELL size, CELL base);
void init_card_decks(void);
F_DATA_HEAP *grow_data_heap(F_DATA_HEAP *data_heap, CELL requested_bytes);
void dealloc_data_heap(F_DATA_HEAP *data_heap);
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(F_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 */
F_SEGMENT *alloc_segment(CELL size);
void dealloc_segment(F_SEGMENT *block);
CELL untagged_object_size(CELL pointer);
CELL unaligned_object_size(CELL pointer);
CELL object_size(CELL pointer);
CELL binary_payload_start(CELL pointer);
void begin_scan(void);
CELL next_object(void);
void primitive_data_room(void);
void primitive_size(void);
void primitive_begin_scan(void);
void primitive_next_object(void);
void primitive_end_scan(void);
/* GC is off during heap walking */
extern bool gc_off;
INLINE void *allot_zone(F_ZONE *z, CELL a)
{
CELL h = z->here;
z->here = h + align8(a);
return (void*)h;
}
CELL find_all_words(void);
/* 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 void do_slots(CELL obj, void (* iter)(CELL *))
{
CELL scan = obj;
CELL payload_start = binary_payload_start(obj);
CELL end = obj + payload_start;
scan += CELLS;
while(scan < end)
{
iter((CELL *)scan);
scan += CELLS;
}
}