typedef enum { B_FREE, B_ALLOCATED, B_MARKED } F_BLOCK_STATUS; typedef struct _F_BLOCK { F_BLOCK_STATUS status; /* In bytes, includes this header */ CELL size; /* Filled in on image load */ struct _F_BLOCK *next_free; /* Used during compaction */ struct _F_BLOCK *forwarding; } F_BLOCK; typedef struct { F_SEGMENT *segment; F_BLOCK *free_list; } F_HEAP; void new_heap(F_HEAP *heap, CELL size); void build_free_list(F_HEAP *heap, CELL size); CELL heap_allot(F_HEAP *heap, CELL size); void unmark_marked(F_HEAP *heap); void free_unmarked(F_HEAP *heap); void heap_usage(F_HEAP *heap, CELL *used, CELL *total_free, CELL *max_free); CELL heap_size(F_HEAP *heap); INLINE F_BLOCK *next_block(F_HEAP *heap, F_BLOCK *block) { CELL next = ((CELL)block + block->size); if(next == heap->segment->end) return NULL; else return (F_BLOCK *)next; } /* compiled code */ F_HEAP code_heap; typedef void (*CODE_HEAP_ITERATOR)(F_COMPILED *compiled, CELL code_start, CELL literals_start); INLINE void iterate_code_heap_step(F_COMPILED *compiled, CODE_HEAP_ITERATOR iter) { CELL code_start = (CELL)(compiled + 1); CELL literals_start = code_start + compiled->code_length; iter(compiled,code_start,literals_start); } INLINE F_BLOCK *compiled_to_block(F_COMPILED *compiled) { return (F_BLOCK *)compiled - 1; } INLINE F_COMPILED *block_to_compiled(F_BLOCK *block) { return (F_COMPILED *)(block + 1); } INLINE F_BLOCK *first_block(F_HEAP *heap) { return (F_BLOCK *)heap->segment->start; } INLINE F_BLOCK *last_block(F_HEAP *heap) { return (F_BLOCK *)heap->segment->end; } void init_code_heap(CELL size); bool in_code_heap_p(CELL ptr); void iterate_code_heap(CODE_HEAP_ITERATOR iter); void collect_literals(void); void recursive_mark(F_BLOCK *block); void dump_heap(F_HEAP *heap); void compact_code_heap(void); DECLARE_PRIMITIVE(code_room);