Merge branch 'no_literal_table' of git://factorcode.org/git/factor into no_literal_table
commit
333c7654ae
|
@ -40,7 +40,7 @@ SYMBOL: labels
|
|||
V{ } clone calls set ;
|
||||
|
||||
: generate-insns ( asm -- code )
|
||||
dup word>> [
|
||||
dup label>> [
|
||||
init-generator
|
||||
instructions>> [
|
||||
[ class insn-counts get inc-at ]
|
||||
|
|
|
@ -4,7 +4,7 @@ USING: arrays byte-arrays byte-vectors generic assocs hashtables
|
|||
io.binary kernel kernel.private math namespaces make sequences
|
||||
words quotations strings alien.accessors alien.strings layouts
|
||||
system combinators math.bitwise math.order
|
||||
accessors growable fry generalizations compiler.constants ;
|
||||
accessors growable fry compiler.constants ;
|
||||
IN: compiler.codegen.fixup
|
||||
|
||||
! Owner
|
||||
|
@ -114,8 +114,7 @@ SYMBOL: relocation-table
|
|||
init-fixup
|
||||
@
|
||||
label-table [ resolve-labels ] change
|
||||
compiling-word get
|
||||
literal-table get >array
|
||||
relocation-table get >byte-array
|
||||
label-table get
|
||||
] B{ } make 5 narray ; inline
|
||||
] B{ } make 4array ; inline
|
||||
|
|
|
@ -54,6 +54,8 @@ void code_block_visitor<Visitor>::visit_object_code_block(object *obj)
|
|||
quotation *q = (quotation *)obj;
|
||||
if(q->code)
|
||||
parent->set_quot_xt(q,visitor(q->code));
|
||||
else
|
||||
q->xt = (void *)lazy_jit_compile;
|
||||
break;
|
||||
}
|
||||
case CALLSTACK_TYPE:
|
||||
|
|
|
@ -3,42 +3,119 @@
|
|||
namespace factor
|
||||
{
|
||||
|
||||
void *factor_vm::object_xt(cell obj)
|
||||
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)
|
||||
{
|
||||
switch(tagged<object>(obj).type())
|
||||
{
|
||||
case WORD_TYPE:
|
||||
return untag<word>(obj)->xt;
|
||||
return (cell)untag<word>(obj)->xt;
|
||||
case QUOTATION_TYPE:
|
||||
return untag<quotation>(obj)->xt;
|
||||
return (cell)untag<quotation>(obj)->xt;
|
||||
default:
|
||||
critical_error("Expected word or quotation",obj);
|
||||
return NULL;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
void *factor_vm::xt_pic(word *w, cell tagged_quot)
|
||||
cell factor_vm::compute_xt_pic_relocation(word *w, cell tagged_quot)
|
||||
{
|
||||
if(!to_boolean(tagged_quot) || max_pic_size == 0)
|
||||
return w->xt;
|
||||
return (cell)w->xt;
|
||||
else
|
||||
{
|
||||
quotation *quot = untag<quotation>(tagged_quot);
|
||||
if(quot->code)
|
||||
return quot->xt;
|
||||
return (cell)quot->xt;
|
||||
else
|
||||
return w->xt;
|
||||
return (cell)w->xt;
|
||||
}
|
||||
}
|
||||
|
||||
void *factor_vm::word_xt_pic(word *w)
|
||||
cell factor_vm::compute_xt_pic_relocation(cell w_)
|
||||
{
|
||||
return xt_pic(w,w->pic_def);
|
||||
tagged<word> w(w_);
|
||||
return compute_xt_pic_relocation(w.untagged(),w->pic_def);
|
||||
}
|
||||
|
||||
void *factor_vm::word_xt_pic_tail(word *w)
|
||||
cell factor_vm::compute_xt_pic_tail_relocation(cell w_)
|
||||
{
|
||||
return xt_pic(w,w->pic_tail_def);
|
||||
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);
|
||||
}
|
||||
|
||||
cell factor_vm::code_block_owner(code_block *compiled)
|
||||
|
@ -83,19 +160,19 @@ struct word_references_updater {
|
|||
case RT_XT:
|
||||
{
|
||||
code_block *compiled = op.load_code_block();
|
||||
op.store_value((cell)parent->object_xt(compiled->owner));
|
||||
op.store_value(parent->compute_xt_relocation(compiled->owner));
|
||||
break;
|
||||
}
|
||||
case RT_XT_PIC:
|
||||
{
|
||||
code_block *compiled = op.load_code_block();
|
||||
op.store_value((cell)parent->word_xt_pic(untag<word>(parent->code_block_owner(compiled))));
|
||||
op.store_value(parent->compute_xt_pic_relocation(parent->code_block_owner(compiled)));
|
||||
break;
|
||||
}
|
||||
case RT_XT_PIC_TAIL:
|
||||
{
|
||||
code_block *compiled = op.load_code_block();
|
||||
op.store_value((cell)parent->word_xt_pic_tail(untag<word>(parent->code_block_owner(compiled))));
|
||||
op.store_value(parent->compute_xt_pic_tail_relocation(parent->code_block_owner(compiled)));
|
||||
break;
|
||||
}
|
||||
default:
|
||||
|
@ -129,97 +206,39 @@ void factor_vm::update_word_references(code_block *compiled)
|
|||
}
|
||||
}
|
||||
|
||||
/* 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 */
|
||||
void *factor_vm::get_rel_symbol(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 (void *)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 sym;
|
||||
else
|
||||
return (void *)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 sym;
|
||||
}
|
||||
return (void *)factor::undefined_symbol;
|
||||
}
|
||||
default:
|
||||
critical_error("Bad symbol specifier",symbol);
|
||||
return (void *)factor::undefined_symbol;
|
||||
}
|
||||
}
|
||||
|
||||
cell factor_vm::compute_relocation(relocation_entry rel, cell index, code_block *compiled)
|
||||
{
|
||||
array *literals = (to_boolean(compiled->literals)
|
||||
? untag<array>(compiled->literals) : NULL);
|
||||
cell offset = rel.rel_offset() + (cell)compiled->xt();
|
||||
|
||||
#define ARG array_nth(literals,index)
|
||||
|
||||
switch(rel.rel_type())
|
||||
{
|
||||
case RT_PRIMITIVE:
|
||||
return (cell)primitives[untag_fixnum(ARG)];
|
||||
return compute_primitive_relocation(ARG);
|
||||
case RT_DLSYM:
|
||||
return (cell)get_rel_symbol(literals,index);
|
||||
return compute_dlsym_relocation(literals,index);
|
||||
case RT_IMMEDIATE:
|
||||
return ARG;
|
||||
case RT_XT:
|
||||
return (cell)object_xt(ARG);
|
||||
return compute_xt_relocation(ARG);
|
||||
case RT_XT_PIC:
|
||||
return (cell)word_xt_pic(untag<word>(ARG));
|
||||
return compute_xt_pic_relocation(ARG);
|
||||
case RT_XT_PIC_TAIL:
|
||||
return (cell)word_xt_pic_tail(untag<word>(ARG));
|
||||
return compute_xt_pic_tail_relocation(ARG);
|
||||
case RT_HERE:
|
||||
{
|
||||
fixnum arg = untag_fixnum(ARG);
|
||||
return (arg >= 0 ? offset + arg : (cell)compiled->xt() - arg);
|
||||
}
|
||||
return compute_here_relocation(ARG,rel.rel_offset(),compiled);
|
||||
case RT_THIS:
|
||||
return (cell)compiled->xt();
|
||||
case RT_CONTEXT:
|
||||
return (cell)&ctx;
|
||||
return compute_context_relocation();
|
||||
case RT_UNTAGGED:
|
||||
return untag_fixnum(ARG);
|
||||
case RT_MEGAMORPHIC_CACHE_HITS:
|
||||
return (cell)&dispatch_stats.megamorphic_cache_hits;
|
||||
case RT_VM:
|
||||
return (cell)this + untag_fixnum(ARG);
|
||||
return compute_vm_relocation(ARG);
|
||||
case RT_CARDS_OFFSET:
|
||||
return cards_offset;
|
||||
case RT_DECKS_OFFSET:
|
||||
|
|
|
@ -113,17 +113,16 @@ void factor_vm::primitive_modify_code_heap()
|
|||
case ARRAY_TYPE:
|
||||
{
|
||||
array *compiled_data = data.as<array>().untagged();
|
||||
cell owner = array_nth(compiled_data,0);
|
||||
cell literals = array_nth(compiled_data,1);
|
||||
cell relocation = array_nth(compiled_data,2);
|
||||
cell labels = array_nth(compiled_data,3);
|
||||
cell code = array_nth(compiled_data,4);
|
||||
cell literals = array_nth(compiled_data,0);
|
||||
cell relocation = array_nth(compiled_data,1);
|
||||
cell labels = array_nth(compiled_data,2);
|
||||
cell code = array_nth(compiled_data,3);
|
||||
|
||||
code_block *compiled = add_code_block(
|
||||
code_block_optimized,
|
||||
code,
|
||||
labels,
|
||||
owner,
|
||||
word.value(),
|
||||
relocation,
|
||||
literals);
|
||||
|
||||
|
|
296
vm/image.cpp
296
vm/image.cpp
|
@ -55,177 +55,206 @@ void factor_vm::load_code_heap(FILE *file, image_header *h, vm_parameters *p)
|
|||
code->allocator->initial_free_list(h->code_size);
|
||||
}
|
||||
|
||||
void factor_vm::data_fixup(cell *handle, cell data_relocation_base)
|
||||
{
|
||||
if(immediate_p(*handle))
|
||||
return;
|
||||
struct data_fixupper {
|
||||
cell offset;
|
||||
|
||||
*handle += (data->tenured->start - data_relocation_base);
|
||||
}
|
||||
explicit data_fixupper(cell offset_) : offset(offset_) {}
|
||||
|
||||
template<typename Type> void factor_vm::code_fixup(Type **handle, cell code_relocation_base)
|
||||
{
|
||||
Type *ptr = *handle;
|
||||
Type *new_ptr = (Type *)(((cell)ptr) + (code->seg->start - code_relocation_base));
|
||||
*handle = new_ptr;
|
||||
}
|
||||
|
||||
void factor_vm::fixup_word(word *word, cell code_relocation_base)
|
||||
{
|
||||
if(word->code)
|
||||
code_fixup(&word->code,code_relocation_base);
|
||||
if(word->profiling)
|
||||
code_fixup(&word->profiling,code_relocation_base);
|
||||
code_fixup(&word->xt,code_relocation_base);
|
||||
}
|
||||
|
||||
void factor_vm::fixup_quotation(quotation *quot, cell code_relocation_base)
|
||||
{
|
||||
if(quot->code)
|
||||
object *operator()(object *obj)
|
||||
{
|
||||
code_fixup("->xt,code_relocation_base);
|
||||
code_fixup("->code,code_relocation_base);
|
||||
}
|
||||
else
|
||||
quot->xt = (void *)lazy_jit_compile;
|
||||
}
|
||||
|
||||
void factor_vm::fixup_alien(alien *ptr)
|
||||
{
|
||||
if(!to_boolean(ptr->base))
|
||||
ptr->expired = true_object;
|
||||
else
|
||||
ptr->update_address();
|
||||
}
|
||||
|
||||
struct stack_frame_fixupper {
|
||||
factor_vm *parent;
|
||||
cell code_relocation_base;
|
||||
|
||||
explicit stack_frame_fixupper(factor_vm *parent_, cell code_relocation_base_) :
|
||||
parent(parent_), code_relocation_base(code_relocation_base_) {}
|
||||
void operator()(stack_frame *frame)
|
||||
{
|
||||
parent->code_fixup(&frame->xt,code_relocation_base);
|
||||
parent->code_fixup(&FRAME_RETURN_ADDRESS(frame,parent),code_relocation_base);
|
||||
return (object *)((char *)obj + offset);
|
||||
}
|
||||
};
|
||||
|
||||
void factor_vm::fixup_callstack_object(callstack *stack, cell code_relocation_base)
|
||||
struct code_fixupper {
|
||||
cell offset;
|
||||
|
||||
explicit code_fixupper(cell offset_) : offset(offset_) {}
|
||||
|
||||
code_block *operator()(code_block *compiled)
|
||||
{
|
||||
return (code_block *)((char *)compiled + offset);
|
||||
}
|
||||
};
|
||||
|
||||
static inline cell tuple_size_with_fixup(cell offset, object *obj)
|
||||
{
|
||||
stack_frame_fixupper fixupper(this,code_relocation_base);
|
||||
iterate_callstack_object(stack,fixupper);
|
||||
tuple_layout *layout = (tuple_layout *)((char *)UNTAG(((tuple *)obj)->layout) + offset);
|
||||
return tuple_size(layout);
|
||||
}
|
||||
|
||||
struct fixup_sizer {
|
||||
cell offset;
|
||||
|
||||
explicit fixup_sizer(cell offset_) : offset(offset_) {}
|
||||
|
||||
cell operator()(object *obj)
|
||||
{
|
||||
if(obj->type() == TUPLE_TYPE)
|
||||
return align(tuple_size_with_fixup(offset,obj),data_alignment);
|
||||
else
|
||||
return obj->size();
|
||||
}
|
||||
};
|
||||
|
||||
struct object_fixupper {
|
||||
factor_vm *parent;
|
||||
cell data_relocation_base;
|
||||
cell data_offset;
|
||||
slot_visitor<data_fixupper> data_visitor;
|
||||
code_block_visitor<code_fixupper> code_visitor;
|
||||
|
||||
explicit object_fixupper(factor_vm *parent_, cell data_relocation_base_) :
|
||||
parent(parent_), data_relocation_base(data_relocation_base_) { }
|
||||
object_fixupper(factor_vm *parent_, cell data_offset_, cell code_offset_) :
|
||||
parent(parent_),
|
||||
data_offset(data_offset_),
|
||||
data_visitor(slot_visitor<data_fixupper>(parent_,data_fixupper(data_offset_))),
|
||||
code_visitor(code_block_visitor<code_fixupper>(parent_,code_fixupper(code_offset_))) {}
|
||||
|
||||
void operator()(cell *scan)
|
||||
void operator()(object *obj, cell size)
|
||||
{
|
||||
parent->data_fixup(scan,data_relocation_base);
|
||||
parent->data->tenured->starts.record_object_start_offset(obj);
|
||||
|
||||
switch(obj->type())
|
||||
{
|
||||
case ALIEN_TYPE:
|
||||
{
|
||||
cell payload_start = obj->binary_payload_start();
|
||||
data_visitor.visit_slots(obj,payload_start);
|
||||
|
||||
alien *ptr = (alien *)obj;
|
||||
|
||||
if(!parent->to_boolean(ptr->base))
|
||||
ptr->expired = parent->true_object;
|
||||
else
|
||||
ptr->update_address();
|
||||
break;
|
||||
}
|
||||
case DLL_TYPE:
|
||||
{
|
||||
cell payload_start = obj->binary_payload_start();
|
||||
data_visitor.visit_slots(obj,payload_start);
|
||||
|
||||
parent->ffi_dlopen((dll *)obj);
|
||||
break;
|
||||
}
|
||||
case TUPLE_TYPE:
|
||||
{
|
||||
cell payload_start = tuple_size_with_fixup(data_offset,obj);
|
||||
data_visitor.visit_slots(obj,payload_start);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
cell payload_start = obj->binary_payload_start();
|
||||
data_visitor.visit_slots(obj,payload_start);
|
||||
code_visitor.visit_object_code_block(obj);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
/* Initialize an object in a newly-loaded image */
|
||||
void factor_vm::relocate_object(object *object,
|
||||
cell data_relocation_base,
|
||||
cell code_relocation_base)
|
||||
void factor_vm::fixup_data(cell data_offset, cell code_offset)
|
||||
{
|
||||
cell type = object->type();
|
||||
slot_visitor<data_fixupper> data_workhorse(this,data_fixupper(data_offset));
|
||||
data_workhorse.visit_roots();
|
||||
|
||||
object_fixupper fixupper(this,data_offset,code_offset);
|
||||
fixup_sizer sizer(data_offset);
|
||||
data->tenured->iterate(fixupper,sizer);
|
||||
}
|
||||
|
||||
struct code_block_updater {
|
||||
factor_vm *parent;
|
||||
cell code_offset;
|
||||
slot_visitor<data_fixupper> data_visitor;
|
||||
code_fixupper code_visitor;
|
||||
|
||||
code_block_updater(factor_vm *parent_, cell data_offset_, cell code_offset_) :
|
||||
parent(parent_),
|
||||
code_offset(code_offset_),
|
||||
data_visitor(slot_visitor<data_fixupper>(parent_,data_fixupper(data_offset_))),
|
||||
code_visitor(code_fixupper(code_offset_)) {}
|
||||
|
||||
void operator()(relocation_entry rel, cell index, code_block *compiled)
|
||||
{
|
||||
relocation_type type = rel.rel_type();
|
||||
instruction_operand op(rel.rel_class(),rel.rel_offset() + (cell)compiled->xt());
|
||||
|
||||
/* Tuple relocation is a bit trickier; we have to fix up the
|
||||
layout object before we can get the tuple size, so each_slot is
|
||||
out of the question */
|
||||
if(type == TUPLE_TYPE)
|
||||
{
|
||||
tuple *t = (tuple *)object;
|
||||
data_fixup(&t->layout,data_relocation_base);
|
||||
array *literals = (parent->to_boolean(compiled->literals)
|
||||
? untag<array>(compiled->literals) : NULL);
|
||||
|
||||
cell *scan = t->data();
|
||||
cell *end = (cell *)((cell)object + object->size());
|
||||
|
||||
for(; scan < end; scan++)
|
||||
data_fixup(scan,data_relocation_base);
|
||||
}
|
||||
else
|
||||
{
|
||||
object_fixupper fixupper(this,data_relocation_base);
|
||||
object->each_slot(fixupper);
|
||||
cell old_offset = (cell)compiled - code_offset;
|
||||
|
||||
switch(type)
|
||||
{
|
||||
case WORD_TYPE:
|
||||
fixup_word((word *)object,code_relocation_base);
|
||||
case RT_IMMEDIATE:
|
||||
op.store_value(data_visitor.visit_pointer(op.load_value(old_offset)));
|
||||
break;
|
||||
case QUOTATION_TYPE:
|
||||
fixup_quotation((quotation *)object,code_relocation_base);
|
||||
case RT_XT:
|
||||
case RT_XT_PIC:
|
||||
case RT_XT_PIC_TAIL:
|
||||
op.store_code_block(code_visitor(op.load_code_block(old_offset)));
|
||||
break;
|
||||
case DLL_TYPE:
|
||||
ffi_dlopen((dll *)object);
|
||||
case RT_PRIMITIVE:
|
||||
op.store_value(parent->compute_primitive_relocation(array_nth(literals,index)));
|
||||
break;
|
||||
case ALIEN_TYPE:
|
||||
fixup_alien((alien *)object);
|
||||
case RT_DLSYM:
|
||||
op.store_value(parent->compute_dlsym_relocation(literals,index));
|
||||
break;
|
||||
case CALLSTACK_TYPE:
|
||||
fixup_callstack_object((callstack *)object,code_relocation_base);
|
||||
case RT_HERE:
|
||||
op.store_value(parent->compute_here_relocation(array_nth(literals,index),rel.rel_offset(),compiled));
|
||||
break;
|
||||
case RT_THIS:
|
||||
op.store_value((cell)compiled->xt());
|
||||
break;
|
||||
case RT_CONTEXT:
|
||||
op.store_value(parent->compute_context_relocation());
|
||||
break;
|
||||
case RT_UNTAGGED:
|
||||
op.store_value(untag_fixnum(array_nth(literals,index)));
|
||||
case RT_MEGAMORPHIC_CACHE_HITS:
|
||||
op.store_value((cell)&parent->dispatch_stats.megamorphic_cache_hits);
|
||||
break;
|
||||
case RT_VM:
|
||||
op.store_value(parent->compute_vm_relocation(array_nth(literals,index)));
|
||||
break;
|
||||
case RT_CARDS_OFFSET:
|
||||
op.store_value(parent->cards_offset);
|
||||
break;
|
||||
case RT_DECKS_OFFSET:
|
||||
op.store_value(parent->decks_offset);
|
||||
break;
|
||||
default:
|
||||
critical_error("Bad rel type",rel.rel_type());
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Since the image might have been saved with a different base address than
|
||||
where it is loaded, we need to fix up pointers in the image. */
|
||||
void factor_vm::relocate_data(cell data_relocation_base, cell code_relocation_base)
|
||||
{
|
||||
for(cell i = 0; i < special_object_count; i++)
|
||||
data_fixup(&special_objects[i],data_relocation_base);
|
||||
|
||||
data_fixup(&true_object,data_relocation_base);
|
||||
data_fixup(&bignum_zero,data_relocation_base);
|
||||
data_fixup(&bignum_pos_one,data_relocation_base);
|
||||
data_fixup(&bignum_neg_one,data_relocation_base);
|
||||
|
||||
cell obj = data->tenured->start;
|
||||
|
||||
while(obj)
|
||||
{
|
||||
relocate_object((object *)obj,data_relocation_base,code_relocation_base);
|
||||
data->tenured->starts.record_object_start_offset((object *)obj);
|
||||
obj = data->tenured->next_object_after(obj);
|
||||
}
|
||||
}
|
||||
|
||||
void factor_vm::fixup_code_block(code_block *compiled, cell data_relocation_base)
|
||||
{
|
||||
/* relocate literal table data */
|
||||
data_fixup(&compiled->owner,data_relocation_base);
|
||||
data_fixup(&compiled->literals,data_relocation_base);
|
||||
data_fixup(&compiled->relocation,data_relocation_base);
|
||||
|
||||
relocate_code_block(compiled);
|
||||
}
|
||||
};
|
||||
|
||||
struct code_block_fixupper {
|
||||
factor_vm *parent;
|
||||
cell data_relocation_base;
|
||||
cell data_offset;
|
||||
cell code_offset;
|
||||
|
||||
explicit code_block_fixupper(factor_vm *parent_, cell data_relocation_base_) :
|
||||
parent(parent_), data_relocation_base(data_relocation_base_) { }
|
||||
code_block_fixupper(factor_vm *parent_, cell data_offset_, cell code_offset_) :
|
||||
parent(parent_),
|
||||
data_offset(data_offset_),
|
||||
code_offset(code_offset_) {}
|
||||
|
||||
void operator()(code_block *compiled, cell size)
|
||||
{
|
||||
parent->fixup_code_block(compiled,data_relocation_base);
|
||||
slot_visitor<data_fixupper> data_visitor(parent,data_fixupper(data_offset));
|
||||
data_visitor.visit_code_block_objects(compiled);
|
||||
|
||||
code_block_updater updater(parent,data_offset,code_offset);
|
||||
parent->iterate_relocations(compiled,updater);
|
||||
}
|
||||
};
|
||||
|
||||
void factor_vm::relocate_code(cell data_relocation_base)
|
||||
void factor_vm::fixup_code(cell data_offset, cell code_offset)
|
||||
{
|
||||
code_block_fixupper fixupper(this,data_relocation_base);
|
||||
iterate_code_heap(fixupper);
|
||||
code_block_fixupper fixupper(this,data_offset,code_offset);
|
||||
code->allocator->iterate(fixupper);
|
||||
}
|
||||
|
||||
/* Read an image file from disk, only done once during startup */
|
||||
|
@ -257,8 +286,11 @@ void factor_vm::load_image(vm_parameters *p)
|
|||
|
||||
init_objects(&h);
|
||||
|
||||
relocate_data(h.data_relocation_base,h.code_relocation_base);
|
||||
relocate_code(h.data_relocation_base);
|
||||
cell data_offset = data->tenured->start - h.data_relocation_base;
|
||||
cell code_offset = code->seg->start - h.code_relocation_base;
|
||||
|
||||
fixup_data(data_offset,code_offset);
|
||||
fixup_code(data_offset,code_offset);
|
||||
|
||||
/* Store image path name */
|
||||
special_objects[OBJ_IMAGE] = allot_alien(false_object,(cell)p->image_path);
|
||||
|
|
|
@ -55,9 +55,14 @@ fixnum instruction_operand::load_value()
|
|||
return load_value(pointer);
|
||||
}
|
||||
|
||||
code_block *instruction_operand::load_code_block(cell relative_to)
|
||||
{
|
||||
return ((code_block *)load_value(relative_to) - 1);
|
||||
}
|
||||
|
||||
code_block *instruction_operand::load_code_block()
|
||||
{
|
||||
return ((code_block *)load_value() - 1);
|
||||
return load_code_block(pointer);
|
||||
}
|
||||
|
||||
/* Store a 32-bit value into a PowerPC LIS/ORI sequence */
|
||||
|
|
|
@ -130,6 +130,7 @@ struct instruction_operand {
|
|||
fixnum load_value_masked(cell mask, fixnum shift);
|
||||
fixnum load_value(cell relative_to);
|
||||
fixnum load_value();
|
||||
code_block *load_code_block(cell relative_to);
|
||||
code_block *load_code_block();
|
||||
|
||||
void store_value_2_2(fixnum value);
|
||||
|
|
|
@ -135,9 +135,7 @@ struct literal_references_visitor {
|
|||
if(rel.rel_type() == RT_IMMEDIATE)
|
||||
{
|
||||
instruction_operand op(rel.rel_class(),rel.rel_offset() + (cell)compiled->xt());
|
||||
cell literal = op.load_value();
|
||||
literal = visitor->visit_pointer(literal);
|
||||
op.store_value(literal);
|
||||
op.store_value(visitor->visit_pointer(op.load_value()));
|
||||
}
|
||||
}
|
||||
};
|
||||
|
|
30
vm/vm.hpp
30
vm/vm.hpp
|
@ -500,14 +500,17 @@ struct factor_vm
|
|||
void primitive_fclose();
|
||||
|
||||
//code_block
|
||||
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);
|
||||
cell code_block_owner(code_block *compiled);
|
||||
cell compute_primitive_relocation(cell arg);
|
||||
void undefined_symbol();
|
||||
void *get_rel_symbol(array *literals, cell index);
|
||||
cell compute_relocation(relocation_entry rel, cell index, code_block *compiled);
|
||||
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 code_block_owner(code_block *compiled);
|
||||
|
||||
template<typename Iterator> void iterate_relocations(code_block *compiled, Iterator &iter)
|
||||
{
|
||||
|
@ -528,6 +531,7 @@ struct factor_vm
|
|||
}
|
||||
|
||||
void update_word_references(code_block *compiled);
|
||||
cell compute_relocation(relocation_entry rel, cell index, code_block *compiled);
|
||||
void check_code_address(cell address);
|
||||
void relocate_code_block(code_block *compiled);
|
||||
void fixup_labels(array *labels, code_block *compiled);
|
||||
|
@ -567,16 +571,8 @@ struct factor_vm
|
|||
bool save_image(const vm_char *filename);
|
||||
void primitive_save_image();
|
||||
void primitive_save_image_and_exit();
|
||||
void data_fixup(cell *handle, cell data_relocation_base);
|
||||
template<typename Type> void code_fixup(Type **handle, cell code_relocation_base);
|
||||
void fixup_word(word *word, cell code_relocation_base);
|
||||
void fixup_quotation(quotation *quot, cell code_relocation_base);
|
||||
void fixup_alien(alien *d);
|
||||
void fixup_callstack_object(callstack *stack, cell code_relocation_base);
|
||||
void relocate_object(object *object, cell data_relocation_base, cell code_relocation_base);
|
||||
void relocate_data(cell data_relocation_base, cell code_relocation_base);
|
||||
void fixup_code_block(code_block *compiled, cell data_relocation_base);
|
||||
void relocate_code(cell data_relocation_base);
|
||||
void fixup_data(cell data_offset, cell code_offset);
|
||||
void fixup_code(cell data_offset, cell code_offset);
|
||||
void load_image(vm_parameters *p);
|
||||
|
||||
//callstack
|
||||
|
|
Loading…
Reference in New Issue