vm: misc cleanups

db4
Slava Pestov 2009-10-09 03:20:50 -05:00
parent a4ea6ad339
commit 95722adebc
10 changed files with 86 additions and 99 deletions

View File

@ -14,7 +14,7 @@ char *factor_vm::pinned_alien_offset(cell obj)
alien *ptr = untag<alien>(obj); alien *ptr = untag<alien>(obj);
if(ptr->expired != F) if(ptr->expired != F)
general_error(ERROR_EXPIRED,obj,F,NULL); 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: case F_TYPE:
return NULL; return NULL;
@ -34,10 +34,10 @@ cell factor_vm::allot_alien(cell delegate_, cell displacement)
{ {
tagged<alien> delegate_alien = delegate.as<alien>(); tagged<alien> delegate_alien = delegate.as<alien>();
displacement += delegate_alien->displacement; displacement += delegate_alien->displacement;
new_alien->alien = delegate_alien->alien; new_alien->base = delegate_alien->base;
} }
else else
new_alien->alien = delegate.value(); new_alien->base = delegate.value();
new_alien->displacement = displacement; new_alien->displacement = displacement;
new_alien->expired = F; new_alien->expired = F;
@ -172,7 +172,7 @@ char *factor_vm::alien_offset(cell obj)
alien *ptr = untag<alien>(obj); alien *ptr = untag<alien>(obj);
if(ptr->expired != F) if(ptr->expired != F)
general_error(ERROR_EXPIRED,obj,F,NULL); general_error(ERROR_EXPIRED,obj,F,NULL);
return alien_offset(ptr->alien) + ptr->displacement; return alien_offset(ptr->base) + ptr->displacement;
} }
case F_TYPE: case F_TYPE:
return NULL; return NULL;

View File

@ -95,7 +95,7 @@ void factor_vm::reset_generation(old_space *gen)
clear_cards(gen); clear_cards(gen);
clear_decks(gen); clear_decks(gen);
gen->clear_allot_markers(); gen->clear_object_start_offsets();
} }
void factor_vm::set_data_heap(data_heap *data_) void factor_vm::set_data_heap(data_heap *data_)

View File

@ -172,9 +172,7 @@ void heap::mark_block(heap_block *block)
block->set_marked_p(true); block->set_marked_p(true);
} }
/* If in the middle of code GC, we have to grow the heap, data GC restarts from void heap::clear_mark_bits()
scratch, so we have to unmark any marked blocks. */
void heap::unmark_marked()
{ {
heap_block *scan = first_block(); heap_block *scan = first_block();

View File

@ -46,7 +46,7 @@ struct heap {
heap_block *heap_allot(cell size, cell type); heap_block *heap_allot(cell size, cell type);
void heap_free(heap_block *block); void heap_free(heap_block *block);
void mark_block(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); void heap_usage(cell *used, cell *total_free, cell *max_free);
cell heap_size(); cell heap_size();
cell compute_heap_forwarding(); cell compute_heap_forwarding();

View File

@ -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->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) 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); code->build_free_list(h->code_size);
} }
@ -147,7 +145,7 @@ void factor_vm::primitive_save_image_and_exit()
exit(1); exit(1);
} }
void factor_vm::data_fixup(cell *cell) void factor_vm::data_fixup(cell *cell, cell data_relocation_base)
{ {
if(immediate_p(*cell)) if(immediate_p(*cell))
return; return;
@ -155,28 +153,28 @@ void factor_vm::data_fixup(cell *cell)
*cell += (data->tenured->start - data_relocation_base); *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 *ptr = *handle;
Type *new_ptr = (Type *)(((cell)ptr) + (code->seg->start - code_relocation_base)); Type *new_ptr = (Type *)(((cell)ptr) + (code->seg->start - code_relocation_base));
*handle = new_ptr; *handle = new_ptr;
} }
void factor_vm::fixup_word(word *word) void factor_vm::fixup_word(word *word, cell code_relocation_base)
{ {
if(word->code) if(word->code)
code_fixup(&word->code); code_fixup(&word->code,code_relocation_base);
if(word->profiling) if(word->profiling)
code_fixup(&word->profiling); code_fixup(&word->profiling,code_relocation_base);
code_fixup(&word->xt); 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) if(quot->code)
{ {
code_fixup(&quot->xt); code_fixup(&quot->xt,code_relocation_base);
code_fixup(&quot->code); code_fixup(&quot->code,code_relocation_base);
} }
else else
quot->xt = (void *)lazy_jit_compile; quot->xt = (void *)lazy_jit_compile;
@ -184,39 +182,45 @@ void factor_vm::fixup_quotation(quotation *quot)
void factor_vm::fixup_alien(alien *d) void factor_vm::fixup_alien(alien *d)
{ {
d->expired = T; if(d->base == F) d->expired = T;
} }
struct stack_frame_fixupper { struct stack_frame_fixupper {
factor_vm *myvm; 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) void operator()(stack_frame *frame)
{ {
myvm->code_fixup(&frame->xt); myvm->code_fixup(&frame->xt,code_relocation_base);
myvm->code_fixup(&FRAME_RETURN_ADDRESS(frame,myvm)); 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); iterate_callstack_object(stack,fixupper);
} }
struct object_fixupper { struct object_fixupper {
factor_vm *myvm; 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) void operator()(cell *scan)
{ {
myvm->data_fixup(scan); myvm->data_fixup(scan,data_relocation_base);
} }
}; };
/* Initialize an object in a newly-loaded image */ /* 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(); cell hi_tag = object->h.hi_tag();
@ -226,26 +230,26 @@ void factor_vm::relocate_object(object *object)
if(hi_tag == TUPLE_TYPE) if(hi_tag == TUPLE_TYPE)
{ {
tuple *t = (tuple *)object; tuple *t = (tuple *)object;
data_fixup(&t->layout); data_fixup(&t->layout,data_relocation_base);
cell *scan = t->data(); cell *scan = t->data();
cell *end = (cell *)((cell)object + untagged_object_size(object)); cell *end = (cell *)((cell)object + untagged_object_size(object));
for(; scan < end; scan++) for(; scan < end; scan++)
data_fixup(scan); data_fixup(scan,data_relocation_base);
} }
else else
{ {
object_fixupper fixupper(this); object_fixupper fixupper(this,data_relocation_base);
do_slots((cell)object,fixupper); do_slots((cell)object,fixupper);
switch(hi_tag) switch(hi_tag)
{ {
case WORD_TYPE: case WORD_TYPE:
fixup_word((word *)object); fixup_word((word *)object,code_relocation_base);
break; break;
case QUOTATION_TYPE: case QUOTATION_TYPE:
fixup_quotation((quotation *)object); fixup_quotation((quotation *)object,code_relocation_base);
break; break;
case DLL_TYPE: case DLL_TYPE:
ffi_dlopen((dll *)object); ffi_dlopen((dll *)object);
@ -254,7 +258,7 @@ void factor_vm::relocate_object(object *object)
fixup_alien((alien *)object); fixup_alien((alien *)object);
break; break;
case CALLSTACK_TYPE: case CALLSTACK_TYPE:
fixup_callstack_object((callstack *)object); fixup_callstack_object((callstack *)object,code_relocation_base);
break; 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 /* 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. */ 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; data_fixup(&T,data_relocation_base);
for(i = 0; i < USER_ENV; i++) data_fixup(&bignum_zero,data_relocation_base);
data_fixup(&userenv[i]); data_fixup(&bignum_pos_one,data_relocation_base);
data_fixup(&bignum_neg_one,data_relocation_base);
data_fixup(&T); cell obj = data->tenured->start;
data_fixup(&bignum_zero);
data_fixup(&bignum_pos_one);
data_fixup(&bignum_neg_one);
for(relocating = data->tenured->start; while(obj)
relocating < data->tenured->here;
relocating += untagged_object_size((object *)relocating))
{ {
object *obj = (object *)relocating; relocate_object((object *)obj,data_relocation_base,code_relocation_base);
data->tenured->record_allocation(obj); data->tenured->record_object_start_offset((object *)obj);
relocate_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 */ /* relocate literal table data */
data_fixup(&compiled->owner); data_fixup(&compiled->owner,data_relocation_base);
data_fixup(&compiled->literals); data_fixup(&compiled->literals,data_relocation_base);
data_fixup(&compiled->relocation); data_fixup(&compiled->relocation,data_relocation_base);
relocate_code_block(compiled); relocate_code_block(compiled);
} }
struct code_block_fixupper { struct code_block_fixupper {
factor_vm *myvm; 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) 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); iterate_code_heap(fixupper);
} }
@ -341,8 +344,8 @@ void factor_vm::load_image(vm_parameters *p)
init_objects(&h); init_objects(&h);
relocate_data(); relocate_data(h.data_relocation_base,h.code_relocation_base);
relocate_code(); relocate_code(h.data_relocation_base);
/* Store image path name */ /* Store image path name */
userenv[IMAGE_ENV] = allot_alien(F,(cell)p->image_path); userenv[IMAGE_ENV] = allot_alien(F,(cell)p->image_path);

View File

@ -305,7 +305,7 @@ struct quotation : public object {
struct alien : public object { struct alien : public object {
static const cell type_number = ALIEN_TYPE; static const cell type_number = ALIEN_TYPE;
/* tagged */ /* tagged */
cell alien; cell base;
/* tagged */ /* tagged */
cell expired; cell expired;
/* untagged */ /* untagged */

View File

@ -6,25 +6,20 @@ namespace factor
old_space::old_space(cell size_, cell start_) : zone(size_,start_) old_space::old_space(cell size_, cell start_) : zone(size_,start_)
{ {
cell cards_size = size_ >> card_bits; cell cards_size = size_ >> card_bits;
allot_markers = new card[cards_size]; object_start_offsets = new card[cards_size];
allot_markers_end = allot_markers + cards_size; object_start_offsets_end = object_start_offsets + cards_size;
} }
old_space::~old_space() old_space::~old_space()
{ {
delete[] allot_markers; delete[] object_start_offsets;
}
card *old_space::addr_to_allot_marker(object *a)
{
return (card *)((((cell)a - start) >> card_bits) + (cell)allot_markers);
} }
/* we need to remember the first object allocated in the card */ /* 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); card *ptr = (card *)((((cell)obj - start) >> card_bits) + (cell)object_start_offsets);
if(*ptr == invalid_allot_marker) if(*ptr == card_starts_inside_object)
*ptr = ((cell)obj & addr_card_mask); *ptr = ((cell)obj & addr_card_mask);
} }
@ -33,13 +28,13 @@ object *old_space::allot(cell size)
if(here + size > end) return NULL; if(here + size > end) return NULL;
object *obj = zone::allot(size); object *obj = zone::allot(size);
record_allocation(obj); record_object_start_offset(obj);
return 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 old_space::next_object_after(factor_vm *myvm, cell scan)

View File

@ -1,27 +1,23 @@
namespace factor namespace factor
{ {
struct allot_marker { static const cell card_starts_inside_object = 0xff;
char first_object_start;
char last_object_start;
};
struct old_space : zone { struct old_space : zone {
card *allot_markers; card *object_start_offsets;
card *allot_markers_end; card *object_start_offsets_end;
old_space(cell size_, cell start_); old_space(cell size_, cell start_);
~old_space(); ~old_space();
cell first_object_in_card(cell address) 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_object_start_offset(object *obj);
void record_allocation(object *obj);
object *allot(cell size); object *allot(cell size);
void clear_allot_markers(); void clear_object_start_offsets();
cell next_object_after(factor_vm *myvm, cell scan); cell next_object_after(factor_vm *myvm, cell scan);
}; };

View File

@ -74,10 +74,6 @@ struct factor_vm
cell bignum_pos_one; cell bignum_pos_one;
cell bignum_neg_one; cell bignum_neg_one;
/* Only used during image loading */
cell code_relocation_base;
cell data_relocation_base;
/* Method dispatch statistics */ /* Method dispatch statistics */
cell megamorphic_cache_hits; cell megamorphic_cache_hits;
cell megamorphic_cache_misses; cell megamorphic_cache_misses;
@ -551,16 +547,16 @@ struct factor_vm
bool save_image(const vm_char *filename); bool save_image(const vm_char *filename);
void primitive_save_image(); void primitive_save_image();
void primitive_save_image_and_exit(); void primitive_save_image_and_exit();
void data_fixup(cell *cell); void data_fixup(cell *cell, cell data_relocation_base);
template<typename Type> void code_fixup(Type **handle); template<typename Type> void code_fixup(Type **handle, cell code_relocation_base);
void fixup_word(word *word); void fixup_word(word *word, cell code_relocation_base);
void fixup_quotation(quotation *quot); void fixup_quotation(quotation *quot, cell code_relocation_base);
void fixup_alien(alien *d); void fixup_alien(alien *d);
void fixup_callstack_object(callstack *stack); void fixup_callstack_object(callstack *stack, cell code_relocation_base);
void relocate_object(object *object); void relocate_object(object *object, cell data_relocation_base, cell code_relocation_base);
void relocate_data(); void relocate_data(cell data_relocation_base, cell code_relocation_base);
void fixup_code_block(code_block *compiled); void fixup_code_block(code_block *compiled, cell data_relocation_base);
void relocate_code(); void relocate_code(cell data_relocation_base);
void load_image(vm_parameters *p); void load_image(vm_parameters *p);
//callstack //callstack

View File

@ -24,6 +24,5 @@ typedef u8 card_deck;
static const cell deck_bits = (card_bits + 10); static const cell deck_bits = (card_bits + 10);
static const cell deck_size = (1<<deck_bits); static const cell deck_size = (1<<deck_bits);
static const cell addr_deck_mask = (deck_size-1); static const cell addr_deck_mask = (deck_size-1);
static const cell invalid_allot_marker = 0xff;
} }