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
parent
2a5e1e06f3
commit
50c74fc496
|
@ -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;
|
||||||
|
|
|
@ -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();
|
||||||
|
|
|
@ -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();
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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) */
|
||||||
|
|
|
@ -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) {}
|
||||||
|
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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);
|
||||||
|
|
Loading…
Reference in New Issue