VM: use a function update_relocation to replace the
code_block_compaction_relocation_visitor structdb4
							parent
							
								
									abb8bd74b9
								
							
						
					
					
						commit
						a5a7232b8f
					
				| 
						 | 
				
			
			@ -30,29 +30,58 @@ struct compaction_fixup {
 | 
			
		|||
  object* translate_data(const object* obj) {
 | 
			
		||||
    if (obj < *data_finger)
 | 
			
		||||
      return fixup_data((object*)obj);
 | 
			
		||||
    else
 | 
			
		||||
      return (object*)obj;
 | 
			
		||||
    return (object*)obj;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  code_block* translate_code(const code_block* compiled) {
 | 
			
		||||
    if (compiled < *code_finger)
 | 
			
		||||
      return fixup_code((code_block*)compiled);
 | 
			
		||||
    else
 | 
			
		||||
      return (code_block*)compiled;
 | 
			
		||||
    return (code_block*)compiled;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  cell size(object* obj) {
 | 
			
		||||
    if (data_forwarding_map->marked_p((cell)obj))
 | 
			
		||||
      return obj->size(*this);
 | 
			
		||||
    else
 | 
			
		||||
      return data_forwarding_map->unmarked_block_size((cell)obj);
 | 
			
		||||
    return data_forwarding_map->unmarked_block_size((cell)obj);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  cell size(code_block* compiled) {
 | 
			
		||||
    if (code_forwarding_map->marked_p((cell)compiled))
 | 
			
		||||
      return compiled->size(*this);
 | 
			
		||||
    else
 | 
			
		||||
      return code_forwarding_map->unmarked_block_size((cell)compiled);
 | 
			
		||||
    return code_forwarding_map->unmarked_block_size((cell)compiled);
 | 
			
		||||
  }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
struct code_compaction_fixup {
 | 
			
		||||
  static const bool translated_code_block_map = false;
 | 
			
		||||
 | 
			
		||||
  mark_bits* code_forwarding_map;
 | 
			
		||||
  const code_block** code_finger;
 | 
			
		||||
 | 
			
		||||
  code_compaction_fixup(mark_bits* code_forwarding_map,
 | 
			
		||||
                        const code_block** code_finger)
 | 
			
		||||
      : code_forwarding_map(code_forwarding_map), code_finger(code_finger) {}
 | 
			
		||||
 | 
			
		||||
  object* fixup_data(object* obj) { return obj; }
 | 
			
		||||
 | 
			
		||||
  code_block* fixup_code(code_block* compiled) {
 | 
			
		||||
    return (code_block*)code_forwarding_map->forward_block((cell)compiled);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  object* translate_data(const object* obj) { return fixup_data((object*)obj); }
 | 
			
		||||
 | 
			
		||||
  code_block* translate_code(const code_block* compiled) {
 | 
			
		||||
    if (compiled < *code_finger)
 | 
			
		||||
      return fixup_code((code_block*)compiled);
 | 
			
		||||
    return (code_block*)compiled;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  cell size(object* obj) { return obj->size(); }
 | 
			
		||||
 | 
			
		||||
  cell size(code_block* compiled) {
 | 
			
		||||
    if (code_forwarding_map->marked_p((cell)compiled))
 | 
			
		||||
      return compiled->size(*this);
 | 
			
		||||
    return code_forwarding_map->unmarked_block_size((cell)compiled);
 | 
			
		||||
  }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -74,50 +103,43 @@ struct object_compaction_updater {
 | 
			
		|||
  }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
template <typename Fixup> struct code_block_compaction_relocation_visitor {
 | 
			
		||||
  factor_vm* parent;
 | 
			
		||||
  code_block* old_address;
 | 
			
		||||
  Fixup fixup;
 | 
			
		||||
template <typename Fixup>
 | 
			
		||||
void update_relocation(factor_vm* parent,
 | 
			
		||||
                       cell old_entry_point,
 | 
			
		||||
                       Fixup fixup,
 | 
			
		||||
                       instruction_operand op) {
 | 
			
		||||
  cell old_offset = op.rel_offset() + old_entry_point;
 | 
			
		||||
 | 
			
		||||
  code_block_compaction_relocation_visitor(factor_vm* parent,
 | 
			
		||||
                                           code_block* old_address,
 | 
			
		||||
                                           Fixup fixup)
 | 
			
		||||
      : parent(parent), old_address(old_address), fixup(fixup) {}
 | 
			
		||||
 | 
			
		||||
  void operator()(instruction_operand op) {
 | 
			
		||||
    cell old_offset = op.rel_offset() + old_address->entry_point();
 | 
			
		||||
 | 
			
		||||
    switch (op.rel_type()) {
 | 
			
		||||
      case RT_LITERAL: {
 | 
			
		||||
        cell value = op.load_value(old_offset);
 | 
			
		||||
        if (immediate_p(value))
 | 
			
		||||
          op.store_value(value);
 | 
			
		||||
        else
 | 
			
		||||
          op.store_value(
 | 
			
		||||
              RETAG(fixup.fixup_data(untag<object>(value)), TAG(value)));
 | 
			
		||||
        break;
 | 
			
		||||
      }
 | 
			
		||||
      case RT_ENTRY_POINT:
 | 
			
		||||
      case RT_ENTRY_POINT_PIC:
 | 
			
		||||
      case RT_ENTRY_POINT_PIC_TAIL:
 | 
			
		||||
      case RT_HERE: {
 | 
			
		||||
        cell value = op.load_value(old_offset);
 | 
			
		||||
        cell offset = TAG(value);
 | 
			
		||||
        code_block* compiled = (code_block*)UNTAG(value);
 | 
			
		||||
        op.store_value((cell)fixup.fixup_code(compiled) + offset);
 | 
			
		||||
        break;
 | 
			
		||||
      }
 | 
			
		||||
      case RT_THIS:
 | 
			
		||||
      case RT_CARDS_OFFSET:
 | 
			
		||||
      case RT_DECKS_OFFSET:
 | 
			
		||||
        parent->store_external_address(op);
 | 
			
		||||
        break;
 | 
			
		||||
      default:
 | 
			
		||||
        op.store_value(op.load_value(old_offset));
 | 
			
		||||
        break;
 | 
			
		||||
  switch (op.rel_type()) {
 | 
			
		||||
    case RT_LITERAL: {
 | 
			
		||||
      cell value = op.load_value(old_offset);
 | 
			
		||||
      if (immediate_p(value))
 | 
			
		||||
        op.store_value(value);
 | 
			
		||||
      else
 | 
			
		||||
        op.store_value(
 | 
			
		||||
            RETAG(fixup.fixup_data(untag<object>(value)), TAG(value)));
 | 
			
		||||
      break;
 | 
			
		||||
    }
 | 
			
		||||
    case RT_ENTRY_POINT:
 | 
			
		||||
    case RT_ENTRY_POINT_PIC:
 | 
			
		||||
    case RT_ENTRY_POINT_PIC_TAIL:
 | 
			
		||||
    case RT_HERE: {
 | 
			
		||||
      cell value = op.load_value(old_offset);
 | 
			
		||||
      cell offset = TAG(value);
 | 
			
		||||
      code_block* compiled = (code_block*)UNTAG(value);
 | 
			
		||||
      op.store_value((cell)fixup.fixup_code(compiled) + offset);
 | 
			
		||||
      break;
 | 
			
		||||
    }
 | 
			
		||||
    case RT_THIS:
 | 
			
		||||
    case RT_CARDS_OFFSET:
 | 
			
		||||
    case RT_DECKS_OFFSET:
 | 
			
		||||
      parent->store_external_address(op);
 | 
			
		||||
      break;
 | 
			
		||||
    default:
 | 
			
		||||
      op.store_value(op.load_value(old_offset));
 | 
			
		||||
      break;
 | 
			
		||||
  }
 | 
			
		||||
};
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template <typename Fixup> struct code_block_compaction_updater {
 | 
			
		||||
  factor_vm* parent;
 | 
			
		||||
| 
						 | 
				
			
			@ -133,9 +155,11 @@ template <typename Fixup> struct code_block_compaction_updater {
 | 
			
		|||
  void operator()(code_block* old_address, code_block* new_address, cell size) {
 | 
			
		||||
    forwarder.visit_code_block_objects(new_address);
 | 
			
		||||
 | 
			
		||||
    code_block_compaction_relocation_visitor<Fixup> visitor(parent, old_address,
 | 
			
		||||
                                                            fixup);
 | 
			
		||||
    new_address->each_instruction_operand(visitor);
 | 
			
		||||
    cell old_entry_point = old_address->entry_point();
 | 
			
		||||
    auto update_func = [&](instruction_operand op) {
 | 
			
		||||
      update_relocation(parent, old_entry_point, fixup, op);
 | 
			
		||||
    };
 | 
			
		||||
    new_address->each_instruction_operand(update_func);
 | 
			
		||||
  }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -222,41 +246,6 @@ void factor_vm::collect_compact_impl() {
 | 
			
		|||
    event->ended_compaction();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
struct code_compaction_fixup {
 | 
			
		||||
  static const bool translated_code_block_map = false;
 | 
			
		||||
 | 
			
		||||
  mark_bits* code_forwarding_map;
 | 
			
		||||
  const code_block** code_finger;
 | 
			
		||||
 | 
			
		||||
  code_compaction_fixup(mark_bits* code_forwarding_map,
 | 
			
		||||
                        const code_block** code_finger)
 | 
			
		||||
      : code_forwarding_map(code_forwarding_map), code_finger(code_finger) {}
 | 
			
		||||
 | 
			
		||||
  object* fixup_data(object* obj) { return obj; }
 | 
			
		||||
 | 
			
		||||
  code_block* fixup_code(code_block* compiled) {
 | 
			
		||||
    return (code_block*)code_forwarding_map->forward_block((cell)compiled);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  object* translate_data(const object* obj) { return fixup_data((object*)obj); }
 | 
			
		||||
 | 
			
		||||
  code_block* translate_code(const code_block* compiled) {
 | 
			
		||||
    if (compiled < *code_finger)
 | 
			
		||||
      return fixup_code((code_block*)compiled);
 | 
			
		||||
    else
 | 
			
		||||
      return (code_block*)compiled;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  cell size(object* obj) { return obj->size(); }
 | 
			
		||||
 | 
			
		||||
  cell size(code_block* compiled) {
 | 
			
		||||
    if (code_forwarding_map->marked_p((cell)compiled))
 | 
			
		||||
      return compiled->size(*this);
 | 
			
		||||
    else
 | 
			
		||||
      return code_forwarding_map->unmarked_block_size((cell)compiled);
 | 
			
		||||
  }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/* Compact just the code heap, after growing the data heap */
 | 
			
		||||
void factor_vm::collect_compact_code_impl() {
 | 
			
		||||
  /* Figure out where blocks are going to go */
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in New Issue