diff --git a/Makefile b/Makefile index dd2e83985e..4c50787f2d 100755 --- a/Makefile +++ b/Makefile @@ -51,7 +51,6 @@ DLL_OBJS = $(PLAF_DLL_OBJS) \ vm/inline_cache.o \ vm/io.o \ vm/jit.o \ - vm/local_roots.o \ vm/math.o \ vm/primitives.o \ vm/profiler.o \ @@ -61,8 +60,7 @@ DLL_OBJS = $(PLAF_DLL_OBJS) \ vm/tuples.o \ vm/utilities.o \ vm/vm.o \ - vm/words.o \ - vm/write_barrier.o + vm/words.o EXE_OBJS = $(PLAF_EXE_OBJS) diff --git a/vm/data_gc.cpp b/vm/data_gc.cpp index b3836e4a3b..dfe5ef3365 100755 --- a/vm/data_gc.cpp +++ b/vm/data_gc.cpp @@ -76,19 +76,20 @@ template object *factor_vm::promote_object(object *untagged, return newpointer; } -template void factor_vm::trace_card(card *ptr, cell here, Strategy &strategy) +template void factor_vm::trace_card(card *ptr, old_space *gen, Strategy &strategy) { - cell card_scan = card_to_addr(ptr) + card_offset(ptr); + cell card_start = card_to_addr(ptr); + cell card_scan = card_start + gen->card_offset(card_start); cell card_end = card_to_addr(ptr + 1); - if(here < card_end) card_end = here; + if(gen->here < card_end) card_end = gen->here; strategy.copy_reachable_objects(card_scan,&card_end); gc_stats.cards_scanned++; } -template void factor_vm::trace_card_deck(card_deck *deck, cell here, card mask, card unmask, Strategy &strategy) +template void factor_vm::trace_card_deck(card_deck *deck, old_space *gen, card mask, card unmask, Strategy &strategy) { card *first_card = deck_to_card(deck); card *last_card = deck_to_card(deck + 1); @@ -107,7 +108,7 @@ template void factor_vm::trace_card_deck(card_deck *deck, cel { if(ptr[card] & mask) { - trace_card(&ptr[card],here,strategy); + trace_card(&ptr[card],gen,strategy); ptr[card] &= ~unmask; } } @@ -118,7 +119,7 @@ template void factor_vm::trace_card_deck(card_deck *deck, cel } /* Trace all objects referenced from marked cards */ -template void factor_vm::trace_cards(cell gen, zone *z, Strategy &strategy) +template void factor_vm::trace_cards(cell gen, old_space *z, Strategy &strategy) { u64 start_time = current_micros(); @@ -179,7 +180,7 @@ template void factor_vm::trace_cards(cell gen, zone *z, Strat { if(*ptr & mask) { - trace_card_deck(ptr,z->here,mask,unmask,strategy); + trace_card_deck(ptr,z,mask,unmask,strategy); *ptr &= ~unmask; } } @@ -398,10 +399,10 @@ void factor_vm::update_dirty_code_blocks() } template -copying_collector::copying_collector(factor_vm *myvm_, zone *newspace_) -: myvm(myvm_), current_gc(myvm_->current_gc), newspace(newspace_) +copying_collector::copying_collector(factor_vm *myvm_, old_space *target_) +: myvm(myvm_), current_gc(myvm_->current_gc), target(target_) { - scan = newspace->here; + scan = target->here; } template Strategy ©ing_collector::strategy() @@ -411,14 +412,7 @@ template Strategy ©ing_collector::strategy() template object *copying_collector::allot(cell size) { - if(newspace->here + size <= newspace->end) - { - object *obj = newspace->allot(size); - myvm->allot_barrier(obj); - return obj; - } - else - return NULL; + return target->allot(size); } template object *copying_collector::copy_object(object *untagged) @@ -440,13 +434,13 @@ template cell copying_collector::trace_next(cell sc template void copying_collector::go() { - strategy().copy_reachable_objects(scan,&newspace->here); + strategy().copy_reachable_objects(scan,&target->here); } struct nursery_collector : copying_collector { - explicit nursery_collector(factor_vm *myvm_, zone *newspace_) : - copying_collector(myvm_,newspace_) {} + explicit nursery_collector(factor_vm *myvm_, old_space *target_) : + copying_collector(myvm_,target_) {} bool should_copy_p(object *untagged) { @@ -463,13 +457,13 @@ struct aging_collector : copying_collector { zone *tenured; - explicit aging_collector(factor_vm *myvm_, zone *newspace_) : - copying_collector(myvm_,newspace_), + explicit aging_collector(factor_vm *myvm_, old_space *target_) : + copying_collector(myvm_,target_), tenured(myvm->data->tenured) {} bool should_copy_p(object *untagged) { - if(newspace->contains_p(untagged)) + if(target->contains_p(untagged)) return false; else return !tenured->contains_p(untagged); @@ -483,12 +477,12 @@ struct aging_collector : copying_collector struct aging_again_collector : copying_collector { - explicit aging_again_collector(factor_vm *myvm_, zone *newspace_) : - copying_collector(myvm_,newspace_) {} + explicit aging_again_collector(factor_vm *myvm_, old_space *target_) : + copying_collector(myvm_,target_) {} bool should_copy_p(object *untagged) { - return !newspace->contains_p(untagged); + return !target->contains_p(untagged); } void copy_reachable_objects(cell scan, cell *end) @@ -499,12 +493,12 @@ struct aging_again_collector : copying_collector struct tenured_collector : copying_collector { - explicit tenured_collector(factor_vm *myvm_, zone *newspace_) : - copying_collector(myvm_,newspace_) {} + explicit tenured_collector(factor_vm *myvm_, old_space *target_) : + copying_collector(myvm_,target_) {} bool should_copy_p(object *untagged) { - return !newspace->contains_p(untagged); + return !target->contains_p(untagged); } void copy_reachable_objects(cell scan, cell *end) @@ -791,7 +785,6 @@ object *factor_vm::allot_object(header header, cell size) garbage_collection(tenured_gen,true,true,size); obj = data->tenured->allot(size); - allot_barrier(obj); /* Allows initialization code to store old->new pointers without hitting the write barrier in the common case of diff --git a/vm/data_gc.hpp b/vm/data_gc.hpp index 68aab2f6b3..9032f6696d 100755 --- a/vm/data_gc.hpp +++ b/vm/data_gc.hpp @@ -66,10 +66,10 @@ struct gc_state { template struct copying_collector { factor_vm *myvm; gc_state *current_gc; - zone *newspace; + old_space *target; cell scan; - explicit copying_collector(factor_vm *myvm_, zone *newspace); + explicit copying_collector(factor_vm *myvm_, old_space *target); Strategy &strategy(); object *allot(cell size); cell trace_next(cell scan); diff --git a/vm/data_heap.cpp b/vm/data_heap.cpp index 4fc9770c55..7e358cb2f9 100755 --- a/vm/data_heap.cpp +++ b/vm/data_heap.cpp @@ -6,7 +6,6 @@ namespace factor void factor_vm::init_card_decks() { cell start = align(data->seg->start,deck_size); - allot_markers_offset = (cell)data->allot_markers - (start >> card_bits); cards_offset = (cell)data->cards - (start >> card_bits); decks_offset = (cell)data->decks - (start >> deck_bits); } @@ -36,26 +35,17 @@ data_heap::data_heap(factor_vm *myvm, cell young_size_, cell aging_size_, cell t decks = new char[decks_size]; decks_end = decks + decks_size; - allot_markers = new char[cards_size]; - allot_markers_end = allot_markers + cards_size; + cell start = align(seg->start,deck_size); - cell alloter = align(seg->start,deck_size); + tenured = new old_space(tenured_size,start); + tenured_semispace = new old_space(tenured_size,tenured->end); - tenured = new zone; - tenured_semispace = new zone; - alloter = tenured->init_zone(tenured_size,alloter); - alloter = tenured_semispace->init_zone(tenured_size,alloter); + aging = new old_space(aging_size,tenured_semispace->end); + aging_semispace = new old_space(aging_size,aging->end); - aging = new zone; - aging_semispace = new zone; - alloter = aging->init_zone(aging_size,alloter); - alloter = aging_semispace->init_zone(aging_size,alloter); + nursery = new zone(young_size,aging_semispace->end); - nursery = new zone; - alloter = nursery->init_zone(young_size,alloter); - - if(seg->end - alloter > deck_size) - critical_error("Bug in alloc_data_heap",alloter); + assert(seg->end - nursery->end <= deck_size); } data_heap::~data_heap() @@ -66,7 +56,6 @@ data_heap::~data_heap() delete aging_semispace; delete tenured; delete tenured_semispace; - delete[] allot_markers; delete[] cards; delete[] decks; } @@ -81,7 +70,7 @@ data_heap *factor_vm::grow_data_heap(data_heap *data, cell requested_bytes) new_tenured_size); } -void factor_vm::clear_cards(zone *gen) +void factor_vm::clear_cards(old_space *gen) { /* NOTE: reverse order due to heap layout. */ card *first_card = addr_to_card(gen->start); @@ -89,7 +78,7 @@ void factor_vm::clear_cards(zone *gen) memset(first_card,0,last_card - first_card); } -void factor_vm::clear_decks(zone *gen) +void factor_vm::clear_decks(old_space *gen) { /* NOTE: reverse order due to heap layout. */ card_deck *first_deck = addr_to_deck(gen->start); @@ -97,23 +86,16 @@ void factor_vm::clear_decks(zone *gen) memset(first_deck,0,last_deck - first_deck); } -void factor_vm::clear_allot_markers(zone *gen) -{ - card *first_card = addr_to_allot_marker((object *)gen->start); - card *last_card = addr_to_allot_marker((object *)gen->end); - memset(first_card,invalid_allot_marker,last_card - first_card); -} - /* After garbage collection, any generations which are now empty need to have their allocation pointers and cards reset. */ -void factor_vm::reset_generation(zone *gen) +void factor_vm::reset_generation(old_space *gen) { gen->here = gen->start; if(secure_gc) memset((void*)gen->start,69,gen->size); clear_cards(gen); clear_decks(gen); - clear_allot_markers(gen); + gen->clear_allot_markers(); } void factor_vm::set_data_heap(data_heap *data_) diff --git a/vm/data_heap.hpp b/vm/data_heap.hpp index 891d1361ed..3f620e3d42 100755 --- a/vm/data_heap.hpp +++ b/vm/data_heap.hpp @@ -9,13 +9,10 @@ struct data_heap { segment *seg; zone *nursery; - zone *aging; - zone *aging_semispace; - zone *tenured; - zone *tenured_semispace; - - char *allot_markers; - char *allot_markers_end; + old_space *aging; + old_space *aging_semispace; + old_space *tenured; + old_space *tenured_semispace; char *cards; char *cards_end; diff --git a/vm/image.cpp b/vm/image.cpp index 9a70937508..272309063b 100755 --- a/vm/image.cpp +++ b/vm/image.cpp @@ -280,7 +280,7 @@ void factor_vm::relocate_data() relocating += untagged_object_size((object *)relocating)) { object *obj = (object *)relocating; - allot_barrier(obj); + data->tenured->record_allocation(obj); relocate_object(obj); } } diff --git a/vm/local_roots.cpp b/vm/local_roots.cpp deleted file mode 100644 index 71baee6deb..0000000000 --- a/vm/local_roots.cpp +++ /dev/null @@ -1,5 +0,0 @@ -#include "master.hpp" - -namespace factor -{ -} diff --git a/vm/master.hpp b/vm/master.hpp index d942c1a3ac..97e9ed4a8b 100755 --- a/vm/master.hpp +++ b/vm/master.hpp @@ -69,9 +69,10 @@ namespace factor #include "bignumint.hpp" #include "bignum.hpp" #include "code_block.hpp" -#include "gc/zone.hpp" -#include "data_heap.hpp" +#include "zone.hpp" #include "write_barrier.hpp" +#include "old_space.hpp" +#include "data_heap.hpp" #include "data_gc.hpp" #include "debug.hpp" #include "strings.hpp" diff --git a/vm/old_space.hpp b/vm/old_space.hpp new file mode 100644 index 0000000000..598c1f4090 --- /dev/null +++ b/vm/old_space.hpp @@ -0,0 +1,62 @@ +namespace factor +{ + +struct old_space : zone { + card *allot_markers; + card *allot_markers_end; + + old_space(cell size_, cell start_) : zone(size_,start_) + { + cell cards_size = size_ >> card_bits; + allot_markers = new card[cards_size]; + allot_markers_end = allot_markers + cards_size; + } + + ~old_space() + { + delete[] allot_markers; + } + + card *addr_to_allot_marker(object *a) + { + return (card *)((((cell)a - start) >> card_bits) + (cell)allot_markers); + } + + /* we need to remember the first object allocated in the card */ + void record_allocation(object *obj) + { + card *ptr = addr_to_allot_marker(obj); + if(*ptr == invalid_allot_marker) + *ptr = ((cell)obj & addr_card_mask); + } + + cell card_offset(cell address) + { + return allot_markers[(address - start) >> card_bits]; + } + + object *allot(cell size) + { + if(here + size > end) return NULL; + + object *obj = zone::allot(size); + record_allocation(obj); + return obj; + } + + void clear_allot_markers() + { + memset(allot_markers,invalid_allot_marker,size >> card_bits); + } + + /* object *next_object_after(object *ptr) + { + cell size = untagged_object_size(ptr); + if((cell)ptr + size < end) + return (object *)((cell)ptr + size); + else + return NULL; + } */ +}; + +} diff --git a/vm/vm.cpp b/vm/vm.cpp index 15df6cc18a..50dc441086 100755 --- a/vm/vm.cpp +++ b/vm/vm.cpp @@ -4,6 +4,7 @@ namespace factor { factor_vm::factor_vm() : + nursery(0,0), profiling_p(false), secure_gc(false), gc_off(false), diff --git a/vm/vm.hpp b/vm/vm.hpp index 9836342fe2..02ab128969 100755 --- a/vm/vm.hpp +++ b/vm/vm.hpp @@ -53,9 +53,6 @@ struct factor_vm /* Code heap */ code_heap *code; - /* Where we store object start offsets in cards */ - cell allot_markers_offset; - /* Only set if we're performing a GC */ gc_state *current_gc; @@ -211,10 +208,9 @@ struct factor_vm //data_heap void init_card_decks(); data_heap *grow_data_heap(data_heap *data, cell requested_bytes); - void clear_cards(zone *gen); - void clear_decks(zone *gen); - void clear_allot_markers(zone *gen); - void reset_generation(zone *gen); + void clear_cards(old_space *gen); + void clear_decks(old_space *gen); + void reset_generation(old_space *gen); void set_data_heap(data_heap *data_); void init_data_heap(cell young_size, cell aging_size, cell tenured_size, bool secure_gc_); cell untagged_object_size(object *pointer); @@ -243,11 +239,6 @@ struct factor_vm return ((cell)c - cards_offset) << card_bits; } - inline cell card_offset(card *c) - { - return *(c - (cell)data->cards + (cell)data->allot_markers); - } - inline card_deck *addr_to_deck(cell a) { return (card_deck *)(((cell)a >> deck_bits) + decks_offset); @@ -263,11 +254,6 @@ struct factor_vm return (card *)((((cell)d - decks_offset) << (deck_bits - card_bits)) + cards_offset); } - inline card *addr_to_allot_marker(object *a) - { - return (card *)(((cell)a >> card_bits) + allot_markers_offset); - } - /* the write barrier must be called any time we are potentially storing a pointer from an older generation to a younger one */ inline void write_barrier(object *obj) @@ -276,22 +262,14 @@ struct factor_vm *addr_to_deck((cell)obj) = card_mark_mask; } - /* we need to remember the first object allocated in the card */ - inline void allot_barrier(object *address) - { - card *ptr = addr_to_allot_marker(address); - if(*ptr == invalid_allot_marker) - *ptr = ((cell)address & addr_card_mask); - } - // data_gc template object *resolve_forwarding(object *untagged, Strategy &strategy); template void trace_handle(cell *handle, Strategy &strategy); template object *promote_object(object *pointer, Strategy &strategy); template void trace_slots(object *ptr, Strategy &strategy); - template void trace_card(card *ptr, cell here, Strategy &strategy); - template void trace_card_deck(card_deck *deck, cell here, card mask, card unmask, Strategy &strategy); - template void trace_cards(cell gen, zone *z, Strategy &strategy); + template void trace_card(card *ptr, old_space *gen, Strategy &strategy); + template void trace_card_deck(card_deck *deck, old_space *gen, card mask, card unmask, Strategy &strategy); + template void trace_cards(cell gen, old_space *z, Strategy &strategy); template void trace_stack_elements(segment *region, cell top, Strategy &strategy); template void trace_registered_locals(Strategy &strategy); template void trace_registered_bignums(Strategy &strategy); diff --git a/vm/write_barrier.cpp b/vm/write_barrier.cpp deleted file mode 100644 index 774f744a3f..0000000000 --- a/vm/write_barrier.cpp +++ /dev/null @@ -1,4 +0,0 @@ -#include "master.hpp" - -using namespace factor; - diff --git a/vm/gc/zone.hpp b/vm/zone.hpp similarity index 100% rename from vm/gc/zone.hpp rename to vm/zone.hpp