]> gitweb.factorcode.org Git - factor.git/commitdiff
vm: clean up gc events, remove -verbosegc switch, fix compaction bug
authorSlava Pestov <slava@slava-pestovs-macbook-pro.local>
Wed, 28 Oct 2009 02:31:28 +0000 (21:31 -0500)
committerSlava Pestov <slava@slava-pestovs-macbook-pro.local>
Wed, 28 Oct 2009 02:31:28 +0000 (21:31 -0500)
16 files changed:
basis/tools/memory/memory.factor
basis/vm/vm.factor
vm/byte_arrays.hpp
vm/code_heap.cpp
vm/compaction.cpp
vm/data_heap.cpp
vm/factor.cpp
vm/free_list.cpp
vm/free_list_allocator.hpp
vm/gc.cpp
vm/gc.hpp
vm/image.hpp
vm/mark_bits.hpp
vm/master.hpp
vm/tenured_space.hpp
vm/vm.hpp

index 446f04715023c66fbbfe83d9e5a27094a6c85823..6d0c4b7c86b90a49c22afc434553c3389bb802db 100644 (file)
@@ -10,10 +10,15 @@ IN: tools.memory
 
 <PRIVATE
 
+: commas ( n -- str )
+    number>string
+    reverse 3 group "," join reverse ;
+
 : kilobytes ( n -- str )
-    1024 /i number>string
-    dup length 4 > [ 3 cut* "," glue ] when
-    " KB" append ;
+    1024 /i commas " KB" append ;
+
+: micros>string ( n -- str )
+    commas " microseconds" append ;
 
 : fancy-table. ( obj alist -- )
     [ [ nip first ] [ second call( obj -- str ) ] 2bi 2array ] with map
@@ -97,50 +102,23 @@ PRIVATE>
     enable-gc-events [ ] [ disable-gc-events drop ] cleanup
     disable-gc-events byte-array>gc-event-array ; inline
 
-: generation-sizes-before ( events -- sizes )
-    [
-        {
-            [ start-time>> ]
-            [ nursery-size-before>> ]
-            [ aging-size-before>> ]
-            [ tenured-size-before>> ]
-            [ code-size-before>> ]
-        } cleave 5 narray
-    ] { } map-as ;
-
-: generation-sizes-after ( events -- sizes )
-    [
-        {
-            [ start-time>> ]
-            [ nursery-size-after>> ]
-            [ aging-size-after>> ]
-            [ tenured-size-after>> ]
-            [ code-size-after>> ]
-        } cleave 5 narray
-    ] { } map-as ;
-
-: reclaimed-space ( events -- sizes )
-    [
-        [ start-time>> ] [
-            {
-                [ [ nursery-size-before>> ] [ nursery-size-after>> ] bi - ]
-                [ [   aging-size-before>> ] [   aging-size-after>> ] bi - ]
-                [ [ tenured-size-before>> ] [ tenured-size-after>> ] bi - ]
-                [ [    code-size-before>> ] [    code-size-after>> ] bi - ]
-            } cleave
-            + + +
-        ] bi 2array
-    ] { } map-as ;
-
-: allocated-space ( events -- sizes )
-    2 <sliced-clumps> [
-        [ second start-time>> ] [
-            {
-                [ [ second nursery-size-before>> ] [ first nursery-size-after>> ] bi - ]
-                [ [ second   aging-size-before>> ] [ first   aging-size-after>> ] bi - ]
-                [ [ second tenured-size-before>> ] [ first tenured-size-after>> ] bi - ]
-                [ [ second    code-size-before>> ] [ first    code-size-after>> ] bi - ]
-            } cleave
-            + + +
-        ] bi 2array
-    ] { } map-as ;
+: gc-op-string ( op -- string )
+    {
+        { collect-nursery-op      [ "copying from nursery" ] }
+        { collect-aging-op        [ "copying from aging"   ] }
+        { collect-to-tenured-op   [ "copying to tenured"   ] }
+        { collect-full-op         [ "mark and sweep"       ] }
+        { collect-compact-op      [ "mark and compact"     ] }
+        { collect-growing-heap-op [ "grow heap"            ] }
+    } case ;
+
+: space-reclaimed ( event -- bytes )
+    [ data-heap-before>> ] [ data-heap-after>> ] bi
+    [ [ nursery>> ] [ aging>> ] [ tenured>> ] tri [ occupied>> ] tri@ + + ] bi@ - ;
+
+: gc-event. ( event -- )
+    {
+        { "Event type:" [ op>> gc-op-string ] }
+        { "Total time:" [ total-time>> micros>string ] }
+        { "Space reclaimed:" [ space-reclaimed kilobytes ] }
+    } fancy-table. ;
index 1351ed10a3b2c584b8217ae2dc67c832ed57dc5f..6bcdd2862a457a40e3e4c5de7aef1a20b2b92f6f 100644 (file)
@@ -29,31 +29,6 @@ collect-full-op
 collect-compact-op
 collect-growing-heap-op ;
 
-STRUCT: gc-event
-{ op uint }
-{ nursery-size-before cell }
-{ aging-size-before cell }
-{ tenured-size-before cell }
-{ tenured-free-block-count-before cell }
-{ code-size-before cell }
-{ code-free-block-count-before cell }
-{ nursery-size-after cell }
-{ aging-size-after cell }
-{ tenured-size-after cell }
-{ tenured-free-block-count-after cell }
-{ code-size-after cell }
-{ code-free-block-count-after cell }
-{ cards-scanned cell }
-{ decks-scanned cell }
-{ code-blocks-scanned cell }
-{ start-time ulonglong }
-{ total-time cell }
-{ card-scan-time cell }
-{ code-scan-time cell }
-{ data-sweep-time cell }
-{ code-sweep-time cell }
-{ compaction-time cell } ;
-
 STRUCT: copying-sizes
 { size cell }
 { occupied cell }
@@ -73,3 +48,20 @@ STRUCT: data-heap-room
 { cards cell }
 { decks cell }
 { mark-stack cell } ;
+
+STRUCT: gc-event
+{ op uint }
+{ data-heap-before data-heap-room }
+{ code-heap-before mark-sweep-sizes }
+{ data-heap-after data-heap-room }
+{ code-heap-after mark-sweep-sizes }
+{ cards-scanned cell }
+{ decks-scanned cell }
+{ code-blocks-scanned cell }
+{ start-time ulonglong }
+{ total-time cell }
+{ card-scan-time cell }
+{ code-scan-time cell }
+{ data-sweep-time cell }
+{ code-sweep-time cell }
+{ compaction-time cell } ;
index 93cb775b1eebb60967565b81bf74059ca2c66944..0817f7dcdcd6ca132fada7c85cf7164ddedf9fc2 100755 (executable)
@@ -13,14 +13,14 @@ struct growable_byte_array {
        void trim();
 };
 
-template<typename T> byte_array *factor_vm::byte_array_from_value(T *value)
+template<typename Type> byte_array *factor_vm::byte_array_from_value(Type *value)
 {
        return byte_array_from_values(value,1);
 }
 
-template<typename T> byte_array *factor_vm::byte_array_from_values(T *values, cell len)
+template<typename Type> byte_array *factor_vm::byte_array_from_values(Type *values, cell len)
 {
-       cell size = sizeof(T) * len;
+       cell size = sizeof(Type) * len;
        byte_array *data = allot_uninitialized_array<byte_array>(size);
        memcpy(data->data<char>(),values,size);
        return data;
index ac6669ca4900827823ee49b7ba988f7a0909f07b..77ae5180c84e5a9eef8d6d04476f4380b8d5a3d1 100755 (executable)
@@ -196,7 +196,7 @@ void factor_vm::primitive_modify_code_heap()
        update_code_heap_words();
 }
 
-void factor_vm::primitive_code_room()
+code_heap_room factor_vm::code_room()
 {
        code_heap_room room;
 
@@ -206,6 +206,12 @@ void factor_vm::primitive_code_room()
        room.contiguous_free  = code->allocator->free_blocks.largest_free_block();
        room.free_block_count = code->allocator->free_blocks.free_block_count;
 
+       return room;
+}
+
+void factor_vm::primitive_code_room()
+{
+       code_heap_room room = code_room();
        dpush(tag<byte_array>(byte_array_from_value(&room)));
 }
 
index 4540560ac44e05e363b4fa758254027daf81dce5..bda803585898776e430edc62a6607940fd2a5b8c 100644 (file)
@@ -55,10 +55,12 @@ struct compaction_sizer {
 
        cell operator()(object *obj)
        {
-               if(obj->free_p() || obj->h.hi_tag() != TUPLE_TYPE)
-                       return obj->size();
-               else
+               if(!forwarding_map->marked_p(obj))
+                       return forwarding_map->unmarked_space_starting_at(obj);
+               else if(obj->h.hi_tag() == TUPLE_TYPE)
                        return align(tuple_size_with_forwarding(forwarding_map,obj),data_alignment);
+               else
+                       return obj->size();
        }
 };
 
index 8f8db699f64000d7526e96e54b64b85e988974d8..b38674fe1f833dcba33a84cbbf255ec188f4acf3 100755 (executable)
@@ -201,7 +201,7 @@ void factor_vm::primitive_size()
        box_unsigned_cell(object_size(dpop()));
 }
 
-void factor_vm::primitive_data_room()
+data_heap_room factor_vm::data_room()
 {
        data_heap_room room;
 
@@ -220,6 +220,12 @@ void factor_vm::primitive_data_room()
        room.decks                    = data->decks_end - data->decks;
        room.mark_stack               = data->tenured->mark_stack.capacity();
 
+       return room;
+}
+
+void factor_vm::primitive_data_room()
+{
+       data_heap_room room = data_room();
        dpush(tag<byte_array>(byte_array_from_value(&room)));
 }
 
index 6a235ec88de711b9819c3c563e034a85d982b832..510900a0361cc5b3ce8849a63af5396e2c027c86 100755 (executable)
@@ -38,7 +38,6 @@ void factor_vm::default_parameters(vm_parameters *p)
        p->max_pic_size = 3;
 
        p->fep = false;
-       p->verbose_gc = false;
        p->signals = true;
 
 #ifdef WINDOWS
@@ -87,7 +86,6 @@ void factor_vm::init_parameters_from_args(vm_parameters *p, int argc, vm_char **
                else if(factor_arg(arg,STRING_LITERAL("-callbacks=%d"),&p->callback_size));
                else if(STRCMP(arg,STRING_LITERAL("-fep")) == 0) p->fep = true;
                else if(STRCMP(arg,STRING_LITERAL("-nosignals")) == 0) p->signals = false;
-               else if(STRCMP(arg,STRING_LITERAL("-verbosegc")) == 0) p->verbose_gc = true;
                else if(STRNCMP(arg,STRING_LITERAL("-i="),3) == 0) p->image_path = arg + 3;
                else if(STRCMP(arg,STRING_LITERAL("-console")) == 0) p->console = true;
        }
@@ -142,8 +140,6 @@ void factor_vm::init_factor(vm_parameters *p)
        if(p->signals)
                init_signals();
 
-       verbose_gc = p->verbose_gc;
-
        if(p->console)
                open_console();
 
index 24ffab9f2cd330edbf83e75b9de203c1f97fa9aa..644f62d87002e3987dc96550efce8f5ded8bea9d 100644 (file)
@@ -108,10 +108,8 @@ cell free_list::largest_free_block()
 {
        if(large_blocks.size())
        {
-               large_block_set::iterator end = large_blocks.end();
-               free_heap_block *block = *end;
-               large_blocks.erase(end);
-               return block->size();
+               large_block_set::reverse_iterator last = large_blocks.rbegin();
+               return (*last)->size();
        }
        else
        {
index d74dd5be9a88ad295f7be7c06fedc4c222056827..dad54b644dcfb499be37e89894ec80f747f23204 100644 (file)
@@ -14,6 +14,7 @@ template<typename Block> struct free_list_allocator {
        Block *first_block();
        Block *last_block();
        Block *next_block_after(Block *block);
+       Block *next_allocated_block_after(Block *block);
        bool can_allot_p(cell size);
        Block *allot(cell size);
        void free(Block *block);
@@ -58,6 +59,20 @@ template<typename Block> Block *free_list_allocator<Block>::next_block_after(Blo
        return (Block *)((cell)block + block->size());
 }
 
+template<typename Block> Block *free_list_allocator<Block>::next_allocated_block_after(Block *block)
+{
+       while(block != this->last_block() && block->free_p())
+       {
+               free_heap_block *free_block = (free_heap_block *)block;
+               block = (object *)((cell)free_block + free_block->size());
+       }
+
+       if(block == this->last_block())
+               return NULL;
+       else
+               return block;
+}
+
 template<typename Block> bool free_list_allocator<Block>::can_allot_p(cell size)
 {
        return free_blocks.can_allot_p(size);
index 0c8750ad925e650fcbd807aa6fa0f0b220f108b0..cce82989213c3fba5249ac1f446ad893a81ebbb2 100755 (executable)
--- a/vm/gc.cpp
+++ b/vm/gc.cpp
@@ -15,12 +15,8 @@ gc_event::gc_event(gc_op op_, factor_vm *parent) :
        code_sweep_time(0),
        compaction_time(0)
 {
-       nursery_size_before = parent->nursery.occupied_space();
-       aging_size_before = parent->data->aging->occupied_space();
-       tenured_size_before = parent->data->tenured->occupied_space();
-       tenured_free_block_count_before = parent->data->tenured->free_blocks.free_block_count;
-       code_size_before = parent->code->allocator->occupied_space();
-       code_free_block_count_before = parent->code->allocator->free_blocks.free_block_count;
+       data_heap_before = parent->data_room();
+       code_heap_before = parent->code_room();
        start_time = current_micros();
 }
 
@@ -79,44 +75,11 @@ void gc_event::ended_compaction()
 
 void gc_event::ended_gc(factor_vm *parent)
 {
-       nursery_size_after = parent->nursery.occupied_space();
-       aging_size_after = parent->data->aging->occupied_space();
-       tenured_size_after = parent->data->tenured->occupied_space();
-       tenured_free_block_count_after = parent->data->tenured->free_blocks.free_block_count;
-       code_size_after = parent->code->allocator->occupied_space();
-       code_free_block_count_after = parent->code->allocator->free_blocks.free_block_count;
+       data_heap_after = parent->data_room();
+       code_heap_after = parent->code_room();
        total_time = current_micros() - start_time;
 }
 
-std::ostream &operator<<(std::ostream &out, const gc_event *event)
-{
-       out << "<event\n"
-           << " op                              = '" << event->op                              << "'\n"
-           << " nursery_size_before             = '" << event->nursery_size_before             << "'\n"
-           << " aging_size_before               = '" << event->aging_size_before               << "'\n"
-           << " tenured_size_before             = '" << event->tenured_size_before             << "'\n"
-           << " tenured_free_block_count_before = '" << event->tenured_free_block_count_before << "'\n"
-           << " code_size_before                = '" << event->code_size_before                << "'\n"
-           << " code_free_block_count_before    = '" << event->code_free_block_count_before    << "'\n"
-           << " nursery_size_after              = '" << event->nursery_size_after              << "'\n"
-           << " aging_size_after                = '" << event->aging_size_after                << "'\n"
-           << " tenured_size_after              = '" << event->tenured_size_after              << "'\n"
-           << " tenured_free_block_count_after  = '" << event->tenured_free_block_count_after  << "'\n"
-           << " code_size_after                 = '" << event->code_size_after                 << "'\n"
-           << " code_free_block_count_after     = '" << event->code_free_block_count_after     << "'\n"
-           << " cards_scanned                   = '" << event->cards_scanned                   << "'\n"
-           << " decks_scanned                   = '" << event->decks_scanned                   << "'\n"
-           << " code_blocks_scanned             = '" << event->code_blocks_scanned             << "'\n"
-           << " start_time                      = '" << event->start_time                      << "'\n"
-           << " total_time                      = '" << event->total_time                      << "'\n"
-           << " card_scan_time                  = '" << event->card_scan_time                  << "'\n"
-           << " code_scan_time                  = '" << event->code_scan_time                  << "'\n"
-           << " data_sweep_time                 = '" << event->data_sweep_time                 << "'\n"
-           << " code_sweep_time                 = '" << event->code_sweep_time                 << "'\n"
-           << " compaction_time                 = '" << event->compaction_time                 << "' />";
-       return out;
-}
-
 gc_state::gc_state(gc_op op_, factor_vm *parent) : op(op_), start_time(current_micros())
 {
        event = new gc_event(op,parent);
@@ -131,7 +94,6 @@ gc_state::~gc_state()
 void factor_vm::end_gc()
 {
        current_gc->event->ended_gc(this);
-       if(verbose_gc) std::cout << current_gc->event << std::endl;
        if(gc_events) gc_events->push_back(*current_gc->event);
        delete current_gc->event;
        current_gc->event = NULL;
@@ -354,7 +316,7 @@ void factor_vm::primitive_disable_gc_events()
 {
        if(gc_events)
        {
-               byte_array *data = byte_array_from_values(&gc_events->front(),gc_events->size());
+               byte_array *data = byte_array_from_values(&gc_events->first(),gc_events->size());
                dpush(tag<byte_array>(data));
 
                delete gc_events;
index fe19f93ff1beb29696e8b091507bd7786219688f..90b5ce60322b8b81a7b8b168c7a0a34483dfdf8d 100755 (executable)
--- a/vm/gc.hpp
+++ b/vm/gc.hpp
@@ -12,18 +12,10 @@ enum gc_op {
 
 struct gc_event {
        gc_op op;
-       cell nursery_size_before;
-       cell aging_size_before;
-       cell tenured_size_before;
-       cell tenured_free_block_count_before;
-       cell code_size_before;
-       cell code_free_block_count_before;
-       cell nursery_size_after;
-       cell aging_size_after;
-       cell tenured_size_after;
-       cell tenured_free_block_count_after;
-       cell code_size_after;
-       cell code_free_block_count_after;
+       data_heap_room data_heap_before;
+       code_heap_room code_heap_before;
+       data_heap_room data_heap_after;
+       code_heap_room code_heap_after;
        cell cards_scanned;
        cell decks_scanned;
        cell code_blocks_scanned;
index f740b65f68f44d5ca25632e74d95add7d7ccb700..cca0e9e378a548d0e81cc735e276f9c14c68c7e4 100755 (executable)
@@ -35,7 +35,6 @@ struct vm_parameters {
        cell young_size, aging_size, tenured_size;
        cell code_size;
        bool fep;
-       bool verbose_gc;
        bool console;
        bool signals;
        cell max_pic_size;
index 8b6b0c75eb57a5c554cd2cde6bd9545043d85623..1b8fa913a6de8d5d6f9a26e1c9937bbb81074200 100644 (file)
@@ -154,6 +154,20 @@ template<typename Block> struct mark_bits {
 #endif
                return new_block;
        }
+
+       /* Find the next allocated block without calling size() on unmarked
+       objects. */
+       cell unmarked_space_starting_at(Block *original)
+       {
+               char *start = (char *)original;
+               char *scan = start;
+               char *end = (char *)(this->start + this->size);
+
+               while(scan != end && !marked_p((Block *)scan))
+                       scan += block_granularity;
+
+               return scan - start;
+       }
 };
 
 }
index 0873480addff31cb8108190133a4c4c83dba734f..9b525bd22e816fee0948dbda58d95c723f603f78 100755 (executable)
@@ -59,6 +59,7 @@ namespace factor
 #include "aging_space.hpp"
 #include "tenured_space.hpp"
 #include "data_heap.hpp"
+#include "code_heap.hpp"
 #include "gc.hpp"
 #include "debug.hpp"
 #include "strings.hpp"
@@ -68,7 +69,6 @@ namespace factor
 #include "io.hpp"
 #include "image.hpp"
 #include "alien.hpp"
-#include "code_heap.hpp"
 #include "callbacks.hpp"
 #include "vm.hpp"
 #include "tagged.hpp"
index 1b3baeaf52dfba74e8ac5550e831c6aec284b43f..f77f17a56a6383618fcbaa55b7aa493d223f4be1 100644 (file)
@@ -20,30 +20,16 @@ struct tenured_space : free_list_allocator<object> {
                        return NULL;
        }
 
-       object *first_allocated_block_after(object *block)
-       {
-               while(block != this->last_block() && block->free_p())
-               {
-                       free_heap_block *free_block = (free_heap_block *)block;
-                       block = (object *)((cell)free_block + free_block->size());
-               }
-
-               if(block == this->last_block())
-                       return NULL;
-               else
-                       return block;
-       }
-
        cell first_object()
        {
-               return (cell)first_allocated_block_after(this->first_block());
+               return (cell)next_allocated_block_after(this->first_block());
        }
 
        cell next_object_after(cell scan)
        {
                cell size = ((object *)scan)->size();
                object *next = (object *)(scan + size);
-               return (cell)first_allocated_block_after(next);
+               return (cell)next_allocated_block_after(next);
        }
 
        void clear_mark_bits()
index 128982fb9cc54f7f5b6c799b7f02737e912aeae5..0844b47e51f9cb84cb7cd653f76eccd4d815e6a5 100755 (executable)
--- a/vm/vm.hpp
+++ b/vm/vm.hpp
@@ -46,9 +46,6 @@ struct factor_vm
        /* GC is off during heap walking */
        bool gc_off;
 
-       /* GC logging */
-       bool verbose_gc;
-
        /* Data heap */
        data_heap *data;
 
@@ -223,6 +220,7 @@ struct factor_vm
        void set_data_heap(data_heap *data_);
        void init_data_heap(cell young_size, cell aging_size, cell tenured_size);
        void primitive_size();
+       data_heap_room data_room();
        void primitive_data_room();
        void begin_scan();
        void end_scan();
@@ -502,6 +500,7 @@ struct factor_vm
        void update_code_heap_words_and_literals();
        void relocate_code_heap();
        void primitive_modify_code_heap();
+       code_heap_room code_room();
        void primitive_code_room();
        void primitive_strip_stack_traces();