VM: get rid of the duplicated nursery instance in vm->data->nursery

vm.nursery and vm->data->nursery are different objects. They get out
of sync when Factor code bumps vm.nursery but leaves vm->data->nursery
unchanged. The emptiness of vm->data->nursery meant that each_object()
never iterated it.
db4
Björn Lindqvist 2014-11-21 08:52:33 +01:00 committed by Doug Coleman
parent 2a5e1e06f3
commit 50c74fc496
8 changed files with 39 additions and 22 deletions

View File

@ -8,14 +8,15 @@ namespace factor {
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;

View File

@ -328,7 +328,7 @@ void factor_vm::collect_growing_heap(cell requested_size,
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();

View File

@ -7,7 +7,11 @@ void factor_vm::init_card_decks() {
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);
@ -36,14 +40,18 @@ data_heap::data_heap(cell young_size_, cell aging_size_, cell tenured_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;
@ -51,9 +59,10 @@ data_heap::~data_heap() {
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) {
@ -99,21 +108,20 @@ void data_heap::mark_all_cards() {
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();

View File

@ -9,6 +9,7 @@ struct data_heap {
segment* seg;
/* Borrowed reference to a factor_vm::nursery */
nursery_space* nursery;
aging_space* aging;
aging_space* aging_semispace;
@ -20,9 +21,12 @@ struct data_heap {
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);

View File

@ -23,7 +23,8 @@ Array* factor_vm::allot_uninitialized_array(cell capacity) {
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) */

View File

@ -5,7 +5,9 @@ struct nursery_policy {
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) {}

View File

@ -54,9 +54,9 @@ void factor_vm::primitive_string() {
}
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);
}

View File

@ -16,7 +16,8 @@ struct factor_vm {
/* 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 */
@ -331,7 +332,7 @@ struct factor_vm {
/* 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);