Move literal tables out of code heap, instead each code block holds a reference to the literal table
parent
29b561a7ee
commit
32bb531621
|
@ -103,10 +103,13 @@ CELL frame_type(F_STACK_FRAME *frame)
|
|||
CELL frame_executing(F_STACK_FRAME *frame)
|
||||
{
|
||||
F_COMPILED *compiled = frame_code(frame);
|
||||
CELL code_start = (CELL)(compiled + 1);
|
||||
CELL literal_start = code_start + compiled->code_length;
|
||||
|
||||
return get(literal_start);
|
||||
if(compiled->literals == F)
|
||||
return F;
|
||||
else
|
||||
{
|
||||
F_ARRAY *array = untag_object(compiled->literals);
|
||||
return array_nth(array,0);
|
||||
}
|
||||
}
|
||||
|
||||
F_STACK_FRAME *frame_successor(F_STACK_FRAME *frame)
|
||||
|
|
101
vm/code_gc.c
101
vm/code_gc.c
|
@ -92,7 +92,7 @@ void build_free_list(F_HEAP *heap, CELL size)
|
|||
}
|
||||
|
||||
/* Allocate a block of memory from the mark and sweep GC heap */
|
||||
CELL heap_allot(F_HEAP *heap, CELL size)
|
||||
void *heap_allot(F_HEAP *heap, CELL size)
|
||||
{
|
||||
F_BLOCK *prev = NULL;
|
||||
F_BLOCK *scan = heap->free_list;
|
||||
|
@ -139,13 +139,13 @@ CELL heap_allot(F_HEAP *heap, CELL size)
|
|||
/* this is our new block */
|
||||
scan->status = B_ALLOCATED;
|
||||
|
||||
return (CELL)(scan + 1);
|
||||
return scan + 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* If in the middle of code GC, we have to grow the heap, GC restarts from
|
||||
/* If in the middle of code GC, we have to grow the heap, data GC restarts from
|
||||
scratch, so we have to unmark any marked blocks. */
|
||||
void unmark_marked(F_HEAP *heap)
|
||||
{
|
||||
|
@ -251,61 +251,73 @@ void iterate_code_heap(CODE_HEAP_ITERATOR iter)
|
|||
while(scan)
|
||||
{
|
||||
if(scan->status != B_FREE)
|
||||
iterate_code_heap_step(block_to_compiled(scan),iter);
|
||||
iter(block_to_compiled(scan));
|
||||
scan = next_block(&code_heap,scan);
|
||||
}
|
||||
}
|
||||
|
||||
/* Copy all literals referenced from a code block to newspace */
|
||||
void collect_literals_step(F_COMPILED *compiled, CELL code_start, CELL literals_start)
|
||||
/* Update pointers to literals from compiled code. */
|
||||
void update_literal_references(F_COMPILED *compiled)
|
||||
{
|
||||
if(compiled->relocation != F)
|
||||
{
|
||||
F_ARRAY *literals = untag_object(compiled->literals);
|
||||
F_BYTE_ARRAY *relocation = untag_object(compiled->relocation);
|
||||
|
||||
F_REL *rel = (F_REL *)(relocation + 1);
|
||||
F_REL *rel_end = (F_REL *)((char *)rel + byte_array_capacity(relocation));
|
||||
|
||||
while(rel < rel_end)
|
||||
{
|
||||
if(REL_TYPE(rel) == RT_IMMEDIATE)
|
||||
{
|
||||
CELL offset = rel->offset + (CELL)(compiled + 1);
|
||||
F_FIXNUM absolute_value = array_nth(literals,REL_ARGUMENT(rel));
|
||||
apply_relocation(REL_CLASS(rel),offset,absolute_value);
|
||||
}
|
||||
|
||||
rel++;
|
||||
}
|
||||
}
|
||||
|
||||
flush_icache_for(compiled);
|
||||
}
|
||||
|
||||
/* Copy all literals referenced from a code block to newspace. Only for
|
||||
aging and nursery collections */
|
||||
void copy_literal_references(F_COMPILED *compiled)
|
||||
{
|
||||
if(collecting_gen >= compiled->last_scan)
|
||||
{
|
||||
CELL scan;
|
||||
CELL literal_end = literals_start + compiled->literals_length;
|
||||
|
||||
if(collecting_accumulation_gen_p())
|
||||
compiled->last_scan = collecting_gen;
|
||||
else
|
||||
compiled->last_scan = collecting_gen + 1;
|
||||
|
||||
for(scan = literals_start; scan < literal_end; scan += CELLS)
|
||||
copy_handle((CELL*)scan);
|
||||
/* initialize chase pointer */
|
||||
CELL scan = newspace->here;
|
||||
|
||||
if(compiled->relocation != F)
|
||||
{
|
||||
copy_handle(&compiled->relocation);
|
||||
copy_handle(&compiled->literals);
|
||||
copy_handle(&compiled->relocation);
|
||||
|
||||
F_BYTE_ARRAY *relocation = untag_object(compiled->relocation);
|
||||
/* do some tracing so that all reachable literals are now
|
||||
at their final address */
|
||||
copy_reachable_objects(scan,&newspace->here);
|
||||
|
||||
F_REL *rel = (F_REL *)(relocation + 1);
|
||||
F_REL *rel_end = (F_REL *)((char *)rel + byte_array_capacity(relocation));
|
||||
|
||||
while(rel < rel_end)
|
||||
{
|
||||
if(REL_TYPE(rel) == RT_IMMEDIATE)
|
||||
{
|
||||
CELL offset = rel->offset + code_start;
|
||||
F_FIXNUM absolute_value = get(CREF(literals_start,REL_ARGUMENT(rel)));
|
||||
apply_relocation(REL_CLASS(rel),offset,absolute_value);
|
||||
}
|
||||
|
||||
rel++;
|
||||
}
|
||||
}
|
||||
|
||||
flush_icache(code_start,literals_start - code_start);
|
||||
update_literal_references(compiled);
|
||||
}
|
||||
}
|
||||
|
||||
/* Copy literals referenced from all code blocks to newspace */
|
||||
void collect_literals(void)
|
||||
/* Copy literals referenced from all code blocks to newspace. Only for
|
||||
aging and nursery collections */
|
||||
void copy_code_heap_roots(void)
|
||||
{
|
||||
iterate_code_heap(collect_literals_step);
|
||||
iterate_code_heap(copy_literal_references);
|
||||
}
|
||||
|
||||
/* Mark all XTs and literals referenced from a word XT */
|
||||
void recursive_mark(F_BLOCK *block)
|
||||
/* Mark all XTs and literals referenced from a word XT. Only for tenured
|
||||
collections */
|
||||
void mark_block(F_BLOCK *block)
|
||||
{
|
||||
/* If already marked, do nothing */
|
||||
switch(block->status)
|
||||
|
@ -321,7 +333,18 @@ void recursive_mark(F_BLOCK *block)
|
|||
}
|
||||
|
||||
F_COMPILED *compiled = block_to_compiled(block);
|
||||
iterate_code_heap_step(compiled,collect_literals_step);
|
||||
|
||||
copy_handle(&compiled->literals);
|
||||
copy_handle(&compiled->relocation);
|
||||
|
||||
flush_icache_for(compiled);
|
||||
}
|
||||
|
||||
/* Update literals referenced from all code blocks. Only for tenured
|
||||
collections, done at the end. */
|
||||
void update_code_heap_roots(void)
|
||||
{
|
||||
iterate_code_heap(update_literal_references);
|
||||
}
|
||||
|
||||
/* Push the free space and total size of the code heap */
|
||||
|
|
17
vm/code_gc.h
17
vm/code_gc.h
|
@ -26,7 +26,7 @@ typedef struct {
|
|||
|
||||
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 *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);
|
||||
|
@ -44,15 +44,7 @@ INLINE F_BLOCK *next_block(F_HEAP *heap, F_BLOCK *block)
|
|||
/* 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);
|
||||
}
|
||||
typedef void (*CODE_HEAP_ITERATOR)(F_COMPILED *compiled);
|
||||
|
||||
INLINE F_BLOCK *compiled_to_block(F_COMPILED *compiled)
|
||||
{
|
||||
|
@ -77,8 +69,9 @@ INLINE F_BLOCK *last_block(F_HEAP *heap)
|
|||
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 copy_code_heap_roots(void);
|
||||
void update_code_heap_roots(void);
|
||||
void mark_block(F_BLOCK *block);
|
||||
void dump_heap(F_HEAP *heap);
|
||||
void compact_code_heap(void);
|
||||
|
||||
|
|
102
vm/code_heap.c
102
vm/code_heap.c
|
@ -7,17 +7,12 @@ void undefined_symbol(void)
|
|||
general_error(ERROR_UNDEFINED_SYMBOL,F,F,NULL);
|
||||
}
|
||||
|
||||
INLINE CELL get_literal(CELL literals_start, CELL num)
|
||||
{
|
||||
return get(CREF(literals_start,num));
|
||||
}
|
||||
|
||||
/* Look up an external library symbol referenced by a compiled code block */
|
||||
void *get_rel_symbol(F_REL *rel, CELL literals_start)
|
||||
void *get_rel_symbol(F_REL *rel, F_ARRAY *literals)
|
||||
{
|
||||
CELL arg = REL_ARGUMENT(rel);
|
||||
CELL symbol = get_literal(literals_start,arg);
|
||||
CELL library = get_literal(literals_start,arg + 1);
|
||||
CELL symbol = array_nth(literals,arg);
|
||||
CELL library = array_nth(literals,arg + 1);
|
||||
|
||||
F_DLL *dll = (library == F ? NULL : untag_dll(library));
|
||||
|
||||
|
@ -50,9 +45,10 @@ void *get_rel_symbol(F_REL *rel, CELL literals_start)
|
|||
}
|
||||
|
||||
/* Compute an address to store at a relocation */
|
||||
INLINE CELL compute_code_rel(F_REL *rel,
|
||||
CELL code_start, CELL literals_start)
|
||||
INLINE CELL compute_code_rel(F_REL *rel, F_COMPILED *compiled)
|
||||
{
|
||||
F_ARRAY *literals = untag_object(compiled->literals);
|
||||
|
||||
CELL obj;
|
||||
|
||||
switch(REL_TYPE(rel))
|
||||
|
@ -60,19 +56,19 @@ INLINE CELL compute_code_rel(F_REL *rel,
|
|||
case RT_PRIMITIVE:
|
||||
return (CELL)primitives[REL_ARGUMENT(rel)];
|
||||
case RT_DLSYM:
|
||||
return (CELL)get_rel_symbol(rel,literals_start);
|
||||
return (CELL)get_rel_symbol(rel,literals);
|
||||
case RT_IMMEDIATE:
|
||||
return get(CREF(literals_start,REL_ARGUMENT(rel)));
|
||||
return array_nth(literals,REL_ARGUMENT(rel));
|
||||
case RT_XT:
|
||||
obj = get(CREF(literals_start,REL_ARGUMENT(rel)));
|
||||
obj = array_nth(literals,REL_ARGUMENT(rel));
|
||||
if(type_of(obj) == WORD_TYPE)
|
||||
return (CELL)untag_word(obj)->xt;
|
||||
else
|
||||
return (CELL)untag_quotation(obj)->xt;
|
||||
case RT_HERE:
|
||||
return rel->offset + code_start + (short)REL_ARGUMENT(rel);
|
||||
return rel->offset + (CELL)(compiled + 1) + (short)REL_ARGUMENT(rel);
|
||||
case RT_LABEL:
|
||||
return code_start + REL_ARGUMENT(rel);
|
||||
return (CELL)(compiled + 1) + REL_ARGUMENT(rel);
|
||||
case RT_STACK_CHAIN:
|
||||
return (CELL)&stack_chain;
|
||||
default:
|
||||
|
@ -145,7 +141,7 @@ void apply_relocation(CELL class, CELL offset, F_FIXNUM absolute_value)
|
|||
}
|
||||
|
||||
/* Perform all fixups on a code block */
|
||||
void relocate_code_block(F_COMPILED *compiled, CELL code_start, CELL literals_start)
|
||||
void relocate_code_block(F_COMPILED *compiled)
|
||||
{
|
||||
compiled->last_scan = NURSERY;
|
||||
|
||||
|
@ -158,10 +154,9 @@ void relocate_code_block(F_COMPILED *compiled, CELL code_start, CELL literals_st
|
|||
|
||||
while(rel < rel_end)
|
||||
{
|
||||
CELL offset = rel->offset + code_start;
|
||||
CELL offset = rel->offset + (CELL)(compiled + 1);
|
||||
|
||||
F_FIXNUM absolute_value = compute_code_rel(
|
||||
rel,code_start,literals_start);
|
||||
F_FIXNUM absolute_value = compute_code_rel(rel,compiled);
|
||||
|
||||
apply_relocation(REL_CLASS(rel),offset,absolute_value);
|
||||
|
||||
|
@ -169,11 +164,11 @@ void relocate_code_block(F_COMPILED *compiled, CELL code_start, CELL literals_st
|
|||
}
|
||||
}
|
||||
|
||||
flush_icache(code_start,literals_start - code_start);
|
||||
flush_icache_for(compiled);
|
||||
}
|
||||
|
||||
/* Fixup labels. This is done at compile time, not image load time */
|
||||
void fixup_labels(F_ARRAY *labels, CELL code_format, CELL code_start)
|
||||
void fixup_labels(F_ARRAY *labels, CELL code_format, F_COMPILED *compiled)
|
||||
{
|
||||
CELL i;
|
||||
CELL size = array_capacity(labels);
|
||||
|
@ -185,8 +180,8 @@ void fixup_labels(F_ARRAY *labels, CELL code_format, CELL code_start)
|
|||
CELL target = to_fixnum(array_nth(labels,i + 2));
|
||||
|
||||
apply_relocation(class,
|
||||
offset + code_start,
|
||||
target + code_start);
|
||||
offset + (CELL)(compiled + 1),
|
||||
target + (CELL)(compiled + 1));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -210,12 +205,6 @@ void deposit_integers(CELL here, F_ARRAY *array, CELL format)
|
|||
}
|
||||
}
|
||||
|
||||
/* Write a sequence of tagged pointers to memory */
|
||||
void deposit_objects(CELL here, F_ARRAY *array)
|
||||
{
|
||||
memcpy((void*)here,array + 1,array_capacity(array) * CELLS);
|
||||
}
|
||||
|
||||
bool stack_traces_p(void)
|
||||
{
|
||||
return to_boolean(userenv[STACK_TRACES_ENV]);
|
||||
|
@ -226,18 +215,18 @@ CELL compiled_code_format(void)
|
|||
return untag_fixnum_fast(userenv[JIT_CODE_FORMAT]);
|
||||
}
|
||||
|
||||
CELL allot_code_block(CELL size)
|
||||
void *allot_code_block(CELL size)
|
||||
{
|
||||
CELL start = heap_allot(&code_heap,size);
|
||||
void *start = heap_allot(&code_heap,size);
|
||||
|
||||
/* If allocation failed, do a code GC */
|
||||
if(start == 0)
|
||||
if(start == NULL)
|
||||
{
|
||||
gc();
|
||||
start = heap_allot(&code_heap,size);
|
||||
|
||||
/* Insufficient room even after code GC, give up */
|
||||
if(start == 0)
|
||||
if(start == NULL)
|
||||
{
|
||||
CELL used, total_free, max_free;
|
||||
heap_usage(&code_heap,&used,&total_free,&max_free);
|
||||
|
@ -259,54 +248,41 @@ F_COMPILED *add_compiled_block(
|
|||
F_ARRAY *code,
|
||||
F_ARRAY *labels,
|
||||
CELL relocation,
|
||||
F_ARRAY *literals)
|
||||
CELL literals)
|
||||
{
|
||||
CELL code_format = compiled_code_format();
|
||||
|
||||
CELL code_length = align8(array_capacity(code) * code_format);
|
||||
CELL literals_length = array_capacity(literals) * CELLS;
|
||||
|
||||
REGISTER_ROOT(literals);
|
||||
REGISTER_ROOT(relocation);
|
||||
REGISTER_UNTAGGED(code);
|
||||
REGISTER_UNTAGGED(labels);
|
||||
REGISTER_UNTAGGED(literals);
|
||||
|
||||
CELL here = allot_code_block(sizeof(F_COMPILED) + code_length + literals_length);
|
||||
F_COMPILED *compiled = allot_code_block(sizeof(F_COMPILED) + code_length);
|
||||
|
||||
UNREGISTER_UNTAGGED(literals);
|
||||
UNREGISTER_UNTAGGED(labels);
|
||||
UNREGISTER_UNTAGGED(code);
|
||||
UNREGISTER_ROOT(relocation);
|
||||
UNREGISTER_ROOT(literals);
|
||||
|
||||
/* compiled header */
|
||||
F_COMPILED *header = (void *)here;
|
||||
header->type = type;
|
||||
header->last_scan = NURSERY;
|
||||
header->code_length = code_length;
|
||||
header->literals_length = literals_length;
|
||||
header->relocation = relocation;
|
||||
|
||||
here += sizeof(F_COMPILED);
|
||||
|
||||
CELL code_start = here;
|
||||
compiled->type = type;
|
||||
compiled->last_scan = NURSERY;
|
||||
compiled->code_length = code_length;
|
||||
compiled->literals = literals;
|
||||
compiled->relocation = relocation;
|
||||
|
||||
/* code */
|
||||
deposit_integers(here,code,code_format);
|
||||
here += code_length;
|
||||
|
||||
/* literals */
|
||||
deposit_objects(here,literals);
|
||||
here += literals_length;
|
||||
deposit_integers((CELL)(compiled + 1),code,code_format);
|
||||
|
||||
/* fixup labels */
|
||||
if(labels)
|
||||
fixup_labels(labels,code_format,code_start);
|
||||
if(labels) fixup_labels(labels,code_format,compiled);
|
||||
|
||||
/* next time we do a minor GC, we have to scan the code heap for
|
||||
literals */
|
||||
last_code_heap_scan = NURSERY;
|
||||
|
||||
return header;
|
||||
return compiled;
|
||||
}
|
||||
|
||||
void set_word_code(F_WORD *word, F_COMPILED *compiled)
|
||||
|
@ -369,7 +345,7 @@ void primitive_modify_code_heap(void)
|
|||
code,
|
||||
labels,
|
||||
relocation,
|
||||
literals);
|
||||
tag_object(literals));
|
||||
|
||||
UNREGISTER_UNTAGGED(word);
|
||||
UNREGISTER_UNTAGGED(alist);
|
||||
|
@ -396,7 +372,13 @@ void primitive_modify_code_heap(void)
|
|||
F_ARRAY *pair = untag_array(array_nth(alist,i));
|
||||
F_WORD *word = untag_word(array_nth(pair,0));
|
||||
|
||||
iterate_code_heap_step(word->code,relocate_code_block);
|
||||
relocate_code_block(word->code);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void flush_icache_for(F_COMPILED *compiled)
|
||||
{
|
||||
CELL start = (CELL)(compiled + 1);
|
||||
flush_icache(start,compiled->code_length);
|
||||
}
|
||||
|
|
|
@ -59,7 +59,7 @@ typedef struct {
|
|||
|
||||
void apply_relocation(CELL class, CELL offset, F_FIXNUM absolute_value);
|
||||
|
||||
void relocate_code_block(F_COMPILED *relocating, CELL code_start, CELL literals_start);
|
||||
void relocate_code_block(F_COMPILED *relocating);
|
||||
|
||||
void default_word_code(F_WORD *word, bool relocate);
|
||||
|
||||
|
@ -70,9 +70,12 @@ F_COMPILED *add_compiled_block(
|
|||
F_ARRAY *code,
|
||||
F_ARRAY *labels,
|
||||
CELL relocation,
|
||||
F_ARRAY *literals);
|
||||
CELL literals);
|
||||
|
||||
CELL compiled_code_format(void);
|
||||
|
||||
bool stack_traces_p(void);
|
||||
|
||||
void primitive_modify_code_heap(void);
|
||||
|
||||
void flush_icache_for(F_COMPILED *compiled);
|
||||
|
|
92
vm/data_gc.c
92
vm/data_gc.c
|
@ -296,7 +296,7 @@ void primitive_end_scan(void)
|
|||
}
|
||||
|
||||
/* Scan all the objects in the card */
|
||||
void collect_card(F_CARD *ptr, CELL gen, CELL here)
|
||||
void copy_card(F_CARD *ptr, CELL gen, CELL here)
|
||||
{
|
||||
CELL card_scan = (CELL)CARD_TO_ADDR(ptr) + CARD_OFFSET(ptr);
|
||||
CELL card_end = (CELL)CARD_TO_ADDR(ptr + 1);
|
||||
|
@ -304,12 +304,12 @@ void collect_card(F_CARD *ptr, CELL gen, CELL here)
|
|||
if(here < card_end)
|
||||
card_end = here;
|
||||
|
||||
collect_next_loop(card_scan,&card_end);
|
||||
copy_reachable_objects(card_scan,&card_end);
|
||||
|
||||
cards_scanned++;
|
||||
}
|
||||
|
||||
void collect_card_deck(F_DECK *deck, CELL gen, F_CARD mask, F_CARD unmask)
|
||||
void copy_card_deck(F_DECK *deck, CELL gen, F_CARD mask, F_CARD unmask)
|
||||
{
|
||||
F_CARD *first_card = DECK_TO_CARD(deck);
|
||||
F_CARD *last_card = DECK_TO_CARD(deck + 1);
|
||||
|
@ -330,7 +330,7 @@ void collect_card_deck(F_DECK *deck, CELL gen, F_CARD mask, F_CARD unmask)
|
|||
{
|
||||
if(ptr[card] & mask)
|
||||
{
|
||||
collect_card(&ptr[card],gen,here);
|
||||
copy_card(&ptr[card],gen,here);
|
||||
ptr[card] &= ~unmask;
|
||||
}
|
||||
}
|
||||
|
@ -341,7 +341,7 @@ void collect_card_deck(F_DECK *deck, CELL gen, F_CARD mask, F_CARD unmask)
|
|||
}
|
||||
|
||||
/* Copy all newspace objects referenced from marked cards to the destination */
|
||||
void collect_gen_cards(CELL gen)
|
||||
void copy_gen_cards(CELL gen)
|
||||
{
|
||||
F_DECK *first_deck = ADDR_TO_DECK(data_heap->generations[gen].start);
|
||||
F_DECK *last_deck = ADDR_TO_DECK(data_heap->generations[gen].end);
|
||||
|
@ -365,7 +365,7 @@ void collect_gen_cards(CELL gen)
|
|||
unmask = CARD_MARK_MASK;
|
||||
else
|
||||
{
|
||||
critical_error("bug in collect_gen_cards",gen);
|
||||
critical_error("bug in copy_gen_cards",gen);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
@ -390,7 +390,7 @@ void collect_gen_cards(CELL gen)
|
|||
}
|
||||
else
|
||||
{
|
||||
critical_error("bug in collect_gen_cards",gen);
|
||||
critical_error("bug in copy_gen_cards",gen);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -400,7 +400,7 @@ void collect_gen_cards(CELL gen)
|
|||
{
|
||||
if(*ptr & mask)
|
||||
{
|
||||
collect_card_deck(ptr,gen,mask,unmask);
|
||||
copy_card_deck(ptr,gen,mask,unmask);
|
||||
*ptr &= ~unmask;
|
||||
}
|
||||
}
|
||||
|
@ -408,15 +408,15 @@ void collect_gen_cards(CELL gen)
|
|||
|
||||
/* Scan cards in all generations older than the one being collected, copying
|
||||
old->new references */
|
||||
void collect_cards(void)
|
||||
void copy_cards(void)
|
||||
{
|
||||
int i;
|
||||
for(i = collecting_gen + 1; i < data_heap->gen_count; i++)
|
||||
collect_gen_cards(i);
|
||||
copy_gen_cards(i);
|
||||
}
|
||||
|
||||
/* Copy all tagged pointers in a range of memory */
|
||||
void collect_stack(F_SEGMENT *region, CELL top)
|
||||
void copy_stack_elements(F_SEGMENT *region, CELL top)
|
||||
{
|
||||
CELL ptr = region->start;
|
||||
|
||||
|
@ -424,25 +424,23 @@ void collect_stack(F_SEGMENT *region, CELL top)
|
|||
copy_handle((CELL*)ptr);
|
||||
}
|
||||
|
||||
void collect_stack_frame(F_STACK_FRAME *frame)
|
||||
void copy_stack_frame_step(F_STACK_FRAME *frame)
|
||||
{
|
||||
recursive_mark(compiled_to_block(frame_code(frame)));
|
||||
mark_block(compiled_to_block(frame_code(frame)));
|
||||
}
|
||||
|
||||
/* The base parameter allows us to adjust for a heap-allocated
|
||||
callstack snapshot */
|
||||
void collect_callstack(F_CONTEXT *stacks)
|
||||
void copy_callstack_roots(F_CONTEXT *stacks)
|
||||
{
|
||||
if(collecting_gen == TENURED)
|
||||
{
|
||||
CELL top = (CELL)stacks->callstack_top;
|
||||
CELL bottom = (CELL)stacks->callstack_bottom;
|
||||
|
||||
iterate_callstack(top,bottom,collect_stack_frame);
|
||||
iterate_callstack(top,bottom,copy_stack_frame_step);
|
||||
}
|
||||
}
|
||||
|
||||
void collect_gc_locals(void)
|
||||
void copy_registered_locals(void)
|
||||
{
|
||||
CELL ptr = gc_locals_region->start;
|
||||
|
||||
|
@ -452,28 +450,28 @@ void collect_gc_locals(void)
|
|||
|
||||
/* Copy roots over at the start of GC, namely various constants, stacks,
|
||||
the user environment and extra roots registered with REGISTER_ROOT */
|
||||
void collect_roots(void)
|
||||
void copy_roots(void)
|
||||
{
|
||||
copy_handle(&T);
|
||||
copy_handle(&bignum_zero);
|
||||
copy_handle(&bignum_pos_one);
|
||||
copy_handle(&bignum_neg_one);
|
||||
|
||||
collect_gc_locals();
|
||||
collect_stack(extra_roots_region,extra_roots);
|
||||
copy_registered_locals();
|
||||
copy_stack_elements(extra_roots_region,extra_roots);
|
||||
|
||||
save_stacks();
|
||||
F_CONTEXT *stacks = stack_chain;
|
||||
|
||||
while(stacks)
|
||||
{
|
||||
collect_stack(stacks->datastack_region,stacks->datastack);
|
||||
collect_stack(stacks->retainstack_region,stacks->retainstack);
|
||||
copy_stack_elements(stacks->datastack_region,stacks->datastack);
|
||||
copy_stack_elements(stacks->retainstack_region,stacks->retainstack);
|
||||
|
||||
copy_handle(&stacks->catchstack_save);
|
||||
copy_handle(&stacks->current_callback_save);
|
||||
|
||||
collect_callstack(stacks);
|
||||
copy_callstack_roots(stacks);
|
||||
|
||||
stacks = stacks->next;
|
||||
}
|
||||
|
@ -610,23 +608,23 @@ void do_code_slots(CELL scan)
|
|||
{
|
||||
case WORD_TYPE:
|
||||
word = (F_WORD *)scan;
|
||||
recursive_mark(compiled_to_block(word->code));
|
||||
mark_block(compiled_to_block(word->code));
|
||||
if(word->profiling)
|
||||
recursive_mark(compiled_to_block(word->profiling));
|
||||
mark_block(compiled_to_block(word->profiling));
|
||||
break;
|
||||
case QUOTATION_TYPE:
|
||||
quot = (F_QUOTATION *)scan;
|
||||
if(quot->compiledp != F)
|
||||
recursive_mark(compiled_to_block(quot->code));
|
||||
mark_block(compiled_to_block(quot->code));
|
||||
break;
|
||||
case CALLSTACK_TYPE:
|
||||
stack = (F_CALLSTACK *)scan;
|
||||
iterate_callstack_object(stack,collect_stack_frame);
|
||||
iterate_callstack_object(stack,copy_stack_frame_step);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
CELL collect_next_nursery(CELL scan)
|
||||
CELL copy_next_from_nursery(CELL scan)
|
||||
{
|
||||
CELL *obj = (CELL *)scan;
|
||||
CELL *end = (CELL *)(scan + binary_payload_start(scan));
|
||||
|
@ -651,7 +649,7 @@ CELL collect_next_nursery(CELL scan)
|
|||
return scan + untagged_object_size(scan);
|
||||
}
|
||||
|
||||
CELL collect_next_aging(CELL scan)
|
||||
CELL copy_next_from_aging(CELL scan)
|
||||
{
|
||||
CELL *obj = (CELL *)scan;
|
||||
CELL *end = (CELL *)(scan + binary_payload_start(scan));
|
||||
|
@ -680,8 +678,7 @@ CELL collect_next_aging(CELL scan)
|
|||
return scan + untagged_object_size(scan);
|
||||
}
|
||||
|
||||
/* This function is performance-critical */
|
||||
CELL collect_next_tenured(CELL scan)
|
||||
CELL copy_next_from_tenured(CELL scan)
|
||||
{
|
||||
CELL *obj = (CELL *)scan;
|
||||
CELL *end = (CELL *)(scan + binary_payload_start(scan));
|
||||
|
@ -707,22 +704,22 @@ CELL collect_next_tenured(CELL scan)
|
|||
return scan + untagged_object_size(scan);
|
||||
}
|
||||
|
||||
void collect_next_loop(CELL scan, CELL *end)
|
||||
void copy_reachable_objects(CELL scan, CELL *end)
|
||||
{
|
||||
if(HAVE_NURSERY_P && collecting_gen == NURSERY)
|
||||
{
|
||||
while(scan < *end)
|
||||
scan = collect_next_nursery(scan);
|
||||
scan = copy_next_from_nursery(scan);
|
||||
}
|
||||
else if(HAVE_AGING_P && collecting_gen == AGING)
|
||||
{
|
||||
while(scan < *end)
|
||||
scan = collect_next_aging(scan);
|
||||
scan = copy_next_from_aging(scan);
|
||||
}
|
||||
else if(collecting_gen == TENURED)
|
||||
{
|
||||
while(scan < *end)
|
||||
scan = collect_next_tenured(scan);
|
||||
scan = copy_next_from_tenured(scan);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -879,25 +876,22 @@ void garbage_collection(CELL gen,
|
|||
CELL scan = newspace->here;
|
||||
|
||||
/* collect objects referenced from stacks and environment */
|
||||
collect_roots();
|
||||
copy_roots();
|
||||
/* collect objects referenced from older generations */
|
||||
collect_cards();
|
||||
copy_cards();
|
||||
/* do some tracing */
|
||||
copy_reachable_objects(scan,&newspace->here);
|
||||
|
||||
/* don't scan code heap unless it has pointers to this
|
||||
generation or younger */
|
||||
if(collecting_gen >= last_code_heap_scan)
|
||||
{
|
||||
if(collecting_gen != TENURED)
|
||||
{
|
||||
|
||||
/* if we are doing code GC, then we will copy over
|
||||
literals from any code block which gets marked as live.
|
||||
if we are not doing code GC, just consider all literals
|
||||
as roots. */
|
||||
code_heap_scans++;
|
||||
code_heap_scans++;
|
||||
|
||||
collect_literals();
|
||||
}
|
||||
if(collecting_gen == TENURED)
|
||||
update_code_heap_roots();
|
||||
else
|
||||
copy_code_heap_roots();
|
||||
|
||||
if(collecting_accumulation_gen_p())
|
||||
last_code_heap_scan = collecting_gen;
|
||||
|
@ -905,8 +899,6 @@ void garbage_collection(CELL gen,
|
|||
last_code_heap_scan = collecting_gen + 1;
|
||||
}
|
||||
|
||||
collect_next_loop(scan,&newspace->here);
|
||||
|
||||
CELL gc_elapsed = (current_micros() - start);
|
||||
|
||||
end_gc(gc_elapsed);
|
||||
|
|
|
@ -126,7 +126,6 @@ INLINE void allot_barrier(CELL address)
|
|||
}
|
||||
|
||||
void clear_cards(CELL from, CELL to);
|
||||
void collect_cards(void);
|
||||
|
||||
/* the 0th generation is where new objects are allocated. */
|
||||
#define NURSERY 0
|
||||
|
@ -387,7 +386,7 @@ INLINE void* allot_object(CELL type, CELL a)
|
|||
return object;
|
||||
}
|
||||
|
||||
void collect_next_loop(CELL scan, CELL *end);
|
||||
void copy_reachable_objects(CELL scan, CELL *end);
|
||||
|
||||
void primitive_gc(void);
|
||||
void primitive_gc_stats(void);
|
||||
|
|
32
vm/debug.c
32
vm/debug.c
|
@ -308,36 +308,6 @@ void find_data_references(CELL look_for_)
|
|||
gc_off = false;
|
||||
}
|
||||
|
||||
CELL look_for;
|
||||
|
||||
void find_code_references_step(F_COMPILED *compiled, CELL code_start, CELL literals_start)
|
||||
{
|
||||
CELL scan;
|
||||
CELL literal_end = literals_start + compiled->literals_length;
|
||||
|
||||
for(scan = literals_start; scan < literal_end; scan += CELLS)
|
||||
{
|
||||
CELL code_start = (CELL)(compiled + 1);
|
||||
CELL literal_start = code_start + compiled->code_length;
|
||||
|
||||
CELL obj = get(literal_start);
|
||||
|
||||
if(look_for == get(scan))
|
||||
{
|
||||
print_cell_hex_pad(obj);
|
||||
print_string(" ");
|
||||
print_nested_obj(obj,2);
|
||||
nl();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void find_code_references(CELL look_for_)
|
||||
{
|
||||
look_for = look_for_;
|
||||
iterate_code_heap(find_code_references_step);
|
||||
}
|
||||
|
||||
void factorbug(void)
|
||||
{
|
||||
if(fep_disabled)
|
||||
|
@ -464,8 +434,6 @@ void factorbug(void)
|
|||
CELL addr = read_cell_hex();
|
||||
print_string("Data heap references:\n");
|
||||
find_data_references(addr);
|
||||
print_string("Code heap references:\n");
|
||||
find_code_references(addr);
|
||||
nl();
|
||||
}
|
||||
else if(strcmp(cmd,"words") == 0)
|
||||
|
|
11
vm/image.c
11
vm/image.c
|
@ -311,18 +311,13 @@ void relocate_data()
|
|||
}
|
||||
}
|
||||
|
||||
void fixup_code_block(F_COMPILED *compiled, CELL code_start, CELL literals_start)
|
||||
void fixup_code_block(F_COMPILED *compiled)
|
||||
{
|
||||
/* relocate literal table data */
|
||||
CELL scan;
|
||||
CELL literal_end = literals_start + compiled->literals_length;
|
||||
|
||||
data_fixup(&compiled->relocation);
|
||||
data_fixup(&compiled->literals);
|
||||
|
||||
for(scan = literals_start; scan < literal_end; scan += CELLS)
|
||||
data_fixup((CELL*)scan);
|
||||
|
||||
relocate_code_block(compiled,code_start,literals_start);
|
||||
relocate_code_block(compiled);
|
||||
}
|
||||
|
||||
void relocate_code()
|
||||
|
|
|
@ -107,7 +107,7 @@ typedef struct
|
|||
char type; /* this is WORD_TYPE or QUOTATION_TYPE */
|
||||
char last_scan; /* the youngest generation in which this block's literals may live */
|
||||
CELL code_length; /* # bytes */
|
||||
CELL literals_length; /* # bytes */
|
||||
CELL literals; /* # bytes */
|
||||
CELL relocation; /* tagged pointer to byte-array or f */
|
||||
} F_COMPILED;
|
||||
|
||||
|
|
|
@ -26,7 +26,7 @@ F_COMPILED *compile_profiling_stub(F_WORD *word)
|
|||
untag_object(code),
|
||||
NULL, /* no labels */
|
||||
tag_object(relocation),
|
||||
untag_object(literals));
|
||||
literals);
|
||||
}
|
||||
|
||||
/* Allocates memory */
|
||||
|
|
|
@ -344,12 +344,12 @@ void jit_compile(CELL quot, bool relocate)
|
|||
untag_object(code),
|
||||
NULL,
|
||||
relocation,
|
||||
untag_object(literals));
|
||||
literals);
|
||||
|
||||
set_quot_xt(untag_object(quot),compiled);
|
||||
|
||||
if(relocate)
|
||||
iterate_code_heap_step(compiled,relocate_code_block);
|
||||
relocate_code_block(compiled);
|
||||
|
||||
UNREGISTER_ROOT(literals);
|
||||
UNREGISTER_ROOT(relocation);
|
||||
|
|
|
@ -62,7 +62,7 @@ F_WORD *allot_word(CELL vocab, CELL name)
|
|||
UNREGISTER_UNTAGGED(word);
|
||||
|
||||
if(profiling_p)
|
||||
iterate_code_heap_step(word->profiling,relocate_code_block);
|
||||
relocate_code_block(word->profiling);
|
||||
|
||||
return word;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue