vm: misc cleanups
parent
a4ea6ad339
commit
95722adebc
|
@ -14,7 +14,7 @@ char *factor_vm::pinned_alien_offset(cell obj)
|
|||
alien *ptr = untag<alien>(obj);
|
||||
if(ptr->expired != F)
|
||||
general_error(ERROR_EXPIRED,obj,F,NULL);
|
||||
return pinned_alien_offset(ptr->alien) + ptr->displacement;
|
||||
return pinned_alien_offset(ptr->base) + ptr->displacement;
|
||||
}
|
||||
case F_TYPE:
|
||||
return NULL;
|
||||
|
@ -34,10 +34,10 @@ cell factor_vm::allot_alien(cell delegate_, cell displacement)
|
|||
{
|
||||
tagged<alien> delegate_alien = delegate.as<alien>();
|
||||
displacement += delegate_alien->displacement;
|
||||
new_alien->alien = delegate_alien->alien;
|
||||
new_alien->base = delegate_alien->base;
|
||||
}
|
||||
else
|
||||
new_alien->alien = delegate.value();
|
||||
new_alien->base = delegate.value();
|
||||
|
||||
new_alien->displacement = displacement;
|
||||
new_alien->expired = F;
|
||||
|
@ -172,7 +172,7 @@ char *factor_vm::alien_offset(cell obj)
|
|||
alien *ptr = untag<alien>(obj);
|
||||
if(ptr->expired != F)
|
||||
general_error(ERROR_EXPIRED,obj,F,NULL);
|
||||
return alien_offset(ptr->alien) + ptr->displacement;
|
||||
return alien_offset(ptr->base) + ptr->displacement;
|
||||
}
|
||||
case F_TYPE:
|
||||
return NULL;
|
||||
|
|
|
@ -95,7 +95,7 @@ void factor_vm::reset_generation(old_space *gen)
|
|||
|
||||
clear_cards(gen);
|
||||
clear_decks(gen);
|
||||
gen->clear_allot_markers();
|
||||
gen->clear_object_start_offsets();
|
||||
}
|
||||
|
||||
void factor_vm::set_data_heap(data_heap *data_)
|
||||
|
|
|
@ -172,9 +172,7 @@ void heap::mark_block(heap_block *block)
|
|||
block->set_marked_p(true);
|
||||
}
|
||||
|
||||
/* If in the middle of code GC, we have to grow the heap, data GC restarts from
|
||||
scratch, so we have to unmark any marked blocks. */
|
||||
void heap::unmark_marked()
|
||||
void heap::clear_mark_bits()
|
||||
{
|
||||
heap_block *scan = first_block();
|
||||
|
||||
|
|
|
@ -46,7 +46,7 @@ struct heap {
|
|||
heap_block *heap_allot(cell size, cell type);
|
||||
void heap_free(heap_block *block);
|
||||
void mark_block(heap_block *block);
|
||||
void unmark_marked();
|
||||
void clear_mark_bits();
|
||||
void heap_usage(cell *used, cell *total_free, cell *max_free);
|
||||
cell heap_size();
|
||||
cell compute_heap_forwarding();
|
||||
|
|
105
vm/image.cpp
105
vm/image.cpp
|
@ -41,7 +41,6 @@ void factor_vm::load_data_heap(FILE *file, image_header *h, vm_parameters *p)
|
|||
}
|
||||
|
||||
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)
|
||||
|
@ -65,7 +64,6 @@ 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);
|
||||
}
|
||||
|
||||
|
@ -147,7 +145,7 @@ void factor_vm::primitive_save_image_and_exit()
|
|||
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;
|
||||
|
@ -155,28 +153,28 @@ void factor_vm::data_fixup(cell *cell)
|
|||
*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;
|
||||
|
@ -184,39 +182,45 @@ void factor_vm::fixup_quotation(quotation *quot)
|
|||
|
||||
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();
|
||||
|
||||
|
@ -226,26 +230,26 @@ void factor_vm::relocate_object(object *object)
|
|||
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);
|
||||
|
@ -254,7 +258,7 @@ void factor_vm::relocate_object(object *object)
|
|||
fixup_alien((alien *)object);
|
||||
break;
|
||||
case CALLSTACK_TYPE:
|
||||
fixup_callstack_object((callstack *)object);
|
||||
fixup_callstack_object((callstack *)object,code_relocation_base);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -262,53 +266,52 @@ void factor_vm::relocate_object(object *object)
|
|||
|
||||
/* 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);
|
||||
}
|
||||
|
||||
|
@ -341,8 +344,8 @@ void factor_vm::load_image(vm_parameters *p)
|
|||
|
||||
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);
|
||||
|
|
|
@ -305,7 +305,7 @@ struct quotation : public object {
|
|||
struct alien : public object {
|
||||
static const cell type_number = ALIEN_TYPE;
|
||||
/* tagged */
|
||||
cell alien;
|
||||
cell base;
|
||||
/* tagged */
|
||||
cell expired;
|
||||
/* untagged */
|
||||
|
|
|
@ -6,25 +6,20 @@ namespace factor
|
|||
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);
|
||||
}
|
||||
|
||||
|
@ -33,13 +28,13 @@ object *old_space::allot(cell size)
|
|||
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)
|
||||
|
|
|
@ -1,27 +1,23 @@
|
|||
namespace factor
|
||||
{
|
||||
|
||||
struct allot_marker {
|
||||
char first_object_start;
|
||||
char last_object_start;
|
||||
};
|
||||
static const cell card_starts_inside_object = 0xff;
|
||||
|
||||
struct old_space : zone {
|
||||
card *allot_markers;
|
||||
card *allot_markers_end;
|
||||
card *object_start_offsets;
|
||||
card *object_start_offsets_end;
|
||||
|
||||
old_space(cell size_, cell start_);
|
||||
~old_space();
|
||||
|
||||
cell first_object_in_card(cell address)
|
||||
{
|
||||
return allot_markers[(address - start) >> card_bits];
|
||||
return object_start_offsets[(address - start) >> card_bits];
|
||||
}
|
||||
|
||||
card *addr_to_allot_marker(object *a);
|
||||
void record_allocation(object *obj);
|
||||
void record_object_start_offset(object *obj);
|
||||
object *allot(cell size);
|
||||
void clear_allot_markers();
|
||||
void clear_object_start_offsets();
|
||||
cell next_object_after(factor_vm *myvm, cell scan);
|
||||
};
|
||||
|
||||
|
|
22
vm/vm.hpp
22
vm/vm.hpp
|
@ -74,10 +74,6 @@ struct factor_vm
|
|||
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;
|
||||
|
@ -551,16 +547,16 @@ struct factor_vm
|
|||
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
|
||||
|
|
|
@ -24,6 +24,5 @@ typedef u8 card_deck;
|
|||
static const cell deck_bits = (card_bits + 10);
|
||||
static const cell deck_size = (1<<deck_bits);
|
||||
static const cell addr_deck_mask = (deck_size-1);
|
||||
static const cell invalid_allot_marker = 0xff;
|
||||
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue