diff --git a/vm/aging_space.hpp b/vm/aging_space.hpp index c2ec2a645e..1fac4605d2 100644 --- a/vm/aging_space.hpp +++ b/vm/aging_space.hpp @@ -1,8 +1,20 @@ namespace factor { -struct aging_space : old_space { - aging_space(cell size, cell start) : old_space(size,start) {} +struct aging_space : zone { + object_start_map starts; + + aging_space(cell size, cell start) : + zone(size,start), starts(size,start) {} + + object *allot(cell size) + { + if(here + size > end) return NULL; + + object *obj = zone::allot(size); + starts.record_object_start_offset(obj); + return obj; + } }; } diff --git a/vm/code_heap.hpp b/vm/code_heap.hpp index e98d966afe..b29e33ca64 100755 --- a/vm/code_heap.hpp +++ b/vm/code_heap.hpp @@ -6,11 +6,6 @@ struct code_heap_layout { { return block->size(); } - - heap_block *next_block_after(heap_block *block) - { - return (heap_block *)((cell)block + block_size(block)); - } }; struct code_heap : heap { diff --git a/vm/copying_collector.hpp b/vm/copying_collector.hpp index dd36b680a6..4bb56945a1 100644 --- a/vm/copying_collector.hpp +++ b/vm/copying_collector.hpp @@ -95,7 +95,7 @@ struct copying_collector : collector { if(end < card_start_address(card_index)) { - start = gen->find_object_containing_card(card_index - gen_start_card); + start = gen->starts.find_object_containing_card(card_index - gen_start_card); binary_start = start + this->parent->binary_payload_start((object *)start); end = start + ((object *)start)->size(); } diff --git a/vm/data_heap.hpp b/vm/data_heap.hpp index c882262732..3a0af1f36a 100755 --- a/vm/data_heap.hpp +++ b/vm/data_heap.hpp @@ -52,7 +52,7 @@ template void data_heap::reset_generation(Generation *gen) clear_cards(gen); clear_decks(gen); - gen->clear_object_start_offsets(); + gen->starts.clear_object_start_offsets(); } } diff --git a/vm/heap.hpp b/vm/heap.hpp index 653ac2d93d..c82b88ee2f 100644 --- a/vm/heap.hpp +++ b/vm/heap.hpp @@ -28,6 +28,11 @@ template struct heap { return (Block *)seg->end; } + Block *next_block_after(heap_block *block) + { + return (Block *)((cell)block + layout.block_size(block)); + } + void clear_free_list(); void add_to_free_list(free_heap_block *block); void build_free_list(cell size); @@ -50,7 +55,7 @@ template struct heap { while(scan != end) { - Block *next = layout.next_block_after(scan); + Block *next = next_block_after(scan); if(!scan->free_p()) iter(scan,layout.block_size(scan)); scan = next; } @@ -229,7 +234,7 @@ void heap::heap_usage(cell *used, cell *total_free, cell *max_ else *used += size; - scan = layout.next_block_after(scan); + scan = next_block_after(scan); } } @@ -243,7 +248,7 @@ cell heap::heap_size() while(scan != end) { if(scan->free_p()) break; - else scan = layout.next_block_after(scan); + else scan = next_block_after(scan); } if(scan != end) @@ -308,7 +313,7 @@ void heap::sweep_heap(Iterator &iter) } } - scan = layout.next_block_after(scan); + scan = next_block_after(scan); } if(prev && prev->free_p()) diff --git a/vm/image.cpp b/vm/image.cpp index f41ae555a3..7d8c4a2d32 100755 --- a/vm/image.cpp +++ b/vm/image.cpp @@ -203,7 +203,7 @@ void factor_vm::relocate_data(cell data_relocation_base, cell code_relocation_ba while(obj) { relocate_object((object *)obj,data_relocation_base,code_relocation_base); - data->tenured->record_object_start_offset((object *)obj); + data->tenured->starts.record_object_start_offset((object *)obj); obj = data->tenured->next_object_after(obj); } } diff --git a/vm/layouts.hpp b/vm/layouts.hpp index f0dbff6c30..ca51fd6dca 100644 --- a/vm/layouts.hpp +++ b/vm/layouts.hpp @@ -148,8 +148,17 @@ struct header { struct object { NO_TYPE_CHECK; header h; - cell *slots() { return (cell *)this; } + cell size(); + + cell *slots() { return (cell *)this; } + + /* Only valid for objects in tenured space; must fast to free_heap_block + to do anything with it if its free */ + bool free_p() + { + return h.value & 1 == 1; + } }; /* Assembly code makes assumptions about the layout of this struct */ diff --git a/vm/mark_bits.hpp b/vm/mark_bits.hpp index d9c9534edb..bc318524b4 100644 --- a/vm/mark_bits.hpp +++ b/vm/mark_bits.hpp @@ -70,10 +70,15 @@ template struct mark_bits { return (bits[pair.first] & ((u64)1 << pair.second)) != 0; } + Block *next_block_after(Block *block) + { + return (Block *)((cell)block + layout.block_size(block)); + } + void set_bitmap_range(u64 *bits, Block *address) { std::pair start = bitmap_deref(address); - std::pair end = bitmap_deref(layout.next_block_after(address)); + std::pair end = bitmap_deref(next_block_after(address)); u64 start_mask = ((u64)1 << start.second) - 1; u64 end_mask = ((u64)1 << end.second) - 1; diff --git a/vm/old_space.cpp b/vm/old_space.cpp index 9440749e52..5f992e783e 100644 --- a/vm/old_space.cpp +++ b/vm/old_space.cpp @@ -3,23 +3,24 @@ namespace factor { -old_space::old_space(cell size_, cell start_) : zone(size_,start_) +object_start_map::object_start_map(cell size_, cell start_) : + size(size_), start(start_) { object_start_offsets = new card[addr_to_card(size_)]; object_start_offsets_end = object_start_offsets + addr_to_card(size_); } -old_space::~old_space() +object_start_map::~object_start_map() { delete[] object_start_offsets; } -cell old_space::first_object_in_card(cell card_index) +cell object_start_map::first_object_in_card(cell card_index) { return object_start_offsets[card_index]; } -cell old_space::find_object_containing_card(cell card_index) +cell object_start_map::find_object_containing_card(cell card_index) { if(card_index == 0) return start; @@ -41,34 +42,16 @@ cell old_space::find_object_containing_card(cell card_index) } /* we need to remember the first object allocated in the card */ -void old_space::record_object_start_offset(object *obj) +void object_start_map::record_object_start_offset(object *obj) { cell idx = addr_to_card((cell)obj - start); - if(object_start_offsets[idx] == card_starts_inside_object) - object_start_offsets[idx] = ((cell)obj & addr_card_mask); + card obj_start = ((cell)obj & addr_card_mask); + object_start_offsets[idx] = std::min(object_start_offsets[idx],obj_start); } -object *old_space::allot(cell size) -{ - if(here + size > end) return NULL; - - object *obj = zone::allot(size); - record_object_start_offset(obj); - return obj; -} - -void old_space::clear_object_start_offsets() +void object_start_map::clear_object_start_offsets() { memset(object_start_offsets,card_starts_inside_object,addr_to_card(size)); } -cell old_space::next_object_after(cell scan) -{ - cell size = ((object *)scan)->size(); - if(scan + size < here) - return scan + size; - else - return 0; -} - } diff --git a/vm/old_space.hpp b/vm/old_space.hpp index e59537cffb..640e205852 100644 --- a/vm/old_space.hpp +++ b/vm/old_space.hpp @@ -3,19 +3,18 @@ namespace factor static const cell card_starts_inside_object = 0xff; -struct old_space : zone { +struct object_start_map { + cell size, start; card *object_start_offsets; card *object_start_offsets_end; - old_space(cell size_, cell start_); - ~old_space(); + object_start_map(cell size_, cell start_); + ~object_start_map(); cell first_object_in_card(cell card_index); cell find_object_containing_card(cell card_index); void record_object_start_offset(object *obj); - object *allot(cell size); void clear_object_start_offsets(); - cell next_object_after(cell scan); }; } diff --git a/vm/tenured_space.hpp b/vm/tenured_space.hpp index f9f584b200..a700b58bfd 100644 --- a/vm/tenured_space.hpp +++ b/vm/tenured_space.hpp @@ -1,8 +1,33 @@ namespace factor { -struct tenured_space : old_space { - tenured_space(cell size, cell start) : old_space(size,start) {} +struct tenured_space_layout { + cell block_size(object *block) + { + if(block->free_p()) + { + free_heap_block *free_block = (free_heap_block *)block; + return free_block->size(); + } + else + return block->size(); + } +}; + +struct tenured_space : zone { + object_start_map starts; + + tenured_space(cell size, cell start) : + zone(size,start), starts(size,start) {} + + object *allot(cell size) + { + if(here + size > end) return NULL; + + object *obj = zone::allot(size); + starts.record_object_start_offset(obj); + return obj; + } }; } diff --git a/vm/zone.hpp b/vm/zone.hpp index 2c28922fbc..42196f315b 100644 --- a/vm/zone.hpp +++ b/vm/zone.hpp @@ -21,6 +21,15 @@ struct zone { here = h + align(size,data_alignment); return (object *)h; } + + cell next_object_after(cell scan) + { + cell size = ((object *)scan)->size(); + if(scan + size < here) + return scan + size; + else + return 0; + } }; }