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) {
|
||||
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;
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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) */
|
||||
|
|
|
@ -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) {}
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Reference in New Issue