}
data->tenured->here = data->tenured->start + h->data_size;
- data_relocation_base = h->data_relocation_base;
}
void factor_vm::load_code_heap(FILE *file, image_header *h, vm_parameters *p)
}
}
- code_relocation_base = h->code_relocation_base;
code->build_free_list(h->code_size);
}
exit(1);
}
-void factor_vm::data_fixup(cell *cell)
+void factor_vm::data_fixup(cell *cell, cell data_relocation_base)
{
if(immediate_p(*cell))
return;
*cell += (data->tenured->start - data_relocation_base);
}
-template<typename Type> void factor_vm::code_fixup(Type **handle)
+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)
+void factor_vm::fixup_word(word *word, cell code_relocation_base)
{
if(word->code)
- code_fixup(&word->code);
+ code_fixup(&word->code,code_relocation_base);
if(word->profiling)
- code_fixup(&word->profiling);
- code_fixup(&word->xt);
+ code_fixup(&word->profiling,code_relocation_base);
+ code_fixup(&word->xt,code_relocation_base);
}
-void factor_vm::fixup_quotation(quotation *quot)
+void factor_vm::fixup_quotation(quotation *quot, cell code_relocation_base)
{
if(quot->code)
{
- code_fixup("->xt);
- code_fixup("->code);
+ 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 *d)
{
- d->expired = T;
+ if(d->base == F) d->expired = T;
}
struct stack_frame_fixupper {
factor_vm *myvm;
+ cell code_relocation_base;
- explicit stack_frame_fixupper(factor_vm *myvm_) : myvm(myvm_) {}
+ explicit stack_frame_fixupper(factor_vm *myvm_, cell code_relocation_base_) :
+ myvm(myvm_), code_relocation_base(code_relocation_base_) {}
void operator()(stack_frame *frame)
{
- myvm->code_fixup(&frame->xt);
- myvm->code_fixup(&FRAME_RETURN_ADDRESS(frame,myvm));
+ myvm->code_fixup(&frame->xt,code_relocation_base);
+ myvm->code_fixup(&FRAME_RETURN_ADDRESS(frame,myvm),code_relocation_base);
}
};
-void factor_vm::fixup_callstack_object(callstack *stack)
+void factor_vm::fixup_callstack_object(callstack *stack, cell code_relocation_base)
{
- stack_frame_fixupper fixupper(this);
+ stack_frame_fixupper fixupper(this,code_relocation_base);
iterate_callstack_object(stack,fixupper);
}
struct object_fixupper {
factor_vm *myvm;
+ cell data_relocation_base;
- explicit object_fixupper(factor_vm *myvm_) : myvm(myvm_) { }
+ explicit object_fixupper(factor_vm *myvm_, cell data_relocation_base_) :
+ myvm(myvm_), data_relocation_base(data_relocation_base_) { }
void operator()(cell *scan)
{
- myvm->data_fixup(scan);
+ myvm->data_fixup(scan,data_relocation_base);
}
};
/* Initialize an object in a newly-loaded image */
-void factor_vm::relocate_object(object *object)
+void factor_vm::relocate_object(object *object,
+ cell data_relocation_base,
+ cell code_relocation_base)
{
cell hi_tag = object->h.hi_tag();
if(hi_tag == TUPLE_TYPE)
{
tuple *t = (tuple *)object;
- data_fixup(&t->layout);
+ data_fixup(&t->layout,data_relocation_base);
cell *scan = t->data();
cell *end = (cell *)((cell)object + untagged_object_size(object));
for(; scan < end; scan++)
- data_fixup(scan);
+ data_fixup(scan,data_relocation_base);
}
else
{
- object_fixupper fixupper(this);
+ object_fixupper fixupper(this,data_relocation_base);
do_slots((cell)object,fixupper);
switch(hi_tag)
{
case WORD_TYPE:
- fixup_word((word *)object);
+ fixup_word((word *)object,code_relocation_base);
break;
case QUOTATION_TYPE:
- fixup_quotation((quotation *)object);
+ fixup_quotation((quotation *)object,code_relocation_base);
break;
case DLL_TYPE:
ffi_dlopen((dll *)object);
fixup_alien((alien *)object);
break;
case CALLSTACK_TYPE:
- fixup_callstack_object((callstack *)object);
+ fixup_callstack_object((callstack *)object,code_relocation_base);
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()
+void factor_vm::relocate_data(cell data_relocation_base, cell code_relocation_base)
{
- cell relocating;
+ for(cell i = 0; i < USER_ENV; i++)
+ data_fixup(&userenv[i],data_relocation_base);
- cell i;
- for(i = 0; i < USER_ENV; i++)
- data_fixup(&userenv[i]);
+ data_fixup(&T,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);
- data_fixup(&T);
- data_fixup(&bignum_zero);
- data_fixup(&bignum_pos_one);
- data_fixup(&bignum_neg_one);
+ cell obj = data->tenured->start;
- for(relocating = data->tenured->start;
- relocating < data->tenured->here;
- relocating += untagged_object_size((object *)relocating))
+ while(obj)
{
- object *obj = (object *)relocating;
- data->tenured->record_allocation(obj);
- relocate_object(obj);
+ relocate_object((object *)obj,data_relocation_base,code_relocation_base);
+ data->tenured->record_object_start_offset((object *)obj);
+ obj = data->tenured->next_object_after(this,obj);
}
}
-void factor_vm::fixup_code_block(code_block *compiled)
+void factor_vm::fixup_code_block(code_block *compiled, cell data_relocation_base)
{
/* relocate literal table data */
- data_fixup(&compiled->owner);
- data_fixup(&compiled->literals);
- data_fixup(&compiled->relocation);
+ 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 *myvm;
+ cell data_relocation_base;
- code_block_fixupper(factor_vm *myvm_) : myvm(myvm_) { }
+ code_block_fixupper(factor_vm *myvm_, cell data_relocation_base_) :
+ myvm(myvm_), data_relocation_base(data_relocation_base_) { }
void operator()(code_block *compiled)
{
- myvm->fixup_code_block(compiled);
+ myvm->fixup_code_block(compiled,data_relocation_base);
}
};
-void factor_vm::relocate_code()
+void factor_vm::relocate_code(cell data_relocation_base)
{
- code_block_fixupper fixupper(this);
+ code_block_fixupper fixupper(this,data_relocation_base);
iterate_code_heap(fixupper);
}
init_objects(&h);
- relocate_data();
- relocate_code();
+ relocate_data(h.data_relocation_base,h.code_relocation_base);
+ relocate_code(h.data_relocation_base);
/* Store image path name */
userenv[IMAGE_ENV] = allot_alien(F,(cell)p->image_path);
old_space::old_space(cell size_, cell start_) : zone(size_,start_)
{
cell cards_size = size_ >> card_bits;
- allot_markers = new card[cards_size];
- allot_markers_end = allot_markers + cards_size;
+ object_start_offsets = new card[cards_size];
+ object_start_offsets_end = object_start_offsets + cards_size;
}
old_space::~old_space()
{
- delete[] allot_markers;
-}
-
-card *old_space::addr_to_allot_marker(object *a)
-{
- return (card *)((((cell)a - start) >> card_bits) + (cell)allot_markers);
+ delete[] object_start_offsets;
}
/* we need to remember the first object allocated in the card */
-void old_space::record_allocation(object *obj)
+void old_space::record_object_start_offset(object *obj)
{
- card *ptr = addr_to_allot_marker(obj);
- if(*ptr == invalid_allot_marker)
+ card *ptr = (card *)((((cell)obj - start) >> card_bits) + (cell)object_start_offsets);
+ if(*ptr == card_starts_inside_object)
*ptr = ((cell)obj & addr_card_mask);
}
if(here + size > end) return NULL;
object *obj = zone::allot(size);
- record_allocation(obj);
+ record_object_start_offset(obj);
return obj;
}
-void old_space::clear_allot_markers()
+void old_space::clear_object_start_offsets()
{
- memset(allot_markers,invalid_allot_marker,size >> card_bits);
+ memset(object_start_offsets,card_starts_inside_object,size >> card_bits);
}
cell old_space::next_object_after(factor_vm *myvm, cell scan)
cell bignum_pos_one;
cell bignum_neg_one;
- /* Only used during image loading */
- cell code_relocation_base;
- cell data_relocation_base;
-
/* Method dispatch statistics */
cell megamorphic_cache_hits;
cell megamorphic_cache_misses;
bool save_image(const vm_char *filename);
void primitive_save_image();
void primitive_save_image_and_exit();
- void data_fixup(cell *cell);
- template<typename Type> void code_fixup(Type **handle);
- void fixup_word(word *word);
- void fixup_quotation(quotation *quot);
+ void data_fixup(cell *cell, 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);
- void relocate_object(object *object);
- void relocate_data();
- void fixup_code_block(code_block *compiled);
- void relocate_code();
+ 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 load_image(vm_parameters *p);
//callstack