moved code_block functions to vm

db4
Phil Dawes 2009-08-17 21:37:07 +01:00
parent fdabc9a5d8
commit 0097e76a82
2 changed files with 235 additions and 46 deletions

247
vm/code_block.cpp Normal file → Executable file
View File

@ -3,27 +3,47 @@
namespace factor namespace factor
{ {
static relocation_type relocation_type_of(relocation_entry r) relocation_type factorvm::relocation_type_of(relocation_entry r)
{ {
return (relocation_type)((r & 0xf0000000) >> 28); return (relocation_type)((r & 0xf0000000) >> 28);
} }
static relocation_class relocation_class_of(relocation_entry r) relocation_type relocation_type_of(relocation_entry r)
{
return vm->relocation_type_of(r);
}
relocation_class factorvm::relocation_class_of(relocation_entry r)
{ {
return (relocation_class)((r & 0x0f000000) >> 24); return (relocation_class)((r & 0x0f000000) >> 24);
} }
static cell relocation_offset_of(relocation_entry r) relocation_class relocation_class_of(relocation_entry r)
{
return vm->relocation_class_of(r);
}
cell factorvm::relocation_offset_of(relocation_entry r)
{ {
return (r & 0x00ffffff); return (r & 0x00ffffff);
} }
void flush_icache_for(code_block *block) cell relocation_offset_of(relocation_entry r)
{
return vm->relocation_offset_of(r);
}
void factorvm::flush_icache_for(code_block *block)
{ {
flush_icache((cell)block,block->size); flush_icache((cell)block,block->size);
} }
static int number_of_parameters(relocation_type type) void flush_icache_for(code_block *block)
{
return vm->flush_icache_for(block);
}
int factorvm::number_of_parameters(relocation_type type)
{ {
switch(type) switch(type)
{ {
@ -47,7 +67,12 @@ static int number_of_parameters(relocation_type type)
} }
} }
void *object_xt(cell obj) int number_of_parameters(relocation_type type)
{
return vm->number_of_parameters(type);
}
void *factorvm::object_xt(cell obj)
{ {
switch(tagged<object>(obj).type()) switch(tagged<object>(obj).type())
{ {
@ -61,7 +86,12 @@ void *object_xt(cell obj)
} }
} }
static void *xt_pic(word *w, cell tagged_quot) void *object_xt(cell obj)
{
return vm->object_xt(obj);
}
void *factorvm::xt_pic(word *w, cell tagged_quot)
{ {
if(tagged_quot == F || max_pic_size == 0) if(tagged_quot == F || max_pic_size == 0)
return w->xt; return w->xt;
@ -75,25 +105,45 @@ static void *xt_pic(word *w, cell tagged_quot)
} }
} }
void *word_xt_pic(word *w) void *xt_pic(word *w, cell tagged_quot)
{
return vm->xt_pic(w,tagged_quot);
}
void *factorvm::word_xt_pic(word *w)
{ {
return xt_pic(w,w->pic_def); return xt_pic(w,w->pic_def);
} }
void *word_xt_pic_tail(word *w) void *word_xt_pic(word *w)
{
return vm->word_xt_pic(w);
}
void *factorvm::word_xt_pic_tail(word *w)
{ {
return xt_pic(w,w->pic_tail_def); return xt_pic(w,w->pic_tail_def);
} }
void *word_xt_pic_tail(word *w)
{
return vm->word_xt_pic_tail(w);
}
/* References to undefined symbols are patched up to call this function on /* References to undefined symbols are patched up to call this function on
image load */ image load */
void undefined_symbol() void factorvm::undefined_symbol()
{ {
general_error(ERROR_UNDEFINED_SYMBOL,F,F,NULL); general_error(ERROR_UNDEFINED_SYMBOL,F,F,NULL);
} }
void undefined_symbol()
{
return vm->undefined_symbol();
}
/* 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(array *literals, cell index) void *factorvm::get_rel_symbol(array *literals, cell index)
{ {
cell symbol = array_nth(literals,index); cell symbol = array_nth(literals,index);
cell library = array_nth(literals,index + 1); cell library = array_nth(literals,index + 1);
@ -101,7 +151,7 @@ void *get_rel_symbol(array *literals, cell index)
dll *d = (library == F ? NULL : untag<dll>(library)); dll *d = (library == F ? NULL : untag<dll>(library));
if(d != NULL && !d->dll) if(d != NULL && !d->dll)
return (void *)undefined_symbol; return (void *)factor::undefined_symbol;
switch(tagged<object>(symbol).type()) switch(tagged<object>(symbol).type())
{ {
@ -114,7 +164,7 @@ void *get_rel_symbol(array *literals, cell index)
return sym; return sym;
else else
{ {
return (void *)undefined_symbol; return (void *)factor::undefined_symbol;
} }
} }
case ARRAY_TYPE: case ARRAY_TYPE:
@ -129,15 +179,20 @@ void *get_rel_symbol(array *literals, cell index)
if(sym) if(sym)
return sym; return sym;
} }
return (void *)undefined_symbol; return (void *)factor::undefined_symbol;
} }
default: default:
critical_error("Bad symbol specifier",symbol); critical_error("Bad symbol specifier",symbol);
return (void *)undefined_symbol; return (void *)factor::undefined_symbol;
} }
} }
cell compute_relocation(relocation_entry rel, cell index, code_block *compiled) void *get_rel_symbol(array *literals, cell index)
{
return vm->get_rel_symbol(literals,index);
}
cell factorvm::compute_relocation(relocation_entry rel, cell index, code_block *compiled)
{ {
array *literals = untag<array>(compiled->literals); array *literals = untag<array>(compiled->literals);
cell offset = relocation_offset_of(rel) + (cell)compiled->xt(); cell offset = relocation_offset_of(rel) + (cell)compiled->xt();
@ -179,7 +234,12 @@ cell compute_relocation(relocation_entry rel, cell index, code_block *compiled)
#undef ARG #undef ARG
} }
void iterate_relocations(code_block *compiled, relocation_iterator iter) cell compute_relocation(relocation_entry rel, cell index, code_block *compiled)
{
return vm->compute_relocation(rel,index,compiled);
}
void factorvm::iterate_relocations(code_block *compiled, relocation_iterator iter)
{ {
if(compiled->relocation != F) if(compiled->relocation != F)
{ {
@ -197,15 +257,25 @@ void iterate_relocations(code_block *compiled, relocation_iterator iter)
} }
} }
void iterate_relocations(code_block *compiled, relocation_iterator iter)
{
return vm->iterate_relocations(compiled,iter);
}
/* Store a 32-bit value into a PowerPC LIS/ORI sequence */ /* Store a 32-bit value into a PowerPC LIS/ORI sequence */
static void store_address_2_2(cell *ptr, cell value) void factorvm::store_address_2_2(cell *ptr, cell value)
{ {
ptr[-1] = ((ptr[-1] & ~0xffff) | ((value >> 16) & 0xffff)); ptr[-1] = ((ptr[-1] & ~0xffff) | ((value >> 16) & 0xffff));
ptr[ 0] = ((ptr[ 0] & ~0xffff) | (value & 0xffff)); ptr[ 0] = ((ptr[ 0] & ~0xffff) | (value & 0xffff));
} }
void store_address_2_2(cell *ptr, cell value)
{
return vm->store_address_2_2(ptr,value);
}
/* Store a value into a bitfield of a PowerPC instruction */ /* Store a value into a bitfield of a PowerPC instruction */
static void store_address_masked(cell *ptr, fixnum value, cell mask, fixnum shift) void factorvm::store_address_masked(cell *ptr, fixnum value, cell mask, fixnum shift)
{ {
/* This is unaccurate but good enough */ /* This is unaccurate but good enough */
fixnum test = (fixnum)mask >> 1; fixnum test = (fixnum)mask >> 1;
@ -215,8 +285,13 @@ static void store_address_masked(cell *ptr, fixnum value, cell mask, fixnum shif
*ptr = ((*ptr & ~mask) | ((value >> shift) & mask)); *ptr = ((*ptr & ~mask) | ((value >> shift) & mask));
} }
void store_address_masked(cell *ptr, fixnum value, cell mask, fixnum shift)
{
return vm->store_address_masked(ptr,value,mask,shift);
}
/* Perform a fixup on a code block */ /* Perform a fixup on a code block */
void store_address_in_code_block(cell klass, cell offset, fixnum absolute_value) void factorvm::store_address_in_code_block(cell klass, cell offset, fixnum absolute_value)
{ {
fixnum relative_value = absolute_value - offset; fixnum relative_value = absolute_value - offset;
@ -261,7 +336,12 @@ void store_address_in_code_block(cell klass, cell offset, fixnum absolute_value)
} }
} }
void update_literal_references_step(relocation_entry rel, cell index, code_block *compiled) void store_address_in_code_block(cell klass, cell offset, fixnum absolute_value)
{
return vm->store_address_in_code_block(klass,offset,absolute_value);
}
void factorvm::update_literal_references_step(relocation_entry rel, cell index, code_block *compiled)
{ {
if(relocation_type_of(rel) == RT_IMMEDIATE) if(relocation_type_of(rel) == RT_IMMEDIATE)
{ {
@ -272,19 +352,29 @@ void update_literal_references_step(relocation_entry rel, cell index, code_block
} }
} }
void update_literal_references_step(relocation_entry rel, cell index, code_block *compiled)
{
return vm->update_literal_references_step(rel,index,compiled);
}
/* Update pointers to literals from compiled code. */ /* Update pointers to literals from compiled code. */
void update_literal_references(code_block *compiled) void factorvm::update_literal_references(code_block *compiled)
{ {
if(!compiled->needs_fixup) if(!compiled->needs_fixup)
{ {
iterate_relocations(compiled,update_literal_references_step); iterate_relocations(compiled,factor::update_literal_references_step);
flush_icache_for(compiled); flush_icache_for(compiled);
} }
} }
void update_literal_references(code_block *compiled)
{
return vm->update_literal_references(compiled);
}
/* Copy all literals referenced from a code block to newspace. Only for /* Copy all literals referenced from a code block to newspace. Only for
aging and nursery collections */ aging and nursery collections */
void copy_literal_references(code_block *compiled) void factorvm::copy_literal_references(code_block *compiled)
{ {
if(collecting_gen >= compiled->last_scan) if(collecting_gen >= compiled->last_scan)
{ {
@ -307,8 +397,13 @@ void copy_literal_references(code_block *compiled)
} }
} }
void copy_literal_references(code_block *compiled)
{
return vm->copy_literal_references(compiled);
}
/* Compute an address to store at a relocation */ /* Compute an address to store at a relocation */
void relocate_code_block_step(relocation_entry rel, cell index, code_block *compiled) void factorvm::relocate_code_block_step(relocation_entry rel, cell index, code_block *compiled)
{ {
#ifdef FACTOR_DEBUG #ifdef FACTOR_DEBUG
tagged<array>(compiled->literals).untag_check(); tagged<array>(compiled->literals).untag_check();
@ -320,18 +415,28 @@ void relocate_code_block_step(relocation_entry rel, cell index, code_block *comp
compute_relocation(rel,index,compiled)); compute_relocation(rel,index,compiled));
} }
void update_word_references_step(relocation_entry rel, cell index, code_block *compiled) void relocate_code_block_step(relocation_entry rel, cell index, code_block *compiled)
{
return vm->relocate_code_block_step(rel,index,compiled);
}
void factorvm::update_word_references_step(relocation_entry rel, cell index, code_block *compiled)
{ {
relocation_type type = relocation_type_of(rel); relocation_type type = relocation_type_of(rel);
if(type == RT_XT || type == RT_XT_PIC || type == RT_XT_PIC_TAIL) if(type == RT_XT || type == RT_XT_PIC || type == RT_XT_PIC_TAIL)
relocate_code_block_step(rel,index,compiled); relocate_code_block_step(rel,index,compiled);
} }
void update_word_references_step(relocation_entry rel, cell index, code_block *compiled)
{
return vm->update_word_references_step(rel,index,compiled);
}
/* Relocate new code blocks completely; updating references to literals, /* Relocate new code blocks completely; updating references to literals,
dlsyms, and words. For all other words in the code heap, we only need dlsyms, and words. For all other words in the code heap, we only need
to update references to other words, without worrying about literals to update references to other words, without worrying about literals
or dlsyms. */ or dlsyms. */
void update_word_references(code_block *compiled) void factorvm::update_word_references(code_block *compiled)
{ {
if(compiled->needs_fixup) if(compiled->needs_fixup)
relocate_code_block(compiled); relocate_code_block(compiled);
@ -346,30 +451,45 @@ void update_word_references(code_block *compiled)
heap_free(&code,compiled); heap_free(&code,compiled);
else else
{ {
iterate_relocations(compiled,update_word_references_step); iterate_relocations(compiled,factor::update_word_references_step);
flush_icache_for(compiled); flush_icache_for(compiled);
} }
} }
void update_literal_and_word_references(code_block *compiled) void update_word_references(code_block *compiled)
{
return vm->update_word_references(compiled);
}
void factorvm::update_literal_and_word_references(code_block *compiled)
{ {
update_literal_references(compiled); update_literal_references(compiled);
update_word_references(compiled); update_word_references(compiled);
} }
static void check_code_address(cell address) void update_literal_and_word_references(code_block *compiled)
{
return vm->update_literal_and_word_references(compiled);
}
void factorvm::check_code_address(cell address)
{ {
#ifdef FACTOR_DEBUG #ifdef FACTOR_DEBUG
assert(address >= code.seg->start && address < code.seg->end); assert(address >= code.seg->start && address < code.seg->end);
#endif #endif
} }
void check_code_address(cell address)
{
return vm->check_code_address(address);
}
/* Update references to words. This is done after a new code block /* Update references to words. This is done after a new code block
is added to the heap. */ is added to the heap. */
/* Mark all literals referenced from a word XT. Only for tenured /* Mark all literals referenced from a word XT. Only for tenured
collections */ collections */
void mark_code_block(code_block *compiled) void factorvm::mark_code_block(code_block *compiled)
{ {
check_code_address((cell)compiled); check_code_address((cell)compiled);
@ -379,24 +499,39 @@ void mark_code_block(code_block *compiled)
copy_handle(&compiled->relocation); copy_handle(&compiled->relocation);
} }
void mark_stack_frame_step(stack_frame *frame) void mark_code_block(code_block *compiled)
{
return vm->mark_code_block(compiled);
}
void factorvm::mark_stack_frame_step(stack_frame *frame)
{ {
mark_code_block(frame_code(frame)); mark_code_block(frame_code(frame));
} }
void mark_stack_frame_step(stack_frame *frame)
{
return vm->mark_stack_frame_step(frame);
}
/* Mark code blocks executing in currently active stack frames. */ /* Mark code blocks executing in currently active stack frames. */
void mark_active_blocks(context *stacks) void factorvm::mark_active_blocks(context *stacks)
{ {
if(collecting_gen == data->tenured()) if(collecting_gen == data->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,mark_stack_frame_step); iterate_callstack(top,bottom,factor::mark_stack_frame_step);
} }
} }
void mark_object_code_block(object *object) void mark_active_blocks(context *stacks)
{
return vm->mark_active_blocks(stacks);
}
void factorvm::mark_object_code_block(object *object)
{ {
switch(object->h.hi_tag()) switch(object->h.hi_tag())
{ {
@ -419,23 +554,33 @@ void mark_object_code_block(object *object)
case CALLSTACK_TYPE: case CALLSTACK_TYPE:
{ {
callstack *stack = (callstack *)object; callstack *stack = (callstack *)object;
iterate_callstack_object(stack,mark_stack_frame_step); iterate_callstack_object(stack,factor::mark_stack_frame_step);
break; break;
} }
} }
} }
void mark_object_code_block(object *object)
{
return vm->mark_object_code_block(object);
}
/* Perform all fixups on a code block */ /* Perform all fixups on a code block */
void relocate_code_block(code_block *compiled) void factorvm::relocate_code_block(code_block *compiled)
{ {
compiled->last_scan = data->nursery(); compiled->last_scan = data->nursery();
compiled->needs_fixup = false; compiled->needs_fixup = false;
iterate_relocations(compiled,relocate_code_block_step); iterate_relocations(compiled,factor::relocate_code_block_step);
flush_icache_for(compiled); flush_icache_for(compiled);
} }
void relocate_code_block(code_block *compiled)
{
return vm->relocate_code_block(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(array *labels, code_block *compiled) void factorvm::fixup_labels(array *labels, code_block *compiled)
{ {
cell i; cell i;
cell size = array_capacity(labels); cell size = array_capacity(labels);
@ -452,8 +597,13 @@ void fixup_labels(array *labels, code_block *compiled)
} }
} }
void fixup_labels(array *labels, code_block *compiled)
{
return vm->fixup_labels(labels,compiled);
}
/* Might GC */ /* Might GC */
code_block *allot_code_block(cell size) code_block *factorvm::allot_code_block(cell size)
{ {
heap_block *block = heap_allot(&code,size + sizeof(code_block)); heap_block *block = heap_allot(&code,size + sizeof(code_block));
@ -480,13 +630,13 @@ code_block *allot_code_block(cell size)
return (code_block *)block; return (code_block *)block;
} }
code_block *allot_code_block(cell size)
{
return vm->allot_code_block(size);
}
/* Might GC */ /* Might GC */
code_block *add_code_block( code_block *factorvm::add_code_block(cell type,cell code_,cell labels_,cell relocation_,cell literals_)
cell type,
cell code_,
cell labels_,
cell relocation_,
cell literals_)
{ {
gc_root<byte_array> code(code_); gc_root<byte_array> code(code_);
gc_root<object> labels(labels_); gc_root<object> labels(labels_);
@ -522,4 +672,9 @@ code_block *add_code_block(
return compiled; return compiled;
} }
code_block *add_code_block(cell type,cell code_,cell labels_,cell relocation_,cell literals_)
{
return vm->add_code_block(type,code_,labels_,relocation_,literals_);
}
} }

View File

@ -348,6 +348,40 @@ struct factorvm {
cell heap_size(heap *heap); cell heap_size(heap *heap);
cell compute_heap_forwarding(heap *heap, unordered_map<heap_block *,char *> &forwarding); cell compute_heap_forwarding(heap *heap, unordered_map<heap_block *,char *> &forwarding);
void compact_heap(heap *heap, unordered_map<heap_block *,char *> &forwarding); void compact_heap(heap *heap, unordered_map<heap_block *,char *> &forwarding);
//code_block
relocation_type relocation_type_of(relocation_entry r);
relocation_class relocation_class_of(relocation_entry r);
cell relocation_offset_of(relocation_entry r);
void flush_icache_for(code_block *block);
int number_of_parameters(relocation_type type);
void *object_xt(cell obj);
void *xt_pic(word *w, cell tagged_quot);
void *word_xt_pic(word *w);
void *word_xt_pic_tail(word *w);
void undefined_symbol();
void *get_rel_symbol(array *literals, cell index);
cell compute_relocation(relocation_entry rel, cell index, code_block *compiled);
void iterate_relocations(code_block *compiled, relocation_iterator iter);
void store_address_2_2(cell *ptr, cell value);
void store_address_masked(cell *ptr, fixnum value, cell mask, fixnum shift);
void store_address_in_code_block(cell klass, cell offset, fixnum absolute_value);
void update_literal_references_step(relocation_entry rel, cell index, code_block *compiled);
void update_literal_references(code_block *compiled);
void copy_literal_references(code_block *compiled);
void relocate_code_block_step(relocation_entry rel, cell index, code_block *compiled);
void update_word_references_step(relocation_entry rel, cell index, code_block *compiled);
void update_word_references(code_block *compiled);
void update_literal_and_word_references(code_block *compiled);
void check_code_address(cell address);
void mark_code_block(code_block *compiled);
void mark_stack_frame_step(stack_frame *frame);
void mark_active_blocks(context *stacks);
void mark_object_code_block(object *object);
void relocate_code_block(code_block *compiled);
void fixup_labels(array *labels, code_block *compiled);
code_block *allot_code_block(cell size);
code_block *add_code_block(cell type,cell code_,cell labels_,cell relocation_,cell literals_);
// next method here: // next method here: