moved code_block functions to vm
parent
fdabc9a5d8
commit
0097e76a82
|
@ -3,27 +3,47 @@
|
|||
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);
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
|
@ -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())
|
||||
{
|
||||
|
@ -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)
|
||||
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);
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
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
|
||||
image load */
|
||||
void undefined_symbol()
|
||||
void factorvm::undefined_symbol()
|
||||
{
|
||||
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 */
|
||||
void *get_rel_symbol(array *literals, cell index)
|
||||
void *factorvm::get_rel_symbol(array *literals, cell index)
|
||||
{
|
||||
cell symbol = array_nth(literals,index);
|
||||
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));
|
||||
|
||||
if(d != NULL && !d->dll)
|
||||
return (void *)undefined_symbol;
|
||||
return (void *)factor::undefined_symbol;
|
||||
|
||||
switch(tagged<object>(symbol).type())
|
||||
{
|
||||
|
@ -114,7 +164,7 @@ void *get_rel_symbol(array *literals, cell index)
|
|||
return sym;
|
||||
else
|
||||
{
|
||||
return (void *)undefined_symbol;
|
||||
return (void *)factor::undefined_symbol;
|
||||
}
|
||||
}
|
||||
case ARRAY_TYPE:
|
||||
|
@ -129,15 +179,20 @@ void *get_rel_symbol(array *literals, cell index)
|
|||
if(sym)
|
||||
return sym;
|
||||
}
|
||||
return (void *)undefined_symbol;
|
||||
return (void *)factor::undefined_symbol;
|
||||
}
|
||||
default:
|
||||
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);
|
||||
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
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
|
@ -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 */
|
||||
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[ 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 */
|
||||
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 */
|
||||
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));
|
||||
}
|
||||
|
||||
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 */
|
||||
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;
|
||||
|
||||
|
@ -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)
|
||||
{
|
||||
|
@ -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. */
|
||||
void update_literal_references(code_block *compiled)
|
||||
void factorvm::update_literal_references(code_block *compiled)
|
||||
{
|
||||
if(!compiled->needs_fixup)
|
||||
{
|
||||
iterate_relocations(compiled,update_literal_references_step);
|
||||
iterate_relocations(compiled,factor::update_literal_references_step);
|
||||
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
|
||||
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)
|
||||
{
|
||||
|
@ -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 */
|
||||
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
|
||||
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));
|
||||
}
|
||||
|
||||
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);
|
||||
if(type == RT_XT || type == RT_XT_PIC || type == RT_XT_PIC_TAIL)
|
||||
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,
|
||||
dlsyms, and words. For all other words in the code heap, we only need
|
||||
to update references to other words, without worrying about literals
|
||||
or dlsyms. */
|
||||
void update_word_references(code_block *compiled)
|
||||
void factorvm::update_word_references(code_block *compiled)
|
||||
{
|
||||
if(compiled->needs_fixup)
|
||||
relocate_code_block(compiled);
|
||||
|
@ -346,30 +451,45 @@ void update_word_references(code_block *compiled)
|
|||
heap_free(&code,compiled);
|
||||
else
|
||||
{
|
||||
iterate_relocations(compiled,update_word_references_step);
|
||||
iterate_relocations(compiled,factor::update_word_references_step);
|
||||
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_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
|
||||
assert(address >= code.seg->start && address < code.seg->end);
|
||||
#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
|
||||
is added to the heap. */
|
||||
|
||||
/* Mark all literals referenced from a word XT. Only for tenured
|
||||
collections */
|
||||
void mark_code_block(code_block *compiled)
|
||||
void factorvm::mark_code_block(code_block *compiled)
|
||||
{
|
||||
check_code_address((cell)compiled);
|
||||
|
||||
|
@ -379,24 +499,39 @@ void mark_code_block(code_block *compiled)
|
|||
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));
|
||||
}
|
||||
|
||||
void mark_stack_frame_step(stack_frame *frame)
|
||||
{
|
||||
return vm->mark_stack_frame_step(frame);
|
||||
}
|
||||
|
||||
/* 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())
|
||||
{
|
||||
cell top = (cell)stacks->callstack_top;
|
||||
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())
|
||||
{
|
||||
|
@ -419,23 +554,33 @@ void mark_object_code_block(object *object)
|
|||
case CALLSTACK_TYPE:
|
||||
{
|
||||
callstack *stack = (callstack *)object;
|
||||
iterate_callstack_object(stack,mark_stack_frame_step);
|
||||
iterate_callstack_object(stack,factor::mark_stack_frame_step);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void mark_object_code_block(object *object)
|
||||
{
|
||||
return vm->mark_object_code_block(object);
|
||||
}
|
||||
|
||||
/* 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->needs_fixup = false;
|
||||
iterate_relocations(compiled,relocate_code_block_step);
|
||||
iterate_relocations(compiled,factor::relocate_code_block_step);
|
||||
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 */
|
||||
void fixup_labels(array *labels, code_block *compiled)
|
||||
void factorvm::fixup_labels(array *labels, code_block *compiled)
|
||||
{
|
||||
cell i;
|
||||
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 */
|
||||
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));
|
||||
|
||||
|
@ -480,13 +630,13 @@ code_block *allot_code_block(cell size)
|
|||
return (code_block *)block;
|
||||
}
|
||||
|
||||
code_block *allot_code_block(cell size)
|
||||
{
|
||||
return vm->allot_code_block(size);
|
||||
}
|
||||
|
||||
/* Might GC */
|
||||
code_block *add_code_block(
|
||||
cell type,
|
||||
cell code_,
|
||||
cell labels_,
|
||||
cell relocation_,
|
||||
cell literals_)
|
||||
code_block *factorvm::add_code_block(cell type,cell code_,cell labels_,cell relocation_,cell literals_)
|
||||
{
|
||||
gc_root<byte_array> code(code_);
|
||||
gc_root<object> labels(labels_);
|
||||
|
@ -522,4 +672,9 @@ code_block *add_code_block(
|
|||
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_);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
34
vm/vm.hpp
34
vm/vm.hpp
|
@ -348,6 +348,40 @@ struct factorvm {
|
|||
cell heap_size(heap *heap);
|
||||
cell compute_heap_forwarding(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:
|
||||
|
||||
|
||||
|
|
Loading…
Reference in New Issue