Remove code_length field from F_CODE_BLOCK struct, and make F_BLOCK the head of F_CODE_BLOCK to simplify other code

db4
Slava Pestov 2009-03-19 03:45:37 -05:00
parent 44d61b71f6
commit 78f168e304
12 changed files with 57 additions and 73 deletions

View File

@ -1,9 +1,8 @@
#include "master.h"
void flush_icache_for(F_CODE_BLOCK *compiled)
void flush_icache_for(F_CODE_BLOCK *block)
{
CELL start = (CELL)(compiled + 1);
flush_icache(start,compiled->code_length);
flush_icache((CELL)block,block->block.size);
}
void iterate_relocations(F_CODE_BLOCK *compiled, RELOCATION_ITERATOR iter)
@ -170,7 +169,7 @@ is added to the heap. */
collections */
void mark_code_block(F_CODE_BLOCK *compiled)
{
mark_block(compiled_to_block(compiled));
mark_block(&compiled->block);
copy_handle(&compiled->literals);
copy_handle(&compiled->relocation);
@ -361,18 +360,18 @@ CELL compiled_code_format(void)
}
/* Might GC */
void *allot_code_block(CELL size)
F_CODE_BLOCK *allot_code_block(CELL size)
{
void *start = heap_allot(&code_heap,size);
F_BLOCK *block = heap_allot(&code_heap,size + sizeof(F_CODE_BLOCK));
/* If allocation failed, do a code GC */
if(start == NULL)
if(block == NULL)
{
gc();
start = heap_allot(&code_heap,size);
block = heap_allot(&code_heap,size + sizeof(F_CODE_BLOCK));
/* Insufficient room even after code GC, give up */
if(start == NULL)
if(block == NULL)
{
CELL used, total_free, max_free;
heap_usage(&code_heap,&used,&total_free,&max_free);
@ -385,11 +384,11 @@ void *allot_code_block(CELL size)
}
}
return start;
return (F_CODE_BLOCK *)block;
}
/* Might GC */
F_CODE_BLOCK *add_compiled_block(
F_CODE_BLOCK *add_code_block(
CELL type,
F_ARRAY *code,
F_ARRAY *labels,
@ -404,7 +403,7 @@ F_CODE_BLOCK *add_compiled_block(
REGISTER_UNTAGGED(code);
REGISTER_UNTAGGED(labels);
F_CODE_BLOCK *compiled = allot_code_block(sizeof(F_CODE_BLOCK) + code_length);
F_CODE_BLOCK *compiled = allot_code_block(code_length);
UNREGISTER_UNTAGGED(labels);
UNREGISTER_UNTAGGED(code);
@ -415,7 +414,6 @@ F_CODE_BLOCK *add_compiled_block(
compiled->type = type;
compiled->last_scan = NURSERY;
compiled->needs_fixup = true;
compiled->code_length = code_length;
compiled->literals = literals;
compiled->relocation = relocation;

View File

@ -83,7 +83,7 @@ CELL compiled_code_format(void);
bool stack_traces_p(void);
F_CODE_BLOCK *add_compiled_block(
F_CODE_BLOCK *add_code_block(
CELL type,
F_ARRAY *code,
F_ARRAY *labels,

View File

@ -80,7 +80,7 @@ void build_free_list(F_HEAP *heap, CELL size)
}
/* Allocate a block of memory from the mark and sweep GC heap */
void *heap_allot(F_HEAP *heap, CELL size)
F_BLOCK *heap_allot(F_HEAP *heap, CELL size)
{
F_FREE_BLOCK *prev = NULL;
F_FREE_BLOCK *scan = heap->free_list;
@ -92,9 +92,7 @@ void *heap_allot(F_HEAP *heap, CELL size)
if(scan->block.status != B_FREE)
critical_error("Invalid block in free list",(CELL)scan);
CELL this_size = scan->block.size - sizeof(F_BLOCK);
if(this_size < size)
if(scan->block.size < size)
{
prev = scan;
scan = scan->next_free;
@ -104,7 +102,7 @@ void *heap_allot(F_HEAP *heap, CELL size)
/* we found a candidate block */
F_FREE_BLOCK *next_free;
if(this_size - size <= sizeof(F_BLOCK) * 2)
if(scan->block.size - size <= sizeof(F_BLOCK) * 2)
{
/* too small to be split */
next_free = scan->next_free;
@ -112,12 +110,11 @@ void *heap_allot(F_HEAP *heap, CELL size)
else
{
/* split the block in two */
CELL new_size = size + sizeof(F_BLOCK);
F_FREE_BLOCK *split = (F_FREE_BLOCK *)((CELL)scan + new_size);
F_FREE_BLOCK *split = (F_FREE_BLOCK *)((CELL)scan + size);
split->block.status = B_FREE;
split->block.size = scan->block.size - new_size;
split->block.size = scan->block.size - size;
split->next_free = scan->next_free;
scan->block.size = new_size;
scan->block.size = size;
next_free = split;
}
@ -126,8 +123,7 @@ void *heap_allot(F_HEAP *heap, CELL size)
/* this is our new block */
scan->block.status = B_ALLOCATED;
return &scan->block + 1;
return &scan->block;
}
return NULL;

View File

@ -1,29 +1,3 @@
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;
/* Used during compaction */
struct _F_BLOCK *forwarding;
} F_BLOCK;
typedef struct _F_FREE_BLOCK
{
F_BLOCK block;
/* Filled in on image load */
struct _F_FREE_BLOCK *next_free;
} F_FREE_BLOCK;
typedef struct {
F_SEGMENT *segment;
F_FREE_BLOCK *free_list;
@ -31,7 +5,7 @@ typedef struct {
void new_heap(F_HEAP *heap, CELL size);
void build_free_list(F_HEAP *heap, CELL size);
void *heap_allot(F_HEAP *heap, CELL size);
F_BLOCK *heap_allot(F_HEAP *heap, CELL size);
void mark_block(F_BLOCK *block);
void unmark_marked(F_HEAP *heap);
void free_unmarked(F_HEAP *heap);

View File

@ -40,7 +40,7 @@ void iterate_code_heap(CODE_HEAP_ITERATOR iter)
while(scan)
{
if(scan->status != B_FREE)
iter(block_to_compiled(scan));
iter((F_CODE_BLOCK *)scan);
scan = next_block(&code_heap,scan);
}
}
@ -103,7 +103,7 @@ void primitive_modify_code_heap(void)
REGISTER_UNTAGGED(alist);
REGISTER_UNTAGGED(word);
F_CODE_BLOCK *compiled = add_compiled_block(
F_CODE_BLOCK *compiled = add_code_block(
WORD_TYPE,
code,
labels,
@ -137,7 +137,7 @@ void primitive_code_room(void)
F_CODE_BLOCK *forward_xt(F_CODE_BLOCK *compiled)
{
return block_to_compiled(compiled_to_block(compiled)->forwarding);
return (F_CODE_BLOCK *)compiled->block.forwarding;
}
void forward_frame_xt(F_STACK_FRAME *frame)

View File

@ -1,16 +1,6 @@
/* compiled code */
F_HEAP code_heap;
INLINE F_BLOCK *compiled_to_block(F_CODE_BLOCK *compiled)
{
return (F_BLOCK *)compiled - 1;
}
INLINE F_CODE_BLOCK *block_to_compiled(F_BLOCK *block)
{
return (F_CODE_BLOCK *)(block + 1);
}
void init_code_heap(CELL size);
bool in_code_heap_p(CELL ptr);

View File

@ -30,7 +30,7 @@ u64 decks_scanned;
CELL code_heap_scans;
/* What generation was being collected when copy_code_heap_roots() was last
called? Until the next call to add_compiled_block(), future
called? Until the next call to add_code_block(), future
collections of younger generations don't have to touch the code
heap. */
CELL last_code_heap_scan;

View File

@ -324,11 +324,11 @@ void dump_code_heap(void)
status = "free";
break;
case B_ALLOCATED:
size += object_size(block_to_compiled(scan)->relocation);
size += object_size(((F_CODE_BLOCK *)scan)->relocation);
status = "allocated";
break;
case B_MARKED:
size += object_size(block_to_compiled(scan)->relocation);
size += object_size(((F_CODE_BLOCK *)scan)->relocation);
status = "marked";
break;
default:

View File

@ -102,12 +102,38 @@ typedef struct {
} F_STRING;
/* The compiled code heap is structured into blocks. */
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;
/* Used during compaction */
struct _F_BLOCK *forwarding;
} F_BLOCK;
typedef struct _F_FREE_BLOCK
{
F_BLOCK block;
/* Filled in on image load */
struct _F_FREE_BLOCK *next_free;
} F_FREE_BLOCK;
typedef struct
{
F_BLOCK block;
char type; /* this is WORD_TYPE or QUOTATION_TYPE */
char last_scan; /* the youngest generation in which this block's literals may live */
char needs_fixup; /* is this a new block that needs full fixup? */
CELL code_length; /* # bytes */
CELL literals; /* # bytes */
CELL relocation; /* tagged pointer to byte-array or f */
} F_CODE_BLOCK;

View File

@ -21,7 +21,7 @@ F_CODE_BLOCK *compile_profiling_stub(F_WORD *word)
UNREGISTER_ROOT(code);
UNREGISTER_ROOT(literals);
return add_compiled_block(
return add_code_block(
WORD_TYPE,
untag_object(code),
NULL, /* no labels */

View File

@ -158,7 +158,7 @@ bool jit_stack_frame_p(F_ARRAY *array)
void set_quot_xt(F_QUOTATION *quot, F_CODE_BLOCK *code)
{
if(code->type != QUOTATION_TYPE)
critical_error("bad param to set_quot_xt",(CELL)code);
critical_error("Bad param to set_quot_xt",(CELL)code);
quot->code = code;
quot->xt = (XT)(code + 1);
@ -339,7 +339,7 @@ void jit_compile(CELL quot, bool relocate)
GROWABLE_ARRAY_TRIM(literals);
GROWABLE_BYTE_ARRAY_TRIM(relocation);
F_CODE_BLOCK *compiled = add_compiled_block(
F_CODE_BLOCK *compiled = add_code_block(
QUOTATION_TYPE,
untag_object(code),
NULL,

View File

@ -81,7 +81,7 @@ void primitive_word_xt(void)
F_WORD *word = untag_word(dpop());
F_CODE_BLOCK *code = (profiling_p ? word->profiling : word->code);
dpush(allot_cell((CELL)code + sizeof(F_CODE_BLOCK)));
dpush(allot_cell((CELL)code + sizeof(F_CODE_BLOCK) + code->code_length));
dpush(allot_cell((CELL)code + code->block.size));
}
void primitive_wrapper(void)