diff --git a/vm/aging_collector.cpp b/vm/aging_collector.cpp index 5e284be587..49b1c520ec 100644 --- a/vm/aging_collector.cpp +++ b/vm/aging_collector.cpp @@ -32,7 +32,7 @@ void factor_vm::collect_aging() current_gc->op = collect_aging_op; std::swap(data->aging,data->aging_semispace); - reset_generation(data->aging); + data->reset_generation(data->aging); aging_collector collector(this); diff --git a/vm/collector.hpp b/vm/collector.hpp index bbaad1d570..9200d95399 100644 --- a/vm/collector.hpp +++ b/vm/collector.hpp @@ -68,7 +68,7 @@ template struct collector { object *promote_object(object *untagged) { - cell size = parent->untagged_object_size(untagged); + cell size = untagged->size(); object *newpointer = target->allot(size); /* XXX not exception-safe */ if(!newpointer) longjmp(current_gc->gc_unwind,1); diff --git a/vm/copying_collector.hpp b/vm/copying_collector.hpp index 640d355bf4..dd36b680a6 100644 --- a/vm/copying_collector.hpp +++ b/vm/copying_collector.hpp @@ -97,7 +97,7 @@ struct copying_collector : collector { { start = gen->find_object_containing_card(card_index - gen_start_card); binary_start = start + this->parent->binary_payload_start((object *)start); - end = start + this->parent->untagged_object_size((object *)start); + end = start + ((object *)start)->size(); } #ifdef FACTOR_DEBUG @@ -113,11 +113,11 @@ scan_next_object: { card_end_address(card_index)); if(end < card_end_address(card_index)) { - start = gen->next_object_after(this->parent,start); + start = gen->next_object_after(start); if(start) { binary_start = start + this->parent->binary_payload_start((object *)start); - end = start + this->parent->untagged_object_size((object *)start); + end = start + ((object *)start)->size(); goto scan_next_object; } } @@ -158,7 +158,7 @@ end: this->parent->gc_stats.card_scan_time += (current_micros() - start_time); while(scan && scan < this->target->here) { this->trace_slots((object *)scan); - scan = this->target->next_object_after(this->parent,scan); + scan = this->target->next_object_after(scan); } } }; diff --git a/vm/data_heap.cpp b/vm/data_heap.cpp index 05ce026973..05f8f3a044 100755 --- a/vm/data_heap.cpp +++ b/vm/data_heap.cpp @@ -65,40 +65,14 @@ data_heap *data_heap::grow(cell requested_bytes) return new data_heap(young_size,aging_size,new_tenured_size); } -void factor_vm::clear_cards(old_space *gen) -{ - cell first_card = addr_to_card(gen->start - data->start); - cell last_card = addr_to_card(gen->end - data->start); - memset(&data->cards[first_card],0,last_card - first_card); -} - -void factor_vm::clear_decks(old_space *gen) -{ - cell first_deck = addr_to_deck(gen->start - data->start); - cell last_deck = addr_to_deck(gen->end - data->start); - memset(&data->decks[first_deck],0,last_deck - first_deck); -} - -/* After garbage collection, any generations which are now empty need to have -their allocation pointers and cards reset. */ -void factor_vm::reset_generation(old_space *gen) -{ - gen->here = gen->start; - if(secure_gc) memset((void*)gen->start,69,gen->size); - - clear_cards(gen); - clear_decks(gen); - gen->clear_object_start_offsets(); -} - void factor_vm::set_data_heap(data_heap *data_) { data = data_; nursery = *data->nursery; nursery.here = nursery.start; init_card_decks(); - reset_generation(data->aging); - reset_generation(data->tenured); + data->reset_generation(data->aging); + data->reset_generation(data->tenured); } void factor_vm::init_data_heap(cell young_size, cell aging_size, cell tenured_size, bool secure_gc_) @@ -113,46 +87,43 @@ cell factor_vm::object_size(cell tagged) if(immediate_p(tagged)) return 0; else - return untagged_object_size(untag(tagged)); + return untag(tagged)->size(); } /* Size of the object pointed to by an untagged pointer */ -cell factor_vm::untagged_object_size(object *pointer) +cell object::size() { - return align(unaligned_object_size(pointer),data_alignment); -} - -/* Size of the data area of an object pointed to by an untagged pointer */ -cell factor_vm::unaligned_object_size(object *pointer) -{ - switch(pointer->h.hi_tag()) + switch(h.hi_tag()) { case ARRAY_TYPE: - return array_size((array*)pointer); + return align(array_size((array*)this),data_alignment); case BIGNUM_TYPE: - return array_size((bignum*)pointer); + return align(array_size((bignum*)this),data_alignment); case BYTE_ARRAY_TYPE: - return array_size((byte_array*)pointer); + return align(array_size((byte_array*)this),data_alignment); case STRING_TYPE: - return string_size(string_capacity((string*)pointer)); + return align(string_size(string_capacity((string*)this)),data_alignment); case TUPLE_TYPE: - return tuple_size(untag(((tuple *)pointer)->layout)); + { + tuple_layout *layout = (tuple_layout *)UNTAG(((tuple *)this)->layout); + return align(tuple_size(layout),data_alignment); + } case QUOTATION_TYPE: - return sizeof(quotation); + return align(sizeof(quotation),data_alignment); case WORD_TYPE: - return sizeof(word); + return align(sizeof(word),data_alignment); case FLOAT_TYPE: - return sizeof(boxed_float); + return align(sizeof(boxed_float),data_alignment); case DLL_TYPE: - return sizeof(dll); + return align(sizeof(dll),data_alignment); case ALIEN_TYPE: - return sizeof(alien); + return align(sizeof(alien),data_alignment); case WRAPPER_TYPE: - return sizeof(wrapper); + return align(sizeof(wrapper),data_alignment); case CALLSTACK_TYPE: - return callstack_size(untag_fixnum(((callstack *)pointer)->length)); + return align(callstack_size(untag_fixnum(((callstack *)this)->length)),data_alignment); default: - critical_error("Invalid header",(cell)pointer); + critical_error("Invalid header",(cell)this); return 0; /* can't happen */ } } @@ -246,7 +217,7 @@ cell factor_vm::next_object() return false_object; object *obj = (object *)heap_scan_ptr; - heap_scan_ptr += untagged_object_size(obj); + heap_scan_ptr += obj->size(); return tag_dynamic(obj); } diff --git a/vm/data_heap.hpp b/vm/data_heap.hpp index 10f3698e74..c882262732 100755 --- a/vm/data_heap.hpp +++ b/vm/data_heap.hpp @@ -25,6 +25,34 @@ struct data_heap { explicit data_heap(cell young_size, cell aging_size, cell tenured_size); ~data_heap(); data_heap *grow(cell requested_size); + template void clear_cards(Generation *gen); + template void clear_decks(Generation *gen); + template void reset_generation(Generation *gen); }; +template void data_heap::clear_cards(Generation *gen) +{ + cell first_card = addr_to_card(gen->start - start); + cell last_card = addr_to_card(gen->end - start); + memset(&cards[first_card],0,last_card - first_card); +} + +template void data_heap::clear_decks(Generation *gen) +{ + cell first_deck = addr_to_deck(gen->start - start); + cell last_deck = addr_to_deck(gen->end - start); + memset(&decks[first_deck],0,last_deck - first_deck); +} + +/* After garbage collection, any generations which are now empty need to have +their allocation pointers and cards reset. */ +template void data_heap::reset_generation(Generation *gen) +{ + gen->here = gen->start; + + clear_cards(gen); + clear_decks(gen); + gen->clear_object_start_offsets(); +} + } diff --git a/vm/full_collector.cpp b/vm/full_collector.cpp index 61827fba41..1bb03d08e7 100644 --- a/vm/full_collector.cpp +++ b/vm/full_collector.cpp @@ -100,7 +100,7 @@ void full_collector::cheneys_algorithm() object *obj = (object *)scan; this->trace_slots(obj); this->mark_object_code_block(obj); - scan = target->next_object_after(this->parent,scan); + scan = target->next_object_after(scan); } } @@ -120,7 +120,7 @@ void factor_vm::collect_full_impl(bool trace_contexts_p) collector.cheneys_algorithm(); - reset_generation(data->aging); + data->reset_generation(data->aging); nursery.here = nursery.start; } @@ -146,7 +146,7 @@ void factor_vm::collect_full(bool trace_contexts_p, bool compact_code_heap_p) { /* Copy all live objects to the tenured semispace. */ std::swap(data->tenured,data->tenured_semispace); - reset_generation(data->tenured); + data->reset_generation(data->tenured); collect_full_impl(trace_contexts_p); if(compact_code_heap_p) diff --git a/vm/image.cpp b/vm/image.cpp index c96da6b703..f41ae555a3 100755 --- a/vm/image.cpp +++ b/vm/image.cpp @@ -155,7 +155,7 @@ void factor_vm::relocate_object(object *object, data_fixup(&t->layout,data_relocation_base); cell *scan = t->data(); - cell *end = (cell *)((cell)object + untagged_object_size(object)); + cell *end = (cell *)((cell)object + object->size()); for(; scan < end; scan++) data_fixup(scan,data_relocation_base); @@ -204,7 +204,7 @@ void factor_vm::relocate_data(cell data_relocation_base, cell code_relocation_ba { 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); + obj = data->tenured->next_object_after(obj); } } diff --git a/vm/layouts.hpp b/vm/layouts.hpp index c25c2c0fc1..f0dbff6c30 100644 --- a/vm/layouts.hpp +++ b/vm/layouts.hpp @@ -114,26 +114,31 @@ struct header { explicit header(cell value_) : value(value_ << TAG_BITS) {} - void check_header() { + void check_header() + { #ifdef FACTOR_DEBUG assert(TAG(value) == FIXNUM_TYPE && untag_fixnum(value) < TYPE_COUNT); #endif } - cell hi_tag() { + cell hi_tag() + { check_header(); return value >> TAG_BITS; } - bool forwarding_pointer_p() { + bool forwarding_pointer_p() + { return TAG(value) == GC_COLLECTED; } - object *forwarding_pointer() { + object *forwarding_pointer() + { return (object *)UNTAG(value); } - void forward_to(object *pointer) { + void forward_to(object *pointer) + { value = RETAG(pointer,GC_COLLECTED); } }; @@ -144,6 +149,7 @@ struct object { NO_TYPE_CHECK; header h; cell *slots() { return (cell *)this; } + cell size(); }; /* Assembly code makes assumptions about the layout of this struct */ diff --git a/vm/old_space.cpp b/vm/old_space.cpp index 5fd78a7cf4..9440749e52 100644 --- a/vm/old_space.cpp +++ b/vm/old_space.cpp @@ -62,9 +62,9 @@ void old_space::clear_object_start_offsets() memset(object_start_offsets,card_starts_inside_object,addr_to_card(size)); } -cell old_space::next_object_after(factor_vm *parent, cell scan) +cell old_space::next_object_after(cell scan) { - cell size = parent->untagged_object_size((object *)scan); + cell size = ((object *)scan)->size(); if(scan + size < here) return scan + size; else diff --git a/vm/old_space.hpp b/vm/old_space.hpp index d037a039ae..e59537cffb 100644 --- a/vm/old_space.hpp +++ b/vm/old_space.hpp @@ -15,7 +15,7 @@ struct old_space : zone { void record_object_start_offset(object *obj); object *allot(cell size); void clear_object_start_offsets(); - cell next_object_after(factor_vm *parent, cell scan); + cell next_object_after(cell scan); }; } diff --git a/vm/to_tenured_collector.cpp b/vm/to_tenured_collector.cpp index b5d4793ceb..3676324ce2 100644 --- a/vm/to_tenured_collector.cpp +++ b/vm/to_tenured_collector.cpp @@ -25,7 +25,7 @@ void factor_vm::collect_to_tenured() update_code_heap_for_minor_gc(&code->points_to_aging); nursery.here = nursery.start; - reset_generation(data->aging); + data->reset_generation(data->aging); code->points_to_nursery.clear(); code->points_to_aging.clear(); } diff --git a/vm/vm.hpp b/vm/vm.hpp index 87697d5a0f..2df66e97b3 100755 --- a/vm/vm.hpp +++ b/vm/vm.hpp @@ -220,13 +220,8 @@ struct factor_vm //data heap void init_card_decks(); - void clear_cards(old_space *gen); - void clear_decks(old_space *gen); - void reset_generation(old_space *gen); void set_data_heap(data_heap *data_); void init_data_heap(cell young_size, cell aging_size, cell tenured_size, bool secure_gc_); - cell untagged_object_size(object *pointer); - cell unaligned_object_size(object *pointer); void primitive_size(); cell binary_payload_start(object *pointer); void primitive_data_room();