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,31 +251,17 @@ 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(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);
if(compiled->relocation != F) if(compiled->relocation != F)
{ {
copy_handle(&compiled->relocation); F_ARRAY *literals = untag_object(compiled->literals);
F_BYTE_ARRAY *relocation = untag_object(compiled->relocation); F_BYTE_ARRAY *relocation = untag_object(compiled->relocation);
F_REL *rel = (F_REL *)(relocation + 1); F_REL *rel = (F_REL *)(relocation + 1);
@ -285,8 +271,8 @@ void collect_literals_step(F_COMPILED *compiled, CELL code_start, CELL literals_
{ {
if(REL_TYPE(rel) == RT_IMMEDIATE) if(REL_TYPE(rel) == RT_IMMEDIATE)
{ {
CELL offset = rel->offset + code_start; CELL offset = rel->offset + (CELL)(compiled + 1);
F_FIXNUM absolute_value = get(CREF(literals_start,REL_ARGUMENT(rel))); F_FIXNUM absolute_value = array_nth(literals,REL_ARGUMENT(rel));
apply_relocation(REL_CLASS(rel),offset,absolute_value); apply_relocation(REL_CLASS(rel),offset,absolute_value);
} }
@ -294,18 +280,44 @@ void collect_literals_step(F_COMPILED *compiled, CELL code_start, CELL literals_
} }
} }
flush_icache(code_start,literals_start - code_start); 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_accumulation_gen_p())
compiled->last_scan = collecting_gen;
else
compiled->last_scan = collecting_gen + 1;
/* initialize chase pointer */
CELL scan = newspace->here;
copy_handle(&compiled->literals);
copy_handle(&compiled->relocation);
/* do some tracing so that all reachable literals are now
at their final address */
copy_reachable_objects(scan,&newspace->here);
update_literal_references(compiled);
} }
} }
/* 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)
{
/* 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()) 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;
} }