vm: Clean up more code duplication and rename a few methods

db4
Slava Pestov 2009-12-02 01:09:08 -06:00
parent d664507b36
commit d49c86ba11
10 changed files with 131 additions and 147 deletions

View File

@ -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();
}

View File

@ -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 */

View File

@ -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));

View File

@ -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;
}
}
};

View File

@ -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;
}
}

View File

@ -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;

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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_);

View File

@ -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());