129 lines
2.7 KiB
C++
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;
|
|
}
|
|
}
|
|
|