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