]> gitweb.factorcode.org Git - factor.git/commitdiff
vm: object start recording in cards is now independent of allocation strategy
authorSlava Pestov <slava@slava-pestovs-macbook-pro.local>
Tue, 20 Oct 2009 18:47:04 +0000 (13:47 -0500)
committerSlava Pestov <slava@slava-pestovs-macbook-pro.local>
Tue, 20 Oct 2009 18:47:04 +0000 (13:47 -0500)
12 files changed:
vm/aging_space.hpp
vm/code_heap.hpp
vm/copying_collector.hpp
vm/data_heap.hpp
vm/heap.hpp
vm/image.cpp
vm/layouts.hpp
vm/mark_bits.hpp
vm/old_space.cpp
vm/old_space.hpp
vm/tenured_space.hpp
vm/zone.hpp

index c2ec2a645e6bae172efdb58eb67e29cf7518e47b..1fac4605d2eeedbfe8acbb7ab50801b1c93572a7 100644 (file)
@@ -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;
+       }
 };
 
 }
index e98d966afe63f99e540e57949ccc472b1e1166f6..b29e33ca64fe3bb6b6834a70231b5f31bad1c901 100755 (executable)
@@ -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<heap_block,code_heap_layout> {
index dd36b680a6888cca0a96170c9aa1290d29619655..4bb56945a1fbd829f440ea4ff14ebdcf1306a79b 100644 (file)
@@ -95,7 +95,7 @@ struct copying_collector : collector<TargetGeneration,Policy> {
 
                                                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();
                                                }
index c882262732e0edc04da12f07e8db68151eb34f66..3a0af1f36a6f64d079207216f29e22883890e4e4 100755 (executable)
@@ -52,7 +52,7 @@ template<typename Generation> void data_heap::reset_generation(Generation *gen)
 
        clear_cards(gen);
        clear_decks(gen);
-       gen->clear_object_start_offsets();
+       gen->starts.clear_object_start_offsets();
 }
 
 }
index 653ac2d93d150676012e6b280bc16b39085840f4..c82b88ee2f1dc703f0b7481cbfca997c0e7b8507 100644 (file)
@@ -28,6 +28,11 @@ template<typename Block, typename HeapLayout> 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<typename Block, typename HeapLayout> 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<Block,HeapLayout>::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<Block,HeapLayout>::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<Block,HeapLayout>::sweep_heap(Iterator &iter)
                        }
                }
 
-               scan = layout.next_block_after(scan);
+               scan = next_block_after(scan);
        }
 
        if(prev && prev->free_p())
index f41ae555a3fffa96743db110090c8d8442e988b1..7d8c4a2d3204b44a3b896c4f5d0d7fa2fef9fb29 100755 (executable)
@@ -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);
        }
 }
index f0dbff6c304e0ed601d2ad58c10bf6ee234a99ff..ca51fd6dca4cee515625907a4525f32239b1817a 100644 (file)
@@ -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 */
index d9c9534edb54efee15c28f5438e774462d3709be..bc318524b4f4e6cde2d7ce2abeb64495221a908c 100644 (file)
@@ -70,10 +70,15 @@ template<typename Block, typename HeapLayout> 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<cell,cell> start = bitmap_deref(address);
-               std::pair<cell,cell> end = bitmap_deref(layout.next_block_after(address));
+               std::pair<cell,cell> end = bitmap_deref(next_block_after(address));
 
                u64 start_mask = ((u64)1 << start.second) - 1;
                u64 end_mask = ((u64)1 << end.second) - 1;
index 9440749e52cca01edcfdc98a296598a7706424ec..5f992e783e5bf90a0e2ee4f0b18b82a830f8661e 100644 (file)
@@ -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;
-}
-
 }
index e59537cffb30504c673b6922a0b150a07e1e657e..640e2058527049cb769806795afa9c6071d05a3c 100644 (file)
@@ -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);
 };
 
 }
index f9f584b200d3d4fc343d0a4c105bd06802c5225f..a700b58bfd576bbefb55aed4b139865e5ee39927 100644 (file)
@@ -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;
+       }
 };
 
 }
index 2c28922fbca7927de022ac2c5b2f4cc99c6e0c78..42196f315bca839815c0f3ec299052fc0a8b807e 100644 (file)
@@ -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;
+       }
 };
 
 }