From 69cb3dee5ed1a59d7f6029568031168dd1f6f01b Mon Sep 17 00:00:00 2001 From: Slava Pestov Date: Wed, 13 May 2009 00:58:54 -0500 Subject: [PATCH] Fix FEP if there are too many words in the image, clean up some VM code --- core/memory/memory-tests.factor | 14 ++------ vm/arrays.hpp | 2 +- vm/byte_arrays.hpp | 3 +- vm/callstack.cpp | 57 +++++++++++++-------------------- vm/callstack.hpp | 20 +++++++++--- vm/code_heap.cpp | 6 ++-- vm/data_heap.cpp | 45 +++++++++++++++++++------- vm/data_heap.hpp | 1 + vm/debug.cpp | 6 ++-- vm/tagged.hpp | 0 10 files changed, 81 insertions(+), 73 deletions(-) mode change 100644 => 100755 core/memory/memory-tests.factor mode change 100644 => 100755 vm/arrays.hpp mode change 100644 => 100755 vm/byte_arrays.hpp mode change 100644 => 100755 vm/data_heap.hpp mode change 100644 => 100755 vm/tagged.hpp diff --git a/core/memory/memory-tests.factor b/core/memory/memory-tests.factor old mode 100644 new mode 100755 index a6ecdc005e..8ecf673b8a --- a/core/memory/memory-tests.factor +++ b/core/memory/memory-tests.factor @@ -27,16 +27,8 @@ TUPLE: testing x y z ; [ save-image-and-exit ] must-fail -[ ] [ - num-types get [ - type>class [ - dup . flush - "predicate" word-prop instances [ - class drop - ] each - ] when* - ] each -] unit-test - ! Erg's bug 2 [ [ [ 3 throw ] instances ] must-fail ] times + +! Bug found on Windows build box, having too many words in the image breaks 'become' +[ ] [ 100000 [ f f ] replicate { } { } become drop ] unit-test diff --git a/vm/arrays.hpp b/vm/arrays.hpp old mode 100644 new mode 100755 index 82da3bb71d..06e6ed6e4d --- a/vm/arrays.hpp +++ b/vm/arrays.hpp @@ -34,7 +34,7 @@ struct growable_array { cell count; gc_root elements; - growable_array() : count(0), elements(allot_array(2,F)) {} + growable_array(cell capacity = 10) : count(0), elements(allot_array(capacity,F)) {} void add(cell elt); void trim(); diff --git a/vm/byte_arrays.hpp b/vm/byte_arrays.hpp old mode 100644 new mode 100755 index ebdc6bead6..6de8ee4e9f --- a/vm/byte_arrays.hpp +++ b/vm/byte_arrays.hpp @@ -7,12 +7,11 @@ PRIMITIVE(byte_array); PRIMITIVE(uninitialized_byte_array); PRIMITIVE(resize_byte_array); -/* Macros to simulate a byte vector in C */ struct growable_byte_array { cell count; gc_root elements; - growable_byte_array() : count(0), elements(allot_byte_array(2)) { } + growable_byte_array(cell capacity = 40) : count(0), elements(allot_byte_array(capacity)) { } void append_bytes(void *elts, cell len); void append_byte_array(cell elts); diff --git a/vm/callstack.cpp b/vm/callstack.cpp index e7009183e9..4ef6db10bd 100755 --- a/vm/callstack.cpp +++ b/vm/callstack.cpp @@ -11,22 +11,6 @@ static void check_frame(stack_frame *frame) #endif } -void iterate_callstack(cell top, cell bottom, CALLSTACK_ITER iterator) -{ - stack_frame *frame = (stack_frame *)bottom - 1; - - while((cell)frame >= top) - { - iterator(frame); - frame = frame_successor(frame); - } -} - -void iterate_callstack_object(callstack *stack, CALLSTACK_ITER iterator) -{ - iterate_callstack((cell)stack->top(),(cell)stack->bottom(),iterator); -} - callstack *allot_callstack(cell size) { callstack *stack = allot(callstack_size(size)); @@ -138,36 +122,39 @@ cell frame_scan(stack_frame *frame) return F; } -/* C doesn't have closures... */ -static cell frame_count; - -void count_stack_frame(stack_frame *frame) +namespace { - frame_count += 2; -} -static cell frame_index; -static array *frames; +struct stack_frame_counter { + cell count; + stack_frame_counter() : count(0) {} + void operator()(stack_frame *frame) { count += 2; } +}; + +struct stack_frame_accumulator { + cell index; + array *frames; + stack_frame_accumulator(cell count) : index(0), frames(allot_array_internal(count)) {} + void operator()(stack_frame *frame) + { + set_array_nth(frames,index++,frame_executing(frame)); + set_array_nth(frames,index++,frame_scan(frame)); + } +}; -void stack_frame_to_array(stack_frame *frame) -{ - set_array_nth(frames,frame_index++,frame_executing(frame)); - set_array_nth(frames,frame_index++,frame_scan(frame)); } PRIMITIVE(callstack_to_array) { gc_root callstack(dpop()); - frame_count = 0; - iterate_callstack_object(callstack.untagged(),count_stack_frame); - - frames = allot_array_internal(frame_count); + stack_frame_counter counter; + iterate_callstack_object(callstack.untagged(),counter); - frame_index = 0; - iterate_callstack_object(callstack.untagged(),stack_frame_to_array); + stack_frame_accumulator accum(counter.count); + iterate_callstack_object(callstack.untagged(),accum); - dpush(tag(frames)); + dpush(tag(accum.frames)); } stack_frame *innermost_stack_frame(callstack *stack) diff --git a/vm/callstack.hpp b/vm/callstack.hpp index a128cfee47..d92e5f69e0 100755 --- a/vm/callstack.hpp +++ b/vm/callstack.hpp @@ -6,11 +6,7 @@ inline static cell callstack_size(cell size) return sizeof(callstack) + size; } -typedef void (*CALLSTACK_ITER)(stack_frame *frame); - stack_frame *fix_callstack_top(stack_frame *top, stack_frame *bottom); -void iterate_callstack(cell top, cell bottom, CALLSTACK_ITER iterator); -void iterate_callstack_object(callstack *stack, CALLSTACK_ITER iterator); stack_frame *frame_successor(stack_frame *frame); code_block *frame_code(stack_frame *frame); cell frame_executing(stack_frame *frame); @@ -26,4 +22,20 @@ PRIMITIVE(set_innermost_stack_frame_quot); VM_ASM_API void save_callstack_bottom(stack_frame *callstack_bottom); +template void iterate_callstack(cell top, cell bottom, T &iterator) +{ + stack_frame *frame = (stack_frame *)bottom - 1; + + while((cell)frame >= top) + { + iterator(frame); + frame = frame_successor(frame); + } +} + +template void iterate_callstack_object(callstack *stack, T &iterator) +{ + iterate_callstack((cell)stack->top(),(cell)stack->bottom(),iterator); +} + } diff --git a/vm/code_heap.cpp b/vm/code_heap.cpp index 2260d133fc..2d2e975fb4 100755 --- a/vm/code_heap.cpp +++ b/vm/code_heap.cpp @@ -173,8 +173,7 @@ void forward_object_xts() } } - /* End the heap scan */ - gc_off = false; + end_scan(); } /* Set the XT fields now that the heap has been compacted */ @@ -203,8 +202,7 @@ void fixup_object_xts() } } - /* End the heap scan */ - gc_off = false; + end_scan(); } /* Move all free space to the end of the code heap. This is not very efficient, diff --git a/vm/data_heap.cpp b/vm/data_heap.cpp index d921d373da..5b20ec890f 100755 --- a/vm/data_heap.cpp +++ b/vm/data_heap.cpp @@ -318,6 +318,11 @@ void begin_scan() gc_off = true; } +void end_scan() +{ + gc_off = false; +} + PRIMITIVE(begin_scan) { begin_scan(); @@ -348,24 +353,40 @@ PRIMITIVE(end_scan) gc_off = false; } -cell find_all_words() +template void each_object(T &functor) { - growable_array words; - begin_scan(); - cell obj; while((obj = next_object()) != F) - { - if(tagged(obj).type_p(WORD_TYPE)) - words.add(obj); - } + functor(tagged(obj)); + end_scan(); +} - /* End heap scan */ - gc_off = false; +namespace +{ + +struct word_counter { + cell count; + word_counter() : count(0) {} + void operator()(tagged obj) { if(obj.type_p(WORD_TYPE)) count++; } +}; + +struct word_accumulator { + growable_array words; + word_accumulator(int count) : words(count) {} + void operator()(tagged obj) { if(obj.type_p(WORD_TYPE)) words.add(obj.value()); } +}; + +} - words.trim(); - return words.elements.value(); +cell find_all_words() +{ + word_counter counter; + each_object(counter); + word_accumulator accum(counter.count); + each_object(accum); + accum.words.trim(); + return accum.words.elements.value(); } } diff --git a/vm/data_heap.hpp b/vm/data_heap.hpp old mode 100644 new mode 100755 index 567c8f9944..4ef72a6fcb --- a/vm/data_heap.hpp +++ b/vm/data_heap.hpp @@ -89,6 +89,7 @@ cell binary_payload_start(object *pointer); cell object_size(cell tagged); void begin_scan(); +void end_scan(); cell next_object(); PRIMITIVE(data_room); diff --git a/vm/debug.cpp b/vm/debug.cpp index 49fdd92541..22e92809a7 100755 --- a/vm/debug.cpp +++ b/vm/debug.cpp @@ -253,8 +253,7 @@ void dump_objects(cell type) } } - /* end scan */ - gc_off = false; + end_scan(); } cell look_for; @@ -280,8 +279,7 @@ void find_data_references(cell look_for_) while((obj = next_object()) != F) do_slots(UNTAG(obj),find_data_references_step); - /* end scan */ - gc_off = false; + end_scan(); } /* Dump all code blocks for debugging */ diff --git a/vm/tagged.hpp b/vm/tagged.hpp old mode 100644 new mode 100755 -- 2.34.1