]> gitweb.factorcode.org Git - factor.git/commitdiff
vm: erase code blocks from all_blocks during sweep
authorJoe Groff <arcata@gmail.com>
Tue, 13 Dec 2011 20:28:09 +0000 (12:28 -0800)
committerJoe Groff <arcata@gmail.com>
Tue, 13 Dec 2011 20:28:09 +0000 (12:28 -0800)
Fixes #437

vm/code_heap.cpp
vm/code_heap.hpp
vm/free_list_allocator.hpp
vm/full_collector.cpp

index e15b9488b51c8a3110945ddd4444baeb8e4dff41..5f6967535aaf82ace3ce5212ed7251a6f4083624 100755 (executable)
@@ -72,6 +72,31 @@ void code_heap::flush_icache()
        factor::flush_icache(seg->start,seg->size);
 }
 
+struct clear_free_blocks_from_all_blocks_iterator
+{
+       code_heap *code;
+
+       clear_free_blocks_from_all_blocks_iterator(code_heap *code) : code(code) {}
+
+       void operator()(code_block *free_block, cell size) {
+               std::set<code_block*>::iterator erase_from =
+                       code->all_blocks.lower_bound(free_block);
+               std::set<code_block*>::iterator erase_to =
+                       code->all_blocks.lower_bound((code_block*)((char*)free_block + size));
+
+               code->all_blocks.erase(erase_from, erase_to);
+       }
+};
+
+void code_heap::sweep()
+{
+       clear_free_blocks_from_all_blocks_iterator clearer(this);
+       allocator->sweep(clearer);
+#ifdef FACTOR_DEBUG
+       verify_all_blocks_set();
+#endif
+}
+
 struct all_blocks_set_verifier {
        std::set<code_block*> *leftovers;
 
@@ -104,6 +129,11 @@ code_block *code_heap::code_block_for_address(cell address)
                && address - (cell)found_block->entry_point() < found_block->size()))
        {
                std::cerr << "invalid block found in all_blocks set!" << std::endl;
+               std::cerr << "address " << (void*)address
+                       << " block " << (void*)found_block
+                       << " entry point " << (void*)found_block->entry_point()
+                       << " size " << found_block->size()
+                       << " free? " << found_block->free_p();
                verify_all_blocks_set();
                FACTOR_ASSERT(false);
        }
index 8db96016dd5b0f8f2cbff9da429efc94f2594f3d..83b3ae586d16b2d5a584d9c5c195871f50785f79 100755 (executable)
@@ -48,6 +48,8 @@ struct code_heap {
        void verify_all_blocks_set();
        void initialize_all_blocks_set();
 
+       void sweep();
+
        code_block *code_block_for_address(cell address);
 
        bool safepoint_p(cell addr)
index ea7b5b1a5d1ded29660bc836a82a61c1a39de693..7106f7cf1355b4f85d0c1b6c4948f49a3ecedf55 100644 (file)
@@ -23,6 +23,7 @@ template<typename Block> struct free_list_allocator {
        cell largest_free_block();
        cell free_block_count();
        void sweep();
+       template<typename Iterator> void sweep(Iterator &iter);
        template<typename Iterator, typename Fixup> void compact(Iterator &iter, Fixup fixup, const Block **finger);
        template<typename Iterator, typename Fixup> void iterate(Iterator &iter, Fixup fixup);
        template<typename Iterator> void iterate(Iterator &iter);
@@ -124,7 +125,8 @@ template<typename Block> cell free_list_allocator<Block>::free_block_count()
 }
 
 template<typename Block>
-void free_list_allocator<Block>::sweep()
+template<typename Iterator>
+void free_list_allocator<Block>::sweep(Iterator &iter)
 {
        free_blocks.clear_free_list();
 
@@ -145,12 +147,26 @@ void free_list_allocator<Block>::sweep()
                        free_heap_block *free_block = (free_heap_block *)start;
                        free_block->make_free(size);
                        free_blocks.add_to_free_list(free_block);
+                       iter(start, size);
 
                        start = (Block *)((char *)start + size);
                }
        }
 }
 
+template<typename Block>
+struct null_sweep_iterator
+{
+       void operator()(Block *free_block, cell size) {}
+};
+
+template<typename Block>
+void free_list_allocator<Block>::sweep()
+{
+       null_sweep_iterator<Block> none;
+       sweep(none);
+}
+
 template<typename Block, typename Iterator> struct heap_compactor {
        mark_bits<Block> *state;
        char *address;
index f53760cecafa7a5e1067cb4ed08b8233707aa22d..fad855301ea991f9e59f640d0abdf327ba21bcbf 100644 (file)
@@ -101,7 +101,7 @@ void factor_vm::collect_sweep_impl()
        update_code_roots_for_sweep();
 
        if(event) event->started_code_sweep();
-       code->allocator->sweep();
+       code->sweep();
        if(event) event->ended_code_sweep();
 }