inline object* factor_vm::allot_object(cell type, cell size) {
FACTOR_ASSERT(!current_gc);
+ nursery_space *nursery = data->nursery;
/* If the object is smaller than the nursery, allocate it in the nursery,
after a GC if needed */
- if (nursery.size > size) {
+ if (nursery->size > size) {
/* If there is insufficient room, collect the nursery */
- if (nursery.here + size > nursery.end)
+ if (nursery->here + size > nursery->end)
primitive_minor_gc();
- object* obj = nursery.allot(size);
+ object* obj = nursery->allot(size);
obj->initialize(type);
return obj;
bool trace_contexts_p) {
/* Grow the data heap and copy all live objects to the new heap. */
data_heap* old = data;
- set_data_heap(data->grow(requested_size));
+ set_data_heap(data->grow(&nursery, requested_size));
collect_mark_impl(trace_contexts_p);
collect_compact_code_impl(trace_contexts_p);
code->flush_icache();
decks_offset = (cell)data->decks - addr_to_deck(data->start);
}
-data_heap::data_heap(cell young_size_, cell aging_size_, cell tenured_size_) {
+data_heap::data_heap(nursery_space* vm_nursery,
+ cell young_size_,
+ cell aging_size_,
+ cell tenured_size_) {
+
young_size_ = align(young_size_, deck_size);
aging_size_ = align(aging_size_, deck_size);
tenured_size_ = align(tenured_size_, deck_size);
aging = new aging_space(aging_size, tenured->end);
aging_semispace = new aging_space(aging_size, aging->end);
- nursery = new nursery_space(young_size, aging_semispace->end);
+ // Initialize vm nursery
+ vm_nursery->here = aging_semispace->end;
+ vm_nursery->start = aging_semispace->end;
+ vm_nursery->end = vm_nursery->start + young_size;
+ vm_nursery->size = young_size;
+ nursery = vm_nursery;
FACTOR_ASSERT(seg->end - nursery->end <= deck_size);
}
data_heap::~data_heap() {
delete seg;
- delete nursery;
delete aging;
delete aging_semispace;
delete tenured;
delete[] decks;
}
-data_heap* data_heap::grow(cell requested_bytes) {
+data_heap* data_heap::grow(nursery_space* vm_nursery, cell requested_bytes) {
+ FACTOR_ASSERT(vm_nursery->occupied_space() == 0);
cell new_tenured_size = (tenured_size * 2) + requested_bytes;
- return new data_heap(young_size, aging_size, new_tenured_size);
+ return new data_heap(vm_nursery, young_size, aging_size, new_tenured_size);
}
template <typename Generation> void data_heap::clear_cards(Generation* gen) {
void factor_vm::set_data_heap(data_heap* data_) {
data = data_;
- nursery = *data->nursery;
init_card_decks();
}
void factor_vm::init_data_heap(cell young_size, cell aging_size,
cell tenured_size) {
- set_data_heap(new data_heap(young_size, aging_size, tenured_size));
+ set_data_heap(new data_heap(&nursery, young_size, aging_size, tenured_size));
}
data_heap_room factor_vm::data_room() {
data_heap_room room;
- room.nursery_size = nursery.size;
- room.nursery_occupied = nursery.occupied_space();
- room.nursery_free = nursery.free_space();
+ room.nursery_size = data->nursery->size;
+ room.nursery_occupied = data->nursery->occupied_space();
+ room.nursery_free = data->nursery->free_space();
room.aging_size = data->aging->size;
room.aging_occupied = data->aging->occupied_space();
room.aging_free = data->aging->free_space();
segment* seg;
+ /* Borrowed reference to a factor_vm::nursery */
nursery_space* nursery;
aging_space* aging;
aging_space* aging_semispace;
card_deck* decks;
card_deck* decks_end;
- data_heap(cell young_size, cell aging_size, cell tenured_size);
+ data_heap(nursery_space* vm_nursery,
+ cell young_size,
+ cell aging_size,
+ cell tenured_size);
~data_heap();
- data_heap* grow(cell requested_size);
+ data_heap* grow(nursery_space* vm_nursery, cell requested_size);
template <typename Generation> void clear_cards(Generation* gen);
template <typename Generation> void clear_decks(Generation* gen);
void reset_generation(nursery_space* gen);
template <typename Array>
bool factor_vm::reallot_array_in_place_p(Array* array, cell capacity) {
- return nursery.contains_p(array) && capacity <= array_capacity(array);
+ return data->nursery->contains_p(array) &&
+ capacity <= array_capacity(array);
}
/* Allocates memory (sometimes) */
explicit nursery_policy(factor_vm* parent) : parent(parent) {}
- bool should_copy_p(object* obj) { return parent->nursery.contains_p(obj); }
+ bool should_copy_p(object* obj) {
+ return parent->data->nursery->contains_p(obj);
+ }
void promoted_object(object* obj) {}
}
bool factor_vm::reallot_string_in_place_p(string* str, cell capacity) {
- return nursery.contains_p(str) &&
+ return data->nursery->contains_p(str) &&
(!to_boolean(str->aux) ||
- nursery.contains_p(untag<byte_array>(str->aux))) &&
+ data->nursery->contains_p(untag<byte_array>(str->aux))) &&
capacity <= string_capacity(str);
}
/* Spare context -- for callbacks */
context* spare_ctx;
- /* New objects are allocated here */
+ /* New objects are allocated here, use the data->nursery reference
+ instead from c++ code. */
nursery_space nursery;
/* Add this to a shifted address to compute write barrier offsets */
/* The nursery can't be iterated because there may be gaps between
the objects (see factor_vm::reallot_array) so we require it to
be empty first. */
- FACTOR_ASSERT(nursery.occupied_space() == 0);
+ FACTOR_ASSERT(data->nursery->occupied_space() == 0);
gc_off = true;
each_object(data->tenured, iterator);