95 lines
		
	
	
		
			2.1 KiB
		
	
	
	
		
			C
		
	
	
			
		
		
	
	
			95 lines
		
	
	
		
			2.1 KiB
		
	
	
	
		
			C
		
	
	
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;
 | 
						|
 | 
						|
	/* Alignment padding */
 | 
						|
	CELL padding[4];
 | 
						|
} 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);
 | 
						|
CELL heap_usage(F_HEAP *heap, F_BLOCK_STATUS status);
 | 
						|
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 reloc_start, CELL literals_start, CELL words_start, CELL words_end);
 | 
						|
 | 
						|
INLINE void iterate_code_heap_step(F_COMPILED *compiled, CODE_HEAP_ITERATOR iter)
 | 
						|
{
 | 
						|
	CELL code_start = (CELL)(compiled + 1);
 | 
						|
	CELL reloc_start = code_start + compiled->code_length;
 | 
						|
	CELL literals_start = reloc_start + compiled->reloc_length;
 | 
						|
	CELL words_start = literals_start + compiled->literals_length;
 | 
						|
	CELL words_end = words_start + compiled->words_length;
 | 
						|
 | 
						|
	iter(compiled,code_start,reloc_start,literals_start,words_start,words_end);
 | 
						|
}
 | 
						|
 | 
						|
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 code_gc(void);
 | 
						|
void compact_code_heap(void);
 | 
						|
 | 
						|
DECLARE_PRIMITIVE(code_room);
 | 
						|
DECLARE_PRIMITIVE(code_gc);
 |