Remove code_length field from F_CODE_BLOCK struct, and make F_BLOCK the head of F_CODE_BLOCK to simplify other code
parent
44d61b71f6
commit
78f168e304
|
@ -1,9 +1,8 @@
|
||||||
#include "master.h"
|
#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((CELL)block,block->block.size);
|
||||||
flush_icache(start,compiled->code_length);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void iterate_relocations(F_CODE_BLOCK *compiled, RELOCATION_ITERATOR iter)
|
void iterate_relocations(F_CODE_BLOCK *compiled, RELOCATION_ITERATOR iter)
|
||||||
|
@ -170,7 +169,7 @@ is added to the heap. */
|
||||||
collections */
|
collections */
|
||||||
void mark_code_block(F_CODE_BLOCK *compiled)
|
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->literals);
|
||||||
copy_handle(&compiled->relocation);
|
copy_handle(&compiled->relocation);
|
||||||
|
@ -361,18 +360,18 @@ CELL compiled_code_format(void)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Might GC */
|
/* 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 allocation failed, do a code GC */
|
||||||
if(start == NULL)
|
if(block == NULL)
|
||||||
{
|
{
|
||||||
gc();
|
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 */
|
/* Insufficient room even after code GC, give up */
|
||||||
if(start == NULL)
|
if(block == NULL)
|
||||||
{
|
{
|
||||||
CELL used, total_free, max_free;
|
CELL used, total_free, max_free;
|
||||||
heap_usage(&code_heap,&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 */
|
/* Might GC */
|
||||||
F_CODE_BLOCK *add_compiled_block(
|
F_CODE_BLOCK *add_code_block(
|
||||||
CELL type,
|
CELL type,
|
||||||
F_ARRAY *code,
|
F_ARRAY *code,
|
||||||
F_ARRAY *labels,
|
F_ARRAY *labels,
|
||||||
|
@ -404,7 +403,7 @@ F_CODE_BLOCK *add_compiled_block(
|
||||||
REGISTER_UNTAGGED(code);
|
REGISTER_UNTAGGED(code);
|
||||||
REGISTER_UNTAGGED(labels);
|
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(labels);
|
||||||
UNREGISTER_UNTAGGED(code);
|
UNREGISTER_UNTAGGED(code);
|
||||||
|
@ -415,7 +414,6 @@ F_CODE_BLOCK *add_compiled_block(
|
||||||
compiled->type = type;
|
compiled->type = type;
|
||||||
compiled->last_scan = NURSERY;
|
compiled->last_scan = NURSERY;
|
||||||
compiled->needs_fixup = true;
|
compiled->needs_fixup = true;
|
||||||
compiled->code_length = code_length;
|
|
||||||
compiled->literals = literals;
|
compiled->literals = literals;
|
||||||
compiled->relocation = relocation;
|
compiled->relocation = relocation;
|
||||||
|
|
||||||
|
|
|
@ -83,7 +83,7 @@ CELL compiled_code_format(void);
|
||||||
|
|
||||||
bool stack_traces_p(void);
|
bool stack_traces_p(void);
|
||||||
|
|
||||||
F_CODE_BLOCK *add_compiled_block(
|
F_CODE_BLOCK *add_code_block(
|
||||||
CELL type,
|
CELL type,
|
||||||
F_ARRAY *code,
|
F_ARRAY *code,
|
||||||
F_ARRAY *labels,
|
F_ARRAY *labels,
|
||||||
|
|
18
vm/code_gc.c
18
vm/code_gc.c
|
@ -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 */
|
/* 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 *prev = NULL;
|
||||||
F_FREE_BLOCK *scan = heap->free_list;
|
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)
|
if(scan->block.status != B_FREE)
|
||||||
critical_error("Invalid block in free list",(CELL)scan);
|
critical_error("Invalid block in free list",(CELL)scan);
|
||||||
|
|
||||||
CELL this_size = scan->block.size - sizeof(F_BLOCK);
|
if(scan->block.size < size)
|
||||||
|
|
||||||
if(this_size < size)
|
|
||||||
{
|
{
|
||||||
prev = scan;
|
prev = scan;
|
||||||
scan = scan->next_free;
|
scan = scan->next_free;
|
||||||
|
@ -104,7 +102,7 @@ void *heap_allot(F_HEAP *heap, CELL size)
|
||||||
/* we found a candidate block */
|
/* we found a candidate block */
|
||||||
F_FREE_BLOCK *next_free;
|
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 */
|
/* too small to be split */
|
||||||
next_free = scan->next_free;
|
next_free = scan->next_free;
|
||||||
|
@ -112,12 +110,11 @@ void *heap_allot(F_HEAP *heap, CELL size)
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* split the block in two */
|
/* split the block in two */
|
||||||
CELL new_size = size + sizeof(F_BLOCK);
|
F_FREE_BLOCK *split = (F_FREE_BLOCK *)((CELL)scan + size);
|
||||||
F_FREE_BLOCK *split = (F_FREE_BLOCK *)((CELL)scan + new_size);
|
|
||||||
split->block.status = B_FREE;
|
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;
|
split->next_free = scan->next_free;
|
||||||
scan->block.size = new_size;
|
scan->block.size = size;
|
||||||
next_free = split;
|
next_free = split;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -126,8 +123,7 @@ void *heap_allot(F_HEAP *heap, CELL size)
|
||||||
|
|
||||||
/* this is our new block */
|
/* this is our new block */
|
||||||
scan->block.status = B_ALLOCATED;
|
scan->block.status = B_ALLOCATED;
|
||||||
|
return &scan->block;
|
||||||
return &scan->block + 1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
28
vm/code_gc.h
28
vm/code_gc.h
|
@ -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 {
|
typedef struct {
|
||||||
F_SEGMENT *segment;
|
F_SEGMENT *segment;
|
||||||
F_FREE_BLOCK *free_list;
|
F_FREE_BLOCK *free_list;
|
||||||
|
@ -31,7 +5,7 @@ typedef struct {
|
||||||
|
|
||||||
void new_heap(F_HEAP *heap, CELL size);
|
void new_heap(F_HEAP *heap, CELL size);
|
||||||
void build_free_list(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 mark_block(F_BLOCK *block);
|
||||||
void unmark_marked(F_HEAP *heap);
|
void unmark_marked(F_HEAP *heap);
|
||||||
void free_unmarked(F_HEAP *heap);
|
void free_unmarked(F_HEAP *heap);
|
||||||
|
|
|
@ -40,7 +40,7 @@ void iterate_code_heap(CODE_HEAP_ITERATOR iter)
|
||||||
while(scan)
|
while(scan)
|
||||||
{
|
{
|
||||||
if(scan->status != B_FREE)
|
if(scan->status != B_FREE)
|
||||||
iter(block_to_compiled(scan));
|
iter((F_CODE_BLOCK *)scan);
|
||||||
scan = next_block(&code_heap,scan);
|
scan = next_block(&code_heap,scan);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -103,7 +103,7 @@ void primitive_modify_code_heap(void)
|
||||||
REGISTER_UNTAGGED(alist);
|
REGISTER_UNTAGGED(alist);
|
||||||
REGISTER_UNTAGGED(word);
|
REGISTER_UNTAGGED(word);
|
||||||
|
|
||||||
F_CODE_BLOCK *compiled = add_compiled_block(
|
F_CODE_BLOCK *compiled = add_code_block(
|
||||||
WORD_TYPE,
|
WORD_TYPE,
|
||||||
code,
|
code,
|
||||||
labels,
|
labels,
|
||||||
|
@ -137,7 +137,7 @@ void primitive_code_room(void)
|
||||||
|
|
||||||
F_CODE_BLOCK *forward_xt(F_CODE_BLOCK *compiled)
|
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)
|
void forward_frame_xt(F_STACK_FRAME *frame)
|
||||||
|
|
|
@ -1,16 +1,6 @@
|
||||||
/* compiled code */
|
/* compiled code */
|
||||||
F_HEAP code_heap;
|
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);
|
void init_code_heap(CELL size);
|
||||||
|
|
||||||
bool in_code_heap_p(CELL ptr);
|
bool in_code_heap_p(CELL ptr);
|
||||||
|
|
|
@ -30,7 +30,7 @@ u64 decks_scanned;
|
||||||
CELL code_heap_scans;
|
CELL code_heap_scans;
|
||||||
|
|
||||||
/* What generation was being collected when copy_code_heap_roots() was last
|
/* 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
|
collections of younger generations don't have to touch the code
|
||||||
heap. */
|
heap. */
|
||||||
CELL last_code_heap_scan;
|
CELL last_code_heap_scan;
|
||||||
|
|
|
@ -324,11 +324,11 @@ void dump_code_heap(void)
|
||||||
status = "free";
|
status = "free";
|
||||||
break;
|
break;
|
||||||
case B_ALLOCATED:
|
case B_ALLOCATED:
|
||||||
size += object_size(block_to_compiled(scan)->relocation);
|
size += object_size(((F_CODE_BLOCK *)scan)->relocation);
|
||||||
status = "allocated";
|
status = "allocated";
|
||||||
break;
|
break;
|
||||||
case B_MARKED:
|
case B_MARKED:
|
||||||
size += object_size(block_to_compiled(scan)->relocation);
|
size += object_size(((F_CODE_BLOCK *)scan)->relocation);
|
||||||
status = "marked";
|
status = "marked";
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
|
28
vm/layouts.h
28
vm/layouts.h
|
@ -102,12 +102,38 @@ typedef struct {
|
||||||
} F_STRING;
|
} F_STRING;
|
||||||
|
|
||||||
/* The compiled code heap is structured into blocks. */
|
/* 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
|
typedef struct
|
||||||
{
|
{
|
||||||
|
F_BLOCK block;
|
||||||
char type; /* this is WORD_TYPE or QUOTATION_TYPE */
|
char type; /* this is WORD_TYPE or QUOTATION_TYPE */
|
||||||
char last_scan; /* the youngest generation in which this block's literals may live */
|
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? */
|
char needs_fixup; /* is this a new block that needs full fixup? */
|
||||||
CELL code_length; /* # bytes */
|
|
||||||
CELL literals; /* # bytes */
|
CELL literals; /* # bytes */
|
||||||
CELL relocation; /* tagged pointer to byte-array or f */
|
CELL relocation; /* tagged pointer to byte-array or f */
|
||||||
} F_CODE_BLOCK;
|
} F_CODE_BLOCK;
|
||||||
|
|
|
@ -21,7 +21,7 @@ F_CODE_BLOCK *compile_profiling_stub(F_WORD *word)
|
||||||
UNREGISTER_ROOT(code);
|
UNREGISTER_ROOT(code);
|
||||||
UNREGISTER_ROOT(literals);
|
UNREGISTER_ROOT(literals);
|
||||||
|
|
||||||
return add_compiled_block(
|
return add_code_block(
|
||||||
WORD_TYPE,
|
WORD_TYPE,
|
||||||
untag_object(code),
|
untag_object(code),
|
||||||
NULL, /* no labels */
|
NULL, /* no labels */
|
||||||
|
|
|
@ -158,7 +158,7 @@ bool jit_stack_frame_p(F_ARRAY *array)
|
||||||
void set_quot_xt(F_QUOTATION *quot, F_CODE_BLOCK *code)
|
void set_quot_xt(F_QUOTATION *quot, F_CODE_BLOCK *code)
|
||||||
{
|
{
|
||||||
if(code->type != QUOTATION_TYPE)
|
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->code = code;
|
||||||
quot->xt = (XT)(code + 1);
|
quot->xt = (XT)(code + 1);
|
||||||
|
@ -339,7 +339,7 @@ void jit_compile(CELL quot, bool relocate)
|
||||||
GROWABLE_ARRAY_TRIM(literals);
|
GROWABLE_ARRAY_TRIM(literals);
|
||||||
GROWABLE_BYTE_ARRAY_TRIM(relocation);
|
GROWABLE_BYTE_ARRAY_TRIM(relocation);
|
||||||
|
|
||||||
F_CODE_BLOCK *compiled = add_compiled_block(
|
F_CODE_BLOCK *compiled = add_code_block(
|
||||||
QUOTATION_TYPE,
|
QUOTATION_TYPE,
|
||||||
untag_object(code),
|
untag_object(code),
|
||||||
NULL,
|
NULL,
|
||||||
|
|
|
@ -81,7 +81,7 @@ void primitive_word_xt(void)
|
||||||
F_WORD *word = untag_word(dpop());
|
F_WORD *word = untag_word(dpop());
|
||||||
F_CODE_BLOCK *code = (profiling_p ? word->profiling : word->code);
|
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)));
|
||||||
dpush(allot_cell((CELL)code + sizeof(F_CODE_BLOCK) + code->code_length));
|
dpush(allot_cell((CELL)code + code->block.size));
|
||||||
}
|
}
|
||||||
|
|
||||||
void primitive_wrapper(void)
|
void primitive_wrapper(void)
|
||||||
|
|
Loading…
Reference in New Issue