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) { inline object* factor_vm::allot_object(cell type, cell size) {
FACTOR_ASSERT(!current_gc); FACTOR_ASSERT(!current_gc);
nursery_space *nursery = data->nursery;
/* If the object is smaller than the nursery, allocate it in the nursery, /* If the object is smaller than the nursery, allocate it in the nursery,
after a GC if needed */ after a GC if needed */
if (nursery.size > size) { if (nursery->size > size) {
/* If there is insufficient room, collect the nursery */ /* If there is insufficient room, collect the nursery */
if (nursery.here + size > nursery.end) if (nursery->here + size > nursery->end)
primitive_minor_gc(); primitive_minor_gc();
object* obj = nursery.allot(size); object* obj = nursery->allot(size);
obj->initialize(type); obj->initialize(type);
return obj; return obj;

View File

@ -328,7 +328,7 @@ void factor_vm::collect_growing_heap(cell requested_size,
bool trace_contexts_p) { bool trace_contexts_p) {
/* Grow the data heap and copy all live objects to the new heap. */ /* Grow the data heap and copy all live objects to the new heap. */
data_heap* old = data; 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_mark_impl(trace_contexts_p);
collect_compact_code_impl(trace_contexts_p); collect_compact_code_impl(trace_contexts_p);
code->flush_icache(); 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); 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); young_size_ = align(young_size_, deck_size);
aging_size_ = align(aging_size_, deck_size); aging_size_ = align(aging_size_, deck_size);
tenured_size_ = align(tenured_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 = new aging_space(aging_size, tenured->end);
aging_semispace = new aging_space(aging_size, aging->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); FACTOR_ASSERT(seg->end - nursery->end <= deck_size);
} }
data_heap::~data_heap() { data_heap::~data_heap() {
delete seg; delete seg;
delete nursery;
delete aging; delete aging;
delete aging_semispace; delete aging_semispace;
delete tenured; delete tenured;
@ -51,9 +59,10 @@ data_heap::~data_heap() {
delete[] decks; 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; 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) { 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_) { void factor_vm::set_data_heap(data_heap* data_) {
data = data_; data = data_;
nursery = *data->nursery;
init_card_decks(); init_card_decks();
} }
void factor_vm::init_data_heap(cell young_size, cell aging_size, void factor_vm::init_data_heap(cell young_size, cell aging_size,
cell tenured_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 factor_vm::data_room() {
data_heap_room room; data_heap_room room;
room.nursery_size = nursery.size; room.nursery_size = data->nursery->size;
room.nursery_occupied = nursery.occupied_space(); room.nursery_occupied = data->nursery->occupied_space();
room.nursery_free = nursery.free_space(); room.nursery_free = data->nursery->free_space();
room.aging_size = data->aging->size; room.aging_size = data->aging->size;
room.aging_occupied = data->aging->occupied_space(); room.aging_occupied = data->aging->occupied_space();
room.aging_free = data->aging->free_space(); room.aging_free = data->aging->free_space();

View File

@ -9,6 +9,7 @@ struct data_heap {
segment* seg; segment* seg;
/* Borrowed reference to a factor_vm::nursery */
nursery_space* nursery; nursery_space* nursery;
aging_space* aging; aging_space* aging;
aging_space* aging_semispace; aging_space* aging_semispace;
@ -20,9 +21,12 @@ struct data_heap {
card_deck* decks; card_deck* decks;
card_deck* decks_end; 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();
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_cards(Generation* gen);
template <typename Generation> void clear_decks(Generation* gen); template <typename Generation> void clear_decks(Generation* gen);
void reset_generation(nursery_space* gen); void reset_generation(nursery_space* gen);

View File

@ -23,7 +23,8 @@ Array* factor_vm::allot_uninitialized_array(cell capacity) {
template <typename Array> template <typename Array>
bool factor_vm::reallot_array_in_place_p(Array* array, cell capacity) { 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) */ /* Allocates memory (sometimes) */

View File

@ -5,7 +5,9 @@ struct nursery_policy {
explicit nursery_policy(factor_vm* parent) : parent(parent) {} 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) {} 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) { 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) || (!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); capacity <= string_capacity(str);
} }

View File

@ -16,7 +16,8 @@ struct factor_vm {
/* Spare context -- for callbacks */ /* Spare context -- for callbacks */
context* spare_ctx; 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; nursery_space nursery;
/* Add this to a shifted address to compute write barrier offsets */ /* 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 nursery can't be iterated because there may be gaps between
the objects (see factor_vm::reallot_array) so we require it to the objects (see factor_vm::reallot_array) so we require it to
be empty first. */ be empty first. */
FACTOR_ASSERT(nursery.occupied_space() == 0); FACTOR_ASSERT(data->nursery->occupied_space() == 0);
gc_off = true; gc_off = true;
each_object(data->tenured, iterator); each_object(data->tenured, iterator);