Move literal tables out of code heap, instead each code block holds a reference to the literal table

db4
Slava Pestov 2009-01-24 17:01:01 -06:00
parent 29b561a7ee
commit 32bb531621
13 changed files with 172 additions and 214 deletions

View File

@ -103,10 +103,13 @@ CELL frame_type(F_STACK_FRAME *frame)
CELL frame_executing(F_STACK_FRAME *frame) CELL frame_executing(F_STACK_FRAME *frame)
{ {
F_COMPILED *compiled = frame_code(frame); F_COMPILED *compiled = frame_code(frame);
CELL code_start = (CELL)(compiled + 1); if(compiled->literals == F)
CELL literal_start = code_start + compiled->code_length; return F;
else
return get(literal_start); {
F_ARRAY *array = untag_object(compiled->literals);
return array_nth(array,0);
}
} }
F_STACK_FRAME *frame_successor(F_STACK_FRAME *frame) F_STACK_FRAME *frame_successor(F_STACK_FRAME *frame)

View File

@ -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 */ /* 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 *prev = NULL;
F_BLOCK *scan = heap->free_list; F_BLOCK *scan = heap->free_list;
@ -139,13 +139,13 @@ CELL heap_allot(F_HEAP *heap, CELL size)
/* this is our new block */ /* this is our new block */
scan->status = B_ALLOCATED; 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. */ scratch, so we have to unmark any marked blocks. */
void unmark_marked(F_HEAP *heap) void unmark_marked(F_HEAP *heap)
{ {
@ -251,61 +251,73 @@ void iterate_code_heap(CODE_HEAP_ITERATOR iter)
while(scan) while(scan)
{ {
if(scan->status != B_FREE) 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); scan = next_block(&code_heap,scan);
} }
} }
/* Copy all literals referenced from a code block to newspace */ /* Update pointers to literals from compiled code. */
void collect_literals_step(F_COMPILED *compiled, CELL code_start, CELL literals_start) 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) if(collecting_gen >= compiled->last_scan)
{ {
CELL scan;
CELL literal_end = literals_start + compiled->literals_length;
if(collecting_accumulation_gen_p()) if(collecting_accumulation_gen_p())
compiled->last_scan = collecting_gen; compiled->last_scan = collecting_gen;
else else
compiled->last_scan = collecting_gen + 1; compiled->last_scan = collecting_gen + 1;
for(scan = literals_start; scan < literal_end; scan += CELLS) /* initialize chase pointer */
copy_handle((CELL*)scan); CELL scan = newspace->here;
if(compiled->relocation != F) copy_handle(&compiled->literals);
{ copy_handle(&compiled->relocation);
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); update_literal_references(compiled);
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);
} }
} }
/* Copy literals referenced from all code blocks to newspace */ /* Copy literals referenced from all code blocks to newspace. Only for
void collect_literals(void) 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 */ /* Mark all XTs and literals referenced from a word XT. Only for tenured
void recursive_mark(F_BLOCK *block) collections */
void mark_block(F_BLOCK *block)
{ {
/* If already marked, do nothing */ /* If already marked, do nothing */
switch(block->status) switch(block->status)
@ -321,7 +333,18 @@ void recursive_mark(F_BLOCK *block)
} }
F_COMPILED *compiled = block_to_compiled(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 */ /* Push the free space and total size of the code heap */

View File

@ -26,7 +26,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);
CELL heap_allot(F_HEAP *heap, CELL size); void *heap_allot(F_HEAP *heap, CELL size);
void unmark_marked(F_HEAP *heap); void unmark_marked(F_HEAP *heap);
void free_unmarked(F_HEAP *heap); void free_unmarked(F_HEAP *heap);
void heap_usage(F_HEAP *heap, CELL *used, CELL *total_free, CELL *max_free); 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 */ /* compiled code */
F_HEAP code_heap; F_HEAP code_heap;
typedef void (*CODE_HEAP_ITERATOR)(F_COMPILED *compiled, CELL code_start, CELL literals_start); typedef void (*CODE_HEAP_ITERATOR)(F_COMPILED *compiled);
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) 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); void init_code_heap(CELL size);
bool in_code_heap_p(CELL ptr); bool in_code_heap_p(CELL ptr);
void iterate_code_heap(CODE_HEAP_ITERATOR iter); void iterate_code_heap(CODE_HEAP_ITERATOR iter);
void collect_literals(void); void copy_code_heap_roots(void);
void recursive_mark(F_BLOCK *block); void update_code_heap_roots(void);
void mark_block(F_BLOCK *block);
void dump_heap(F_HEAP *heap); void dump_heap(F_HEAP *heap);
void compact_code_heap(void); void compact_code_heap(void);

View File

@ -7,17 +7,12 @@ void undefined_symbol(void)
general_error(ERROR_UNDEFINED_SYMBOL,F,F,NULL); 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 */ /* 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 arg = REL_ARGUMENT(rel);
CELL symbol = get_literal(literals_start,arg); CELL symbol = array_nth(literals,arg);
CELL library = get_literal(literals_start,arg + 1); CELL library = array_nth(literals,arg + 1);
F_DLL *dll = (library == F ? NULL : untag_dll(library)); 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 */ /* Compute an address to store at a relocation */
INLINE CELL compute_code_rel(F_REL *rel, INLINE CELL compute_code_rel(F_REL *rel, F_COMPILED *compiled)
CELL code_start, CELL literals_start)
{ {
F_ARRAY *literals = untag_object(compiled->literals);
CELL obj; CELL obj;
switch(REL_TYPE(rel)) switch(REL_TYPE(rel))
@ -60,19 +56,19 @@ INLINE CELL compute_code_rel(F_REL *rel,
case RT_PRIMITIVE: case RT_PRIMITIVE:
return (CELL)primitives[REL_ARGUMENT(rel)]; return (CELL)primitives[REL_ARGUMENT(rel)];
case RT_DLSYM: case RT_DLSYM:
return (CELL)get_rel_symbol(rel,literals_start); return (CELL)get_rel_symbol(rel,literals);
case RT_IMMEDIATE: case RT_IMMEDIATE:
return get(CREF(literals_start,REL_ARGUMENT(rel))); return array_nth(literals,REL_ARGUMENT(rel));
case RT_XT: case RT_XT:
obj = get(CREF(literals_start,REL_ARGUMENT(rel))); obj = array_nth(literals,REL_ARGUMENT(rel));
if(type_of(obj) == WORD_TYPE) if(type_of(obj) == WORD_TYPE)
return (CELL)untag_word(obj)->xt; return (CELL)untag_word(obj)->xt;
else else
return (CELL)untag_quotation(obj)->xt; return (CELL)untag_quotation(obj)->xt;
case RT_HERE: 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: case RT_LABEL:
return code_start + REL_ARGUMENT(rel); return (CELL)(compiled + 1) + REL_ARGUMENT(rel);
case RT_STACK_CHAIN: case RT_STACK_CHAIN:
return (CELL)&stack_chain; return (CELL)&stack_chain;
default: default:
@ -145,7 +141,7 @@ void apply_relocation(CELL class, CELL offset, F_FIXNUM absolute_value)
} }
/* Perform all fixups on a code block */ /* 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; 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) while(rel < rel_end)
{ {
CELL offset = rel->offset + code_start; CELL offset = rel->offset + (CELL)(compiled + 1);
F_FIXNUM absolute_value = compute_code_rel( F_FIXNUM absolute_value = compute_code_rel(rel,compiled);
rel,code_start,literals_start);
apply_relocation(REL_CLASS(rel),offset,absolute_value); 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 */ /* 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 i;
CELL size = array_capacity(labels); 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)); CELL target = to_fixnum(array_nth(labels,i + 2));
apply_relocation(class, apply_relocation(class,
offset + code_start, offset + (CELL)(compiled + 1),
target + code_start); 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) bool stack_traces_p(void)
{ {
return to_boolean(userenv[STACK_TRACES_ENV]); return to_boolean(userenv[STACK_TRACES_ENV]);
@ -226,18 +215,18 @@ CELL compiled_code_format(void)
return untag_fixnum_fast(userenv[JIT_CODE_FORMAT]); 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 allocation failed, do a code GC */
if(start == 0) if(start == NULL)
{ {
gc(); gc();
start = heap_allot(&code_heap,size); start = heap_allot(&code_heap,size);
/* Insufficient room even after code GC, give up */ /* Insufficient room even after code GC, give up */
if(start == 0) if(start == 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);
@ -259,54 +248,41 @@ F_COMPILED *add_compiled_block(
F_ARRAY *code, F_ARRAY *code,
F_ARRAY *labels, F_ARRAY *labels,
CELL relocation, CELL relocation,
F_ARRAY *literals) CELL literals)
{ {
CELL code_format = compiled_code_format(); CELL code_format = compiled_code_format();
CELL code_length = align8(array_capacity(code) * 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_ROOT(relocation);
REGISTER_UNTAGGED(code); REGISTER_UNTAGGED(code);
REGISTER_UNTAGGED(labels); 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(labels);
UNREGISTER_UNTAGGED(code); UNREGISTER_UNTAGGED(code);
UNREGISTER_ROOT(relocation); UNREGISTER_ROOT(relocation);
UNREGISTER_ROOT(literals);
/* compiled header */ /* compiled header */
F_COMPILED *header = (void *)here; compiled->type = type;
header->type = type; compiled->last_scan = NURSERY;
header->last_scan = NURSERY; compiled->code_length = code_length;
header->code_length = code_length; compiled->literals = literals;
header->literals_length = literals_length; compiled->relocation = relocation;
header->relocation = relocation;
here += sizeof(F_COMPILED);
CELL code_start = here;
/* code */ /* code */
deposit_integers(here,code,code_format); deposit_integers((CELL)(compiled + 1),code,code_format);
here += code_length;
/* literals */
deposit_objects(here,literals);
here += literals_length;
/* fixup labels */ /* fixup labels */
if(labels) if(labels) fixup_labels(labels,code_format,compiled);
fixup_labels(labels,code_format,code_start);
/* next time we do a minor GC, we have to scan the code heap for /* next time we do a minor GC, we have to scan the code heap for
literals */ literals */
last_code_heap_scan = NURSERY; last_code_heap_scan = NURSERY;
return header; return compiled;
} }
void set_word_code(F_WORD *word, F_COMPILED *compiled) void set_word_code(F_WORD *word, F_COMPILED *compiled)
@ -369,7 +345,7 @@ void primitive_modify_code_heap(void)
code, code,
labels, labels,
relocation, relocation,
literals); tag_object(literals));
UNREGISTER_UNTAGGED(word); UNREGISTER_UNTAGGED(word);
UNREGISTER_UNTAGGED(alist); UNREGISTER_UNTAGGED(alist);
@ -396,7 +372,13 @@ void primitive_modify_code_heap(void)
F_ARRAY *pair = untag_array(array_nth(alist,i)); F_ARRAY *pair = untag_array(array_nth(alist,i));
F_WORD *word = untag_word(array_nth(pair,0)); 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);
}

View File

@ -59,7 +59,7 @@ typedef struct {
void apply_relocation(CELL class, CELL offset, F_FIXNUM absolute_value); 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); void default_word_code(F_WORD *word, bool relocate);
@ -70,9 +70,12 @@ F_COMPILED *add_compiled_block(
F_ARRAY *code, F_ARRAY *code,
F_ARRAY *labels, F_ARRAY *labels,
CELL relocation, CELL relocation,
F_ARRAY *literals); CELL literals);
CELL compiled_code_format(void); CELL compiled_code_format(void);
bool stack_traces_p(void); bool stack_traces_p(void);
void primitive_modify_code_heap(void); void primitive_modify_code_heap(void);
void flush_icache_for(F_COMPILED *compiled);

View File

@ -296,7 +296,7 @@ void primitive_end_scan(void)
} }
/* Scan all the objects in the card */ /* 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_scan = (CELL)CARD_TO_ADDR(ptr) + CARD_OFFSET(ptr);
CELL card_end = (CELL)CARD_TO_ADDR(ptr + 1); 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) if(here < card_end)
card_end = here; card_end = here;
collect_next_loop(card_scan,&card_end); copy_reachable_objects(card_scan,&card_end);
cards_scanned++; 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 *first_card = DECK_TO_CARD(deck);
F_CARD *last_card = DECK_TO_CARD(deck + 1); 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) if(ptr[card] & mask)
{ {
collect_card(&ptr[card],gen,here); copy_card(&ptr[card],gen,here);
ptr[card] &= ~unmask; 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 */ /* 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 *first_deck = ADDR_TO_DECK(data_heap->generations[gen].start);
F_DECK *last_deck = ADDR_TO_DECK(data_heap->generations[gen].end); 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; unmask = CARD_MARK_MASK;
else else
{ {
critical_error("bug in collect_gen_cards",gen); critical_error("bug in copy_gen_cards",gen);
return; return;
} }
} }
@ -390,7 +390,7 @@ void collect_gen_cards(CELL gen)
} }
else else
{ {
critical_error("bug in collect_gen_cards",gen); critical_error("bug in copy_gen_cards",gen);
return; return;
} }
@ -400,7 +400,7 @@ void collect_gen_cards(CELL gen)
{ {
if(*ptr & mask) if(*ptr & mask)
{ {
collect_card_deck(ptr,gen,mask,unmask); copy_card_deck(ptr,gen,mask,unmask);
*ptr &= ~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 /* Scan cards in all generations older than the one being collected, copying
old->new references */ old->new references */
void collect_cards(void) void copy_cards(void)
{ {
int i; int i;
for(i = collecting_gen + 1; i < data_heap->gen_count; 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 */ /* 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; CELL ptr = region->start;
@ -424,25 +424,23 @@ void collect_stack(F_SEGMENT *region, CELL top)
copy_handle((CELL*)ptr); 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 void copy_callstack_roots(F_CONTEXT *stacks)
callstack snapshot */
void collect_callstack(F_CONTEXT *stacks)
{ {
if(collecting_gen == TENURED) if(collecting_gen == TENURED)
{ {
CELL top = (CELL)stacks->callstack_top; CELL top = (CELL)stacks->callstack_top;
CELL bottom = (CELL)stacks->callstack_bottom; 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; 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, /* Copy roots over at the start of GC, namely various constants, stacks,
the user environment and extra roots registered with REGISTER_ROOT */ the user environment and extra roots registered with REGISTER_ROOT */
void collect_roots(void) void copy_roots(void)
{ {
copy_handle(&T); copy_handle(&T);
copy_handle(&bignum_zero); copy_handle(&bignum_zero);
copy_handle(&bignum_pos_one); copy_handle(&bignum_pos_one);
copy_handle(&bignum_neg_one); copy_handle(&bignum_neg_one);
collect_gc_locals(); copy_registered_locals();
collect_stack(extra_roots_region,extra_roots); copy_stack_elements(extra_roots_region,extra_roots);
save_stacks(); save_stacks();
F_CONTEXT *stacks = stack_chain; F_CONTEXT *stacks = stack_chain;
while(stacks) while(stacks)
{ {
collect_stack(stacks->datastack_region,stacks->datastack); copy_stack_elements(stacks->datastack_region,stacks->datastack);
collect_stack(stacks->retainstack_region,stacks->retainstack); copy_stack_elements(stacks->retainstack_region,stacks->retainstack);
copy_handle(&stacks->catchstack_save); copy_handle(&stacks->catchstack_save);
copy_handle(&stacks->current_callback_save); copy_handle(&stacks->current_callback_save);
collect_callstack(stacks); copy_callstack_roots(stacks);
stacks = stacks->next; stacks = stacks->next;
} }
@ -610,23 +608,23 @@ void do_code_slots(CELL scan)
{ {
case WORD_TYPE: case WORD_TYPE:
word = (F_WORD *)scan; word = (F_WORD *)scan;
recursive_mark(compiled_to_block(word->code)); mark_block(compiled_to_block(word->code));
if(word->profiling) if(word->profiling)
recursive_mark(compiled_to_block(word->profiling)); mark_block(compiled_to_block(word->profiling));
break; break;
case QUOTATION_TYPE: case QUOTATION_TYPE:
quot = (F_QUOTATION *)scan; quot = (F_QUOTATION *)scan;
if(quot->compiledp != F) if(quot->compiledp != F)
recursive_mark(compiled_to_block(quot->code)); mark_block(compiled_to_block(quot->code));
break; break;
case CALLSTACK_TYPE: case CALLSTACK_TYPE:
stack = (F_CALLSTACK *)scan; stack = (F_CALLSTACK *)scan;
iterate_callstack_object(stack,collect_stack_frame); iterate_callstack_object(stack,copy_stack_frame_step);
break; break;
} }
} }
CELL collect_next_nursery(CELL scan) CELL copy_next_from_nursery(CELL scan)
{ {
CELL *obj = (CELL *)scan; CELL *obj = (CELL *)scan;
CELL *end = (CELL *)(scan + binary_payload_start(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); return scan + untagged_object_size(scan);
} }
CELL collect_next_aging(CELL scan) CELL copy_next_from_aging(CELL scan)
{ {
CELL *obj = (CELL *)scan; CELL *obj = (CELL *)scan;
CELL *end = (CELL *)(scan + binary_payload_start(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); return scan + untagged_object_size(scan);
} }
/* This function is performance-critical */ CELL copy_next_from_tenured(CELL scan)
CELL collect_next_tenured(CELL scan)
{ {
CELL *obj = (CELL *)scan; CELL *obj = (CELL *)scan;
CELL *end = (CELL *)(scan + binary_payload_start(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); 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) if(HAVE_NURSERY_P && collecting_gen == NURSERY)
{ {
while(scan < *end) while(scan < *end)
scan = collect_next_nursery(scan); scan = copy_next_from_nursery(scan);
} }
else if(HAVE_AGING_P && collecting_gen == AGING) else if(HAVE_AGING_P && collecting_gen == AGING)
{ {
while(scan < *end) while(scan < *end)
scan = collect_next_aging(scan); scan = copy_next_from_aging(scan);
} }
else if(collecting_gen == TENURED) else if(collecting_gen == TENURED)
{ {
while(scan < *end) 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; CELL scan = newspace->here;
/* collect objects referenced from stacks and environment */ /* collect objects referenced from stacks and environment */
collect_roots(); copy_roots();
/* collect objects referenced from older generations */ /* 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 /* don't scan code heap unless it has pointers to this
generation or younger */ generation or younger */
if(collecting_gen >= last_code_heap_scan) if(collecting_gen >= last_code_heap_scan)
{ {
if(collecting_gen != TENURED) code_heap_scans++;
{
/* if we are doing code GC, then we will copy over if(collecting_gen == TENURED)
literals from any code block which gets marked as live. update_code_heap_roots();
if we are not doing code GC, just consider all literals else
as roots. */ copy_code_heap_roots();
code_heap_scans++;
collect_literals();
}
if(collecting_accumulation_gen_p()) if(collecting_accumulation_gen_p())
last_code_heap_scan = collecting_gen; last_code_heap_scan = collecting_gen;
@ -905,8 +899,6 @@ void garbage_collection(CELL gen,
last_code_heap_scan = collecting_gen + 1; last_code_heap_scan = collecting_gen + 1;
} }
collect_next_loop(scan,&newspace->here);
CELL gc_elapsed = (current_micros() - start); CELL gc_elapsed = (current_micros() - start);
end_gc(gc_elapsed); end_gc(gc_elapsed);

View File

@ -126,7 +126,6 @@ INLINE void allot_barrier(CELL address)
} }
void clear_cards(CELL from, CELL to); void clear_cards(CELL from, CELL to);
void collect_cards(void);
/* the 0th generation is where new objects are allocated. */ /* the 0th generation is where new objects are allocated. */
#define NURSERY 0 #define NURSERY 0
@ -387,7 +386,7 @@ INLINE void* allot_object(CELL type, CELL a)
return object; 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(void);
void primitive_gc_stats(void); void primitive_gc_stats(void);

View File

@ -308,36 +308,6 @@ void find_data_references(CELL look_for_)
gc_off = false; 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) void factorbug(void)
{ {
if(fep_disabled) if(fep_disabled)
@ -464,8 +434,6 @@ void factorbug(void)
CELL addr = read_cell_hex(); CELL addr = read_cell_hex();
print_string("Data heap references:\n"); print_string("Data heap references:\n");
find_data_references(addr); find_data_references(addr);
print_string("Code heap references:\n");
find_code_references(addr);
nl(); nl();
} }
else if(strcmp(cmd,"words") == 0) else if(strcmp(cmd,"words") == 0)

View File

@ -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 */ /* relocate literal table data */
CELL scan;
CELL literal_end = literals_start + compiled->literals_length;
data_fixup(&compiled->relocation); data_fixup(&compiled->relocation);
data_fixup(&compiled->literals);
for(scan = literals_start; scan < literal_end; scan += CELLS) relocate_code_block(compiled);
data_fixup((CELL*)scan);
relocate_code_block(compiled,code_start,literals_start);
} }
void relocate_code() void relocate_code()

View File

@ -107,7 +107,7 @@ typedef struct
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 */
CELL code_length; /* # bytes */ CELL code_length; /* # bytes */
CELL literals_length; /* # bytes */ CELL literals; /* # bytes */
CELL relocation; /* tagged pointer to byte-array or f */ CELL relocation; /* tagged pointer to byte-array or f */
} F_COMPILED; } F_COMPILED;

View File

@ -26,7 +26,7 @@ F_COMPILED *compile_profiling_stub(F_WORD *word)
untag_object(code), untag_object(code),
NULL, /* no labels */ NULL, /* no labels */
tag_object(relocation), tag_object(relocation),
untag_object(literals)); literals);
} }
/* Allocates memory */ /* Allocates memory */

View File

@ -344,12 +344,12 @@ void jit_compile(CELL quot, bool relocate)
untag_object(code), untag_object(code),
NULL, NULL,
relocation, relocation,
untag_object(literals)); literals);
set_quot_xt(untag_object(quot),compiled); set_quot_xt(untag_object(quot),compiled);
if(relocate) if(relocate)
iterate_code_heap_step(compiled,relocate_code_block); relocate_code_block(compiled);
UNREGISTER_ROOT(literals); UNREGISTER_ROOT(literals);
UNREGISTER_ROOT(relocation); UNREGISTER_ROOT(relocation);

View File

@ -62,7 +62,7 @@ F_WORD *allot_word(CELL vocab, CELL name)
UNREGISTER_UNTAGGED(word); UNREGISTER_UNTAGGED(word);
if(profiling_p) if(profiling_p)
iterate_code_heap_step(word->profiling,relocate_code_block); relocate_code_block(word->profiling);
return word; return word;
} }