vm: make a new old_space type to encapsulate a few things, split up generations array somewhat

db4
Slava Pestov 2009-10-07 14:05:09 -05:00
parent 651a7fb6fa
commit 23e133e383
13 changed files with 115 additions and 112 deletions

View File

@ -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)

View File

@ -76,19 +76,20 @@ template<typename Strategy> object *factor_vm::promote_object(object *untagged,
return newpointer;
}
template<typename Strategy> void factor_vm::trace_card(card *ptr, cell here, Strategy &strategy)
template<typename Strategy> 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<typename Strategy> void factor_vm::trace_card_deck(card_deck *deck, cell here, card mask, card unmask, Strategy &strategy)
template<typename Strategy> 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<typename Strategy> 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<typename Strategy> void factor_vm::trace_card_deck(card_deck *deck, cel
}
/* Trace all objects referenced from marked cards */
template<typename Strategy> void factor_vm::trace_cards(cell gen, zone *z, Strategy &strategy)
template<typename Strategy> void factor_vm::trace_cards(cell gen, old_space *z, Strategy &strategy)
{
u64 start_time = current_micros();
@ -179,7 +180,7 @@ template<typename Strategy> 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<typename Strategy>
copying_collector<Strategy>::copying_collector(factor_vm *myvm_, zone *newspace_)
: myvm(myvm_), current_gc(myvm_->current_gc), newspace(newspace_)
copying_collector<Strategy>::copying_collector(factor_vm *myvm_, old_space *target_)
: myvm(myvm_), current_gc(myvm_->current_gc), target(target_)
{
scan = newspace->here;
scan = target->here;
}
template<typename Strategy> Strategy &copying_collector<Strategy>::strategy()
@ -411,14 +412,7 @@ template<typename Strategy> Strategy &copying_collector<Strategy>::strategy()
template<typename Strategy> object *copying_collector<Strategy>::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<typename Strategy> object *copying_collector<Strategy>::copy_object(object *untagged)
@ -440,13 +434,13 @@ template<typename Strategy> cell copying_collector<Strategy>::trace_next(cell sc
template<typename Strategy> void copying_collector<Strategy>::go()
{
strategy().copy_reachable_objects(scan,&newspace->here);
strategy().copy_reachable_objects(scan,&target->here);
}
struct nursery_collector : copying_collector<nursery_collector>
{
explicit nursery_collector(factor_vm *myvm_, zone *newspace_) :
copying_collector<nursery_collector>(myvm_,newspace_) {}
explicit nursery_collector(factor_vm *myvm_, old_space *target_) :
copying_collector<nursery_collector>(myvm_,target_) {}
bool should_copy_p(object *untagged)
{
@ -463,13 +457,13 @@ struct aging_collector : copying_collector<aging_collector>
{
zone *tenured;
explicit aging_collector(factor_vm *myvm_, zone *newspace_) :
copying_collector<aging_collector>(myvm_,newspace_),
explicit aging_collector(factor_vm *myvm_, old_space *target_) :
copying_collector<aging_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<aging_collector>
struct aging_again_collector : copying_collector<aging_again_collector>
{
explicit aging_again_collector(factor_vm *myvm_, zone *newspace_) :
copying_collector<aging_again_collector>(myvm_,newspace_) {}
explicit aging_again_collector(factor_vm *myvm_, old_space *target_) :
copying_collector<aging_again_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<aging_again_collector>
struct tenured_collector : copying_collector<tenured_collector>
{
explicit tenured_collector(factor_vm *myvm_, zone *newspace_) :
copying_collector<tenured_collector>(myvm_,newspace_) {}
explicit tenured_collector(factor_vm *myvm_, old_space *target_) :
copying_collector<tenured_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

View File

@ -66,10 +66,10 @@ struct gc_state {
template<typename Strategy> 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);

View File

@ -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_)

View File

@ -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;

View File

@ -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);
}
}

View File

@ -1,5 +0,0 @@
#include "master.hpp"
namespace factor
{
}

View File

@ -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"

62
vm/old_space.hpp Normal file
View File

@ -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;
} */
};
}

View File

@ -4,6 +4,7 @@ namespace factor
{
factor_vm::factor_vm() :
nursery(0,0),
profiling_p(false),
secure_gc(false),
gc_off(false),

View File

@ -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<typename Strategy> object *resolve_forwarding(object *untagged, Strategy &strategy);
template<typename Strategy> void trace_handle(cell *handle, Strategy &strategy);
template<typename Strategy> object *promote_object(object *pointer, Strategy &strategy);
template<typename Strategy> void trace_slots(object *ptr, Strategy &strategy);
template<typename Strategy> void trace_card(card *ptr, cell here, Strategy &strategy);
template<typename Strategy> void trace_card_deck(card_deck *deck, cell here, card mask, card unmask, Strategy &strategy);
template<typename Strategy> void trace_cards(cell gen, zone *z, Strategy &strategy);
template<typename Strategy> void trace_card(card *ptr, old_space *gen, Strategy &strategy);
template<typename Strategy> void trace_card_deck(card_deck *deck, old_space *gen, card mask, card unmask, Strategy &strategy);
template<typename Strategy> void trace_cards(cell gen, old_space *z, Strategy &strategy);
template<typename Strategy> void trace_stack_elements(segment *region, cell top, Strategy &strategy);
template<typename Strategy> void trace_registered_locals(Strategy &strategy);
template<typename Strategy> void trace_registered_bignums(Strategy &strategy);

View File

@ -1,4 +0,0 @@
#include "master.hpp"
using namespace factor;