vm: Clean up more code duplication and rename a few methods
parent
d664507b36
commit
d49c86ba11
|
@ -3,66 +3,7 @@
|
|||
namespace factor
|
||||
{
|
||||
|
||||
cell factor_vm::compute_primitive_relocation(cell arg)
|
||||
{
|
||||
return (cell)primitives[untag_fixnum(arg)];
|
||||
}
|
||||
|
||||
/* References to undefined symbols are patched up to call this function on
|
||||
image load */
|
||||
void factor_vm::undefined_symbol()
|
||||
{
|
||||
general_error(ERROR_UNDEFINED_SYMBOL,false_object,false_object,NULL);
|
||||
}
|
||||
|
||||
void undefined_symbol()
|
||||
{
|
||||
return tls_vm()->undefined_symbol();
|
||||
}
|
||||
|
||||
/* Look up an external library symbol referenced by a compiled code block */
|
||||
cell factor_vm::compute_dlsym_relocation(array *literals, cell index)
|
||||
{
|
||||
cell symbol = array_nth(literals,index);
|
||||
cell library = array_nth(literals,index + 1);
|
||||
|
||||
dll *d = (to_boolean(library) ? untag<dll>(library) : NULL);
|
||||
|
||||
if(d != NULL && !d->dll)
|
||||
return (cell)factor::undefined_symbol;
|
||||
|
||||
switch(tagged<object>(symbol).type())
|
||||
{
|
||||
case BYTE_ARRAY_TYPE:
|
||||
{
|
||||
symbol_char *name = alien_offset(symbol);
|
||||
void *sym = ffi_dlsym(d,name);
|
||||
|
||||
if(sym)
|
||||
return (cell)sym;
|
||||
else
|
||||
return (cell)factor::undefined_symbol;
|
||||
}
|
||||
case ARRAY_TYPE:
|
||||
{
|
||||
array *names = untag<array>(symbol);
|
||||
for(cell i = 0; i < array_capacity(names); i++)
|
||||
{
|
||||
symbol_char *name = alien_offset(array_nth(names,i));
|
||||
void *sym = ffi_dlsym(d,name);
|
||||
|
||||
if(sym)
|
||||
return (cell)sym;
|
||||
}
|
||||
return (cell)factor::undefined_symbol;
|
||||
}
|
||||
default:
|
||||
critical_error("Bad symbol specifier",symbol);
|
||||
return (cell)factor::undefined_symbol;
|
||||
}
|
||||
}
|
||||
|
||||
cell factor_vm::compute_xt_relocation(cell obj)
|
||||
cell factor_vm::compute_xt_address(cell obj)
|
||||
{
|
||||
switch(tagged<object>(obj).type())
|
||||
{
|
||||
|
@ -76,7 +17,7 @@ cell factor_vm::compute_xt_relocation(cell obj)
|
|||
}
|
||||
}
|
||||
|
||||
cell factor_vm::compute_xt_pic_relocation(word *w, cell tagged_quot)
|
||||
cell factor_vm::compute_xt_pic_address(word *w, cell tagged_quot)
|
||||
{
|
||||
if(!to_boolean(tagged_quot) || max_pic_size == 0)
|
||||
return (cell)w->xt;
|
||||
|
@ -90,32 +31,16 @@ cell factor_vm::compute_xt_pic_relocation(word *w, cell tagged_quot)
|
|||
}
|
||||
}
|
||||
|
||||
cell factor_vm::compute_xt_pic_relocation(cell w_)
|
||||
cell factor_vm::compute_xt_pic_address(cell w_)
|
||||
{
|
||||
tagged<word> w(w_);
|
||||
return compute_xt_pic_relocation(w.untagged(),w->pic_def);
|
||||
return compute_xt_pic_address(w.untagged(),w->pic_def);
|
||||
}
|
||||
|
||||
cell factor_vm::compute_xt_pic_tail_relocation(cell w_)
|
||||
cell factor_vm::compute_xt_pic_tail_address(cell w_)
|
||||
{
|
||||
tagged<word> w(w_);
|
||||
return compute_xt_pic_relocation(w.untagged(),w->pic_tail_def);
|
||||
}
|
||||
|
||||
cell factor_vm::compute_here_relocation(cell arg, cell offset, code_block *compiled)
|
||||
{
|
||||
fixnum n = untag_fixnum(arg);
|
||||
return n >= 0 ? ((cell)compiled->xt() + offset + n) : ((cell)compiled->xt() - n);
|
||||
}
|
||||
|
||||
cell factor_vm::compute_context_relocation()
|
||||
{
|
||||
return (cell)&ctx;
|
||||
}
|
||||
|
||||
cell factor_vm::compute_vm_relocation(cell arg)
|
||||
{
|
||||
return (cell)this + untag_fixnum(arg);
|
||||
return compute_xt_pic_address(w.untagged(),w->pic_tail_def);
|
||||
}
|
||||
|
||||
cell factor_vm::code_block_owner(code_block *compiled)
|
||||
|
@ -157,19 +82,19 @@ struct update_word_references_relocation_visitor {
|
|||
case RT_XT:
|
||||
{
|
||||
code_block *compiled = op.load_code_block();
|
||||
op.store_value(parent->compute_xt_relocation(compiled->owner));
|
||||
op.store_value(parent->compute_xt_address(compiled->owner));
|
||||
break;
|
||||
}
|
||||
case RT_XT_PIC:
|
||||
{
|
||||
code_block *compiled = op.load_code_block();
|
||||
op.store_value(parent->compute_xt_pic_relocation(parent->code_block_owner(compiled)));
|
||||
op.store_value(parent->compute_xt_pic_address(parent->code_block_owner(compiled)));
|
||||
break;
|
||||
}
|
||||
case RT_XT_PIC_TAIL:
|
||||
{
|
||||
code_block *compiled = op.load_code_block();
|
||||
op.store_value(parent->compute_xt_pic_tail_relocation(parent->code_block_owner(compiled)));
|
||||
op.store_value(parent->compute_xt_pic_tail_address(parent->code_block_owner(compiled)));
|
||||
break;
|
||||
}
|
||||
default:
|
||||
|
@ -185,7 +110,7 @@ or dlsyms. */
|
|||
void factor_vm::update_word_references(code_block *compiled)
|
||||
{
|
||||
if(code->needs_fixup_p(compiled))
|
||||
relocate_code_block(compiled);
|
||||
initialize_code_block(compiled);
|
||||
/* update_word_references() is always applied to every block in
|
||||
the code heap. Since it resets all call sites to point to
|
||||
their canonical XT (cold entry point for non-tail calls,
|
||||
|
@ -210,7 +135,82 @@ void factor_vm::check_code_address(cell address)
|
|||
#endif
|
||||
}
|
||||
|
||||
void factor_vm::store_external_relocation(instruction_operand op)
|
||||
|
||||
cell factor_vm::compute_primitive_address(cell arg)
|
||||
{
|
||||
return (cell)primitives[untag_fixnum(arg)];
|
||||
}
|
||||
|
||||
/* References to undefined symbols are patched up to call this function on
|
||||
image load */
|
||||
void factor_vm::undefined_symbol()
|
||||
{
|
||||
general_error(ERROR_UNDEFINED_SYMBOL,false_object,false_object,NULL);
|
||||
}
|
||||
|
||||
void undefined_symbol()
|
||||
{
|
||||
return tls_vm()->undefined_symbol();
|
||||
}
|
||||
|
||||
/* Look up an external library symbol referenced by a compiled code block */
|
||||
cell factor_vm::compute_dlsym_address(array *literals, cell index)
|
||||
{
|
||||
cell symbol = array_nth(literals,index);
|
||||
cell library = array_nth(literals,index + 1);
|
||||
|
||||
dll *d = (to_boolean(library) ? untag<dll>(library) : NULL);
|
||||
|
||||
if(d != NULL && !d->dll)
|
||||
return (cell)factor::undefined_symbol;
|
||||
|
||||
switch(tagged<object>(symbol).type())
|
||||
{
|
||||
case BYTE_ARRAY_TYPE:
|
||||
{
|
||||
symbol_char *name = alien_offset(symbol);
|
||||
void *sym = ffi_dlsym(d,name);
|
||||
|
||||
if(sym)
|
||||
return (cell)sym;
|
||||
else
|
||||
return (cell)factor::undefined_symbol;
|
||||
}
|
||||
case ARRAY_TYPE:
|
||||
{
|
||||
array *names = untag<array>(symbol);
|
||||
for(cell i = 0; i < array_capacity(names); i++)
|
||||
{
|
||||
symbol_char *name = alien_offset(array_nth(names,i));
|
||||
void *sym = ffi_dlsym(d,name);
|
||||
|
||||
if(sym)
|
||||
return (cell)sym;
|
||||
}
|
||||
return (cell)factor::undefined_symbol;
|
||||
}
|
||||
default:
|
||||
critical_error("Bad symbol specifier",symbol);
|
||||
return (cell)factor::undefined_symbol;
|
||||
}
|
||||
}
|
||||
cell factor_vm::compute_here_address(cell arg, cell offset, code_block *compiled)
|
||||
{
|
||||
fixnum n = untag_fixnum(arg);
|
||||
return n >= 0 ? ((cell)compiled->xt() + offset + n) : ((cell)compiled->xt() - n);
|
||||
}
|
||||
|
||||
cell factor_vm::compute_context_address()
|
||||
{
|
||||
return (cell)&ctx;
|
||||
}
|
||||
|
||||
cell factor_vm::compute_vm_address(cell arg)
|
||||
{
|
||||
return (cell)this + untag_fixnum(arg);
|
||||
}
|
||||
|
||||
void factor_vm::store_external_address(instruction_operand op)
|
||||
{
|
||||
code_block *compiled = op.parent_code_block();
|
||||
array *literals = (to_boolean(compiled->literals) ? untag<array>(compiled->literals) : NULL);
|
||||
|
@ -219,34 +219,34 @@ void factor_vm::store_external_relocation(instruction_operand op)
|
|||
switch(op.rel_type())
|
||||
{
|
||||
case RT_PRIMITIVE:
|
||||
op.store_value(parent->compute_primitive_relocation(array_nth(literals,index)));
|
||||
op.store_value(compute_primitive_address(array_nth(literals,index)));
|
||||
break;
|
||||
case RT_DLSYM:
|
||||
op.store_value(parent->compute_dlsym_relocation(literals,index));
|
||||
op.store_value(compute_dlsym_address(literals,index));
|
||||
break;
|
||||
case RT_HERE:
|
||||
op.store_value(parent->compute_here_relocation(array_nth(literals,index),op.rel_offset(),compiled));
|
||||
op.store_value(compute_here_address(array_nth(literals,index),op.rel_offset(),compiled));
|
||||
break;
|
||||
case RT_THIS:
|
||||
op.store_value((cell)compiled->xt());
|
||||
break;
|
||||
case RT_CONTEXT:
|
||||
op.store_value(parent->compute_context_relocation());
|
||||
op.store_value(compute_context_address());
|
||||
break;
|
||||
case RT_UNTAGGED:
|
||||
op.store_value(untag_fixnum(array_nth(literals,index)));
|
||||
break;
|
||||
case RT_MEGAMORPHIC_CACHE_HITS:
|
||||
op.store_value((cell)&parent->dispatch_stats.megamorphic_cache_hits);
|
||||
op.store_value((cell)&dispatch_stats.megamorphic_cache_hits);
|
||||
break;
|
||||
case RT_VM:
|
||||
op.store_value(parent->compute_vm_relocation(array_nth(literals,index)));
|
||||
op.store_value(compute_vm_address(array_nth(literals,index)));
|
||||
break;
|
||||
case RT_CARDS_OFFSET:
|
||||
op.store_value(parent->cards_offset);
|
||||
op.store_value(cards_offset);
|
||||
break;
|
||||
case RT_DECKS_OFFSET:
|
||||
op.store_value(parent->decks_offset);
|
||||
op.store_value(decks_offset);
|
||||
break;
|
||||
default:
|
||||
critical_error("Bad rel type",op.rel_type());
|
||||
|
@ -254,10 +254,10 @@ void factor_vm::store_external_relocation(instruction_operand op)
|
|||
}
|
||||
}
|
||||
|
||||
struct relocate_code_block_relocation_visitor {
|
||||
struct initial_code_block_visitor {
|
||||
factor_vm *parent;
|
||||
|
||||
explicit relocate_code_block_relocation_visitor(factor_vm *parent_) : parent(parent_) {}
|
||||
explicit initial_code_block_visitor(factor_vm *parent_) : parent(parent_) {}
|
||||
|
||||
void operator()(instruction_operand op)
|
||||
{
|
||||
|
@ -271,26 +271,26 @@ struct relocate_code_block_relocation_visitor {
|
|||
op.store_value(array_nth(literals,index));
|
||||
break;
|
||||
case RT_XT:
|
||||
op.store_value(parent->compute_xt_relocation(array_nth(literals,index)));
|
||||
op.store_value(parent->compute_xt_address(array_nth(literals,index)));
|
||||
break;
|
||||
case RT_XT_PIC:
|
||||
op.store_value(parent->compute_xt_pic_relocation(array_nth(literals,index)));
|
||||
op.store_value(parent->compute_xt_pic_address(array_nth(literals,index)));
|
||||
break;
|
||||
case RT_XT_PIC_TAIL:
|
||||
op.store_value(parent->compute_xt_pic_tail_relocation(array_nth(literals,index)));
|
||||
op.store_value(parent->compute_xt_pic_tail_address(array_nth(literals,index)));
|
||||
break;
|
||||
default:
|
||||
parent->store_external_relocation(op);
|
||||
parent->store_external_address(op);
|
||||
break;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
/* Perform all fixups on a code block */
|
||||
void factor_vm::relocate_code_block(code_block *compiled)
|
||||
void factor_vm::initialize_code_block(code_block *compiled)
|
||||
{
|
||||
code->needs_fixup.erase(compiled);
|
||||
relocate_code_block_relocation_visitor visitor(this);
|
||||
initial_code_block_visitor visitor(this);
|
||||
compiled->each_instruction_operand(visitor);
|
||||
compiled->flush_icache();
|
||||
}
|
||||
|
|
|
@ -8,7 +8,7 @@ struct code_heap {
|
|||
/* Memory allocator */
|
||||
free_list_allocator<code_block> *allocator;
|
||||
|
||||
/* Set of blocks which need full relocation. */
|
||||
/* Set of blocks which need to be initialized by initialize_code_block(). */
|
||||
std::set<code_block *> needs_fixup;
|
||||
|
||||
/* Code blocks which may reference objects in the nursery */
|
||||
|
|
|
@ -116,10 +116,6 @@ struct code_block_compaction_relocation_visitor {
|
|||
|
||||
void operator()(instruction_operand op)
|
||||
{
|
||||
code_block *compiled = op.parent_code_block();
|
||||
array *literals = (to_boolean(compiled->literals) ? untag<array>(compiled->literals) : NULL);
|
||||
cell index = op.parameter_index();
|
||||
|
||||
cell old_offset = op.rel_offset() + (cell)old_address->xt();
|
||||
|
||||
switch(op.rel_type())
|
||||
|
@ -133,16 +129,10 @@ struct code_block_compaction_relocation_visitor {
|
|||
op.store_code_block(code_forwarder.visit_code_block(op.load_code_block(old_offset)));
|
||||
break;
|
||||
case RT_HERE:
|
||||
op.store_value(parent->compute_here_relocation(array_nth(literals,index),op.rel_offset(),compiled));
|
||||
break;
|
||||
case RT_THIS:
|
||||
op.store_value((cell)compiled->xt());
|
||||
break;
|
||||
case RT_CARDS_OFFSET:
|
||||
op.store_value(parent->cards_offset);
|
||||
break;
|
||||
case RT_DECKS_OFFSET:
|
||||
op.store_value(parent->decks_offset);
|
||||
parent->store_external_address(op);
|
||||
break;
|
||||
default:
|
||||
op.store_value(op.load_value(old_offset));
|
||||
|
|
20
vm/debug.cpp
20
vm/debug.cpp
|
@ -310,22 +310,20 @@ struct code_block_printer {
|
|||
const char *status;
|
||||
if(scan->free_p())
|
||||
status = "free";
|
||||
else if(parent->code->marked_p(scan))
|
||||
{
|
||||
reloc_size += parent->object_size(scan->relocation);
|
||||
literal_size += parent->object_size(scan->literals);
|
||||
status = "marked";
|
||||
}
|
||||
else
|
||||
{
|
||||
reloc_size += parent->object_size(scan->relocation);
|
||||
literal_size += parent->object_size(scan->literals);
|
||||
status = "allocated";
|
||||
}
|
||||
|
||||
std::cout << std::hex << (cell)scan << std::dec << " ";
|
||||
std::cout << std::hex << size << std::dec << " ";
|
||||
std::cout << status << std::endl;
|
||||
if(parent->code->marked_p(scan))
|
||||
status = "marked";
|
||||
else
|
||||
status = "allocated";
|
||||
|
||||
std::cout << std::hex << (cell)scan << std::dec << " ";
|
||||
std::cout << std::hex << size << std::dec << " ";
|
||||
std::cout << status << std::endl;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
@ -178,9 +178,6 @@ struct code_block_fixup_relocation_visitor {
|
|||
void operator()(instruction_operand op)
|
||||
{
|
||||
code_block *compiled = op.parent_code_block();
|
||||
array *literals = (to_boolean(compiled->literals) ? untag<array>(compiled->literals) : NULL);
|
||||
cell index = op.parameter_index();
|
||||
|
||||
cell old_offset = op.rel_offset() + (cell)compiled->xt() - code_offset;
|
||||
|
||||
switch(op.rel_type())
|
||||
|
@ -194,7 +191,7 @@ struct code_block_fixup_relocation_visitor {
|
|||
op.store_code_block(code_visitor(op.load_code_block(old_offset)));
|
||||
break;
|
||||
default:
|
||||
parent->store_external_relocation(op);
|
||||
parent->store_external_address(op);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -7,12 +7,11 @@ static const cell image_version = 4;
|
|||
struct image_header {
|
||||
cell magic;
|
||||
cell version;
|
||||
/* all pointers in the image file are relocated from
|
||||
relocation_base to here when the image is loaded */
|
||||
/* base address of data heap when image was saved */
|
||||
cell data_relocation_base;
|
||||
/* size of heap */
|
||||
cell data_size;
|
||||
/* code relocation base */
|
||||
/* base address of code heap when image was saved */
|
||||
cell code_relocation_base;
|
||||
/* size of code heap */
|
||||
cell code_size;
|
||||
|
|
|
@ -133,7 +133,7 @@ code_block *factor_vm::compile_inline_cache(fixnum index,
|
|||
cache_entries.value(),
|
||||
tail_call_p);
|
||||
code_block *code = jit.to_code_block();
|
||||
relocate_code_block(code);
|
||||
initialize_code_block(code);
|
||||
return code;
|
||||
}
|
||||
|
||||
|
|
|
@ -304,7 +304,7 @@ code_block *factor_vm::jit_compile_quot(cell owner_, cell quot_, bool relocating
|
|||
|
||||
code_block *compiled = compiler.to_code_block();
|
||||
|
||||
if(relocating) relocate_code_block(compiled);
|
||||
if(relocating) initialize_code_block(compiled);
|
||||
|
||||
return compiled;
|
||||
}
|
||||
|
|
24
vm/vm.hpp
24
vm/vm.hpp
|
@ -503,21 +503,21 @@ struct factor_vm
|
|||
void primitive_fclose();
|
||||
|
||||
//code_block
|
||||
cell compute_primitive_relocation(cell arg);
|
||||
void undefined_symbol();
|
||||
cell compute_dlsym_relocation(array *literals, cell index);
|
||||
cell compute_xt_relocation(cell obj);
|
||||
cell compute_xt_pic_relocation(word *w, cell tagged_quot);
|
||||
cell compute_xt_pic_relocation(cell w_);
|
||||
cell compute_xt_pic_tail_relocation(cell w_);
|
||||
cell compute_here_relocation(cell arg, cell offset, code_block *compiled);
|
||||
cell compute_context_relocation();
|
||||
cell compute_vm_relocation(cell arg);
|
||||
cell compute_xt_address(cell obj);
|
||||
cell compute_xt_pic_address(word *w, cell tagged_quot);
|
||||
cell compute_xt_pic_address(cell w_);
|
||||
cell compute_xt_pic_tail_address(cell w_);
|
||||
cell code_block_owner(code_block *compiled);
|
||||
void update_word_references(code_block *compiled);
|
||||
void check_code_address(cell address);
|
||||
void store_external_relocation(instruction_operand op);
|
||||
void relocate_code_block(code_block *compiled);
|
||||
cell compute_primitive_address(cell arg);
|
||||
void undefined_symbol();
|
||||
cell compute_dlsym_address(array *literals, cell index);
|
||||
cell compute_here_address(cell arg, cell offset, code_block *compiled);
|
||||
cell compute_context_address();
|
||||
cell compute_vm_address(cell arg);
|
||||
void store_external_address(instruction_operand op);
|
||||
void initialize_code_block(code_block *compiled);
|
||||
void fixup_labels(array *labels, code_block *compiled);
|
||||
code_block *allot_code_block(cell size, code_block_type type);
|
||||
code_block *add_code_block(code_block_type type, cell code_, cell labels_, cell owner_, cell relocation_, cell literals_);
|
||||
|
|
|
@ -27,7 +27,7 @@ word *factor_vm::allot_word(cell name_, cell vocab_, cell hashcode_)
|
|||
{
|
||||
code_block *profiling_block = compile_profiling_stub(new_word.value());
|
||||
new_word->profiling = profiling_block;
|
||||
relocate_code_block(new_word->profiling);
|
||||
initialize_code_block(new_word->profiling);
|
||||
}
|
||||
|
||||
update_word_xt(new_word.untagged());
|
||||
|
|
Loading…
Reference in New Issue