vm/inline_cache.o \
vm/io.o \
vm/jit.o \
- vm/local_roots.o \
vm/math.o \
vm/primitives.o \
vm/profiler.o \
vm/tuples.o \
vm/utilities.o \
vm/vm.o \
- vm/words.o \
- vm/write_barrier.o
+ vm/words.o
EXE_OBJS = $(PLAF_EXE_OBJS)
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);
{
if(ptr[card] & mask)
{
- trace_card(&ptr[card],here,strategy);
+ trace_card(&ptr[card],gen,strategy);
ptr[card] &= ~unmask;
}
}
}
/* 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();
{
if(*ptr & mask)
{
- trace_card_deck(ptr,z->here,mask,unmask,strategy);
+ trace_card_deck(ptr,z,mask,unmask,strategy);
*ptr &= ~unmask;
}
}
}
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 ©ing_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)
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)
{
{
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);
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)
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)
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
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);
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);
}
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()
delete aging_semispace;
delete tenured;
delete tenured_semispace;
- delete[] allot_markers;
delete[] cards;
delete[] decks;
}
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);
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);
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_)
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;
+++ /dev/null
-namespace factor
-{
-
-struct zone {
- /* allocation pointer is 'here'; its offset is hardcoded in the
- compiler backends */
- cell start;
- cell here;
- cell size;
- cell end;
-
- cell init_zone(cell size_, cell start_)
- {
- size = size_;
- start = here = start_;
- end = start_ + size_;
- return end;
- }
-
- inline bool contains_p(object *pointer)
- {
- return ((cell)pointer - start) < size;
- }
-
- inline object *allot(cell size)
- {
- cell h = here;
- here = h + align8(size);
- return (object *)h;
- }
-};
-
-}
relocating += untagged_object_size((object *)relocating))
{
object *obj = (object *)relocating;
- allot_barrier(obj);
+ data->tenured->record_allocation(obj);
relocate_object(obj);
}
}
+++ /dev/null
-#include "master.hpp"
-
-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"
--- /dev/null
+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;
+ } */
+};
+
+}
{\r
\r
factor_vm::factor_vm() :\r
+ nursery(0,0),\r
profiling_p(false),\r
secure_gc(false),\r
gc_off(false),\r
/* 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;
//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);
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);
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)
*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);
+++ /dev/null
-#include "master.hpp"
-
-using namespace factor;
-
--- /dev/null
+namespace factor
+{
+
+struct zone {
+ /* allocation pointer is 'here'; its offset is hardcoded in the
+ compiler backends */
+ cell start;
+ cell here;
+ cell size;
+ cell end;
+
+ cell init_zone(cell size_, cell start_)
+ {
+ size = size_;
+ start = here = start_;
+ end = start_ + size_;
+ return end;
+ }
+
+ inline bool contains_p(object *pointer)
+ {
+ return ((cell)pointer - start) < size;
+ }
+
+ inline object *allot(cell size)
+ {
+ cell h = here;
+ here = h + align8(size);
+ return (object *)h;
+ }
+};
+
+}