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 namespace factor
{ {
cell factor_vm::compute_primitive_relocation(cell arg) cell factor_vm::compute_xt_address(cell obj)
{
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)
{ {
switch(tagged<object>(obj).type()) 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) if(!to_boolean(tagged_quot) || max_pic_size == 0)
return (cell)w->xt; 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_); 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_); tagged<word> w(w_);
return compute_xt_pic_relocation(w.untagged(),w->pic_tail_def); return compute_xt_pic_address(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);
} }
cell factor_vm::code_block_owner(code_block *compiled) cell factor_vm::code_block_owner(code_block *compiled)
@ -157,19 +82,19 @@ struct update_word_references_relocation_visitor {
case RT_XT: case RT_XT:
{ {
code_block *compiled = op.load_code_block(); 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; break;
} }
case RT_XT_PIC: case RT_XT_PIC:
{ {
code_block *compiled = op.load_code_block(); 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; break;
} }
case RT_XT_PIC_TAIL: case RT_XT_PIC_TAIL:
{ {
code_block *compiled = op.load_code_block(); 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; break;
} }
default: default:
@ -185,7 +110,7 @@ or dlsyms. */
void factor_vm::update_word_references(code_block *compiled) void factor_vm::update_word_references(code_block *compiled)
{ {
if(code->needs_fixup_p(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 /* update_word_references() is always applied to every block in
the code heap. Since it resets all call sites to point to the code heap. Since it resets all call sites to point to
their canonical XT (cold entry point for non-tail calls, their canonical XT (cold entry point for non-tail calls,
@ -210,7 +135,82 @@ void factor_vm::check_code_address(cell address)
#endif #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(); code_block *compiled = op.parent_code_block();
array *literals = (to_boolean(compiled->literals) ? untag<array>(compiled->literals) : NULL); 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()) switch(op.rel_type())
{ {
case RT_PRIMITIVE: 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; break;
case RT_DLSYM: case RT_DLSYM:
op.store_value(parent->compute_dlsym_relocation(literals,index)); op.store_value(compute_dlsym_address(literals,index));
break; break;
case RT_HERE: 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; break;
case RT_THIS: case RT_THIS:
op.store_value((cell)compiled->xt()); op.store_value((cell)compiled->xt());
break; break;
case RT_CONTEXT: case RT_CONTEXT:
op.store_value(parent->compute_context_relocation()); op.store_value(compute_context_address());
break; break;
case RT_UNTAGGED: case RT_UNTAGGED:
op.store_value(untag_fixnum(array_nth(literals,index))); op.store_value(untag_fixnum(array_nth(literals,index)));
break; break;
case RT_MEGAMORPHIC_CACHE_HITS: 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; break;
case RT_VM: 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; break;
case RT_CARDS_OFFSET: case RT_CARDS_OFFSET:
op.store_value(parent->cards_offset); op.store_value(cards_offset);
break; break;
case RT_DECKS_OFFSET: case RT_DECKS_OFFSET:
op.store_value(parent->decks_offset); op.store_value(decks_offset);
break; break;
default: default:
critical_error("Bad rel type",op.rel_type()); 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; 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) void operator()(instruction_operand op)
{ {
@ -271,26 +271,26 @@ struct relocate_code_block_relocation_visitor {
op.store_value(array_nth(literals,index)); op.store_value(array_nth(literals,index));
break; break;
case RT_XT: 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; break;
case RT_XT_PIC: 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; break;
case RT_XT_PIC_TAIL: 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; break;
default: default:
parent->store_external_relocation(op); parent->store_external_address(op);
break; break;
} }
} }
}; };
/* Perform all fixups on a code block */ /* 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); code->needs_fixup.erase(compiled);
relocate_code_block_relocation_visitor visitor(this); initial_code_block_visitor visitor(this);
compiled->each_instruction_operand(visitor); compiled->each_instruction_operand(visitor);
compiled->flush_icache(); compiled->flush_icache();
} }

View File

@ -8,7 +8,7 @@ struct code_heap {
/* Memory allocator */ /* Memory allocator */
free_list_allocator<code_block> *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; std::set<code_block *> needs_fixup;
/* Code blocks which may reference objects in the nursery */ /* 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) 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(); cell old_offset = op.rel_offset() + (cell)old_address->xt();
switch(op.rel_type()) 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))); op.store_code_block(code_forwarder.visit_code_block(op.load_code_block(old_offset)));
break; break;
case RT_HERE: case RT_HERE:
op.store_value(parent->compute_here_relocation(array_nth(literals,index),op.rel_offset(),compiled));
break;
case RT_THIS: case RT_THIS:
op.store_value((cell)compiled->xt());
break;
case RT_CARDS_OFFSET: case RT_CARDS_OFFSET:
op.store_value(parent->cards_offset);
break;
case RT_DECKS_OFFSET: case RT_DECKS_OFFSET:
op.store_value(parent->decks_offset); parent->store_external_address(op);
break; break;
default: default:
op.store_value(op.load_value(old_offset)); op.store_value(op.load_value(old_offset));

View File

@ -310,22 +310,20 @@ struct code_block_printer {
const char *status; const char *status;
if(scan->free_p()) if(scan->free_p())
status = "free"; 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 else
{ {
reloc_size += parent->object_size(scan->relocation); reloc_size += parent->object_size(scan->relocation);
literal_size += parent->object_size(scan->literals); literal_size += parent->object_size(scan->literals);
status = "allocated";
}
std::cout << std::hex << (cell)scan << std::dec << " "; if(parent->code->marked_p(scan))
std::cout << std::hex << size << std::dec << " "; status = "marked";
std::cout << status << std::endl; 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) void operator()(instruction_operand op)
{ {
code_block *compiled = op.parent_code_block(); 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; cell old_offset = op.rel_offset() + (cell)compiled->xt() - code_offset;
switch(op.rel_type()) 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))); op.store_code_block(code_visitor(op.load_code_block(old_offset)));
break; break;
default: default:
parent->store_external_relocation(op); parent->store_external_address(op);
break; break;
} }
} }

View File

@ -7,12 +7,11 @@ static const cell image_version = 4;
struct image_header { struct image_header {
cell magic; cell magic;
cell version; cell version;
/* all pointers in the image file are relocated from /* base address of data heap when image was saved */
relocation_base to here when the image is loaded */
cell data_relocation_base; cell data_relocation_base;
/* size of heap */ /* size of heap */
cell data_size; cell data_size;
/* code relocation base */ /* base address of code heap when image was saved */
cell code_relocation_base; cell code_relocation_base;
/* size of code heap */ /* size of code heap */
cell code_size; cell code_size;

View File

@ -133,7 +133,7 @@ code_block *factor_vm::compile_inline_cache(fixnum index,
cache_entries.value(), cache_entries.value(),
tail_call_p); tail_call_p);
code_block *code = jit.to_code_block(); code_block *code = jit.to_code_block();
relocate_code_block(code); initialize_code_block(code);
return 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(); code_block *compiled = compiler.to_code_block();
if(relocating) relocate_code_block(compiled); if(relocating) initialize_code_block(compiled);
return compiled; return compiled;
} }

View File

@ -503,21 +503,21 @@ struct factor_vm
void primitive_fclose(); void primitive_fclose();
//code_block //code_block
cell compute_primitive_relocation(cell arg); cell compute_xt_address(cell obj);
void undefined_symbol(); cell compute_xt_pic_address(word *w, cell tagged_quot);
cell compute_dlsym_relocation(array *literals, cell index); cell compute_xt_pic_address(cell w_);
cell compute_xt_relocation(cell obj); cell compute_xt_pic_tail_address(cell w_);
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 code_block_owner(code_block *compiled); cell code_block_owner(code_block *compiled);
void update_word_references(code_block *compiled); void update_word_references(code_block *compiled);
void check_code_address(cell address); void check_code_address(cell address);
void store_external_relocation(instruction_operand op); cell compute_primitive_address(cell arg);
void relocate_code_block(code_block *compiled); 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); void fixup_labels(array *labels, code_block *compiled);
code_block *allot_code_block(cell size, code_block_type type); 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_); 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()); code_block *profiling_block = compile_profiling_stub(new_word.value());
new_word->profiling = profiling_block; new_word->profiling = profiling_block;
relocate_code_block(new_word->profiling); initialize_code_block(new_word->profiling);
} }
update_word_xt(new_word.untagged()); update_word_xt(new_word.untagged());