VM: merge of slot_visitor and code_block_visitor
Looks like there is no reason for them to be separate classes and by merging them you can simplify lots of code.db4
							parent
							
								
									d2aea0f606
								
							
						
					
					
						commit
						4d7bc4c169
					
				| 
						 | 
				
			
			@ -118,7 +118,6 @@ ifdef CONFIG
 | 
			
		|||
		vm/nursery_collector.hpp \
 | 
			
		||||
		vm/aging_collector.hpp \
 | 
			
		||||
		vm/to_tenured_collector.hpp \
 | 
			
		||||
		vm/code_block_visitor.hpp \
 | 
			
		||||
		vm/full_collector.hpp \
 | 
			
		||||
		vm/arrays.hpp \
 | 
			
		||||
		vm/math.hpp \
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,122 +0,0 @@
 | 
			
		|||
namespace factor {
 | 
			
		||||
 | 
			
		||||
/* Code block visitors iterate over sets of code blocks, applying a functor to
 | 
			
		||||
each one. The functor returns a new code_block pointer, which may or may not
 | 
			
		||||
equal the old one. This is stored back to the original location.
 | 
			
		||||
 | 
			
		||||
This is used by GC's sweep and compact phases, and the implementation of the
 | 
			
		||||
modify-code-heap primitive.
 | 
			
		||||
 | 
			
		||||
Iteration is driven by visit_*() methods. Some of them define GC roots:
 | 
			
		||||
- visit_context_code_blocks()
 | 
			
		||||
- visit_callback_code_blocks() */
 | 
			
		||||
 | 
			
		||||
template <typename Fixup> struct code_block_visitor {
 | 
			
		||||
  factor_vm* parent;
 | 
			
		||||
  Fixup fixup;
 | 
			
		||||
 | 
			
		||||
  code_block_visitor(factor_vm* parent, Fixup fixup)
 | 
			
		||||
      : parent(parent), fixup(fixup) {}
 | 
			
		||||
 | 
			
		||||
  code_block* visit_code_block(code_block* compiled);
 | 
			
		||||
  void visit_object_code_block(object* obj);
 | 
			
		||||
  void visit_embedded_code_pointers(code_block* compiled);
 | 
			
		||||
  void visit_context_code_blocks();
 | 
			
		||||
  void visit_uninitialized_code_blocks();
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
template <typename Fixup>
 | 
			
		||||
code_block* code_block_visitor<Fixup>::visit_code_block(code_block* compiled) {
 | 
			
		||||
  return fixup.fixup_code(compiled);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template <typename Fixup> struct call_frame_code_block_visitor {
 | 
			
		||||
  factor_vm* parent;
 | 
			
		||||
  Fixup fixup;
 | 
			
		||||
 | 
			
		||||
  call_frame_code_block_visitor(factor_vm* parent, Fixup fixup)
 | 
			
		||||
      : parent(parent), fixup(fixup) {}
 | 
			
		||||
 | 
			
		||||
  void operator()(cell frame_top, cell size, code_block* owner, cell addr) {
 | 
			
		||||
    code_block* compiled =
 | 
			
		||||
        Fixup::translated_code_block_map ? owner : fixup.fixup_code(owner);
 | 
			
		||||
    cell fixed_addr = compiled->address_for_offset(owner->offset(addr));
 | 
			
		||||
 | 
			
		||||
    *(cell*)frame_top = fixed_addr;
 | 
			
		||||
  }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
template <typename Fixup>
 | 
			
		||||
void code_block_visitor<Fixup>::visit_object_code_block(object* obj) {
 | 
			
		||||
  switch (obj->type()) {
 | 
			
		||||
    case WORD_TYPE: {
 | 
			
		||||
      word* w = (word*)obj;
 | 
			
		||||
      if (w->entry_point)
 | 
			
		||||
        w->entry_point = visit_code_block(w->code())->entry_point();
 | 
			
		||||
      break;
 | 
			
		||||
    }
 | 
			
		||||
    case QUOTATION_TYPE: {
 | 
			
		||||
      quotation* q = (quotation*)obj;
 | 
			
		||||
      if (q->entry_point)
 | 
			
		||||
        q->entry_point = visit_code_block(q->code())->entry_point();
 | 
			
		||||
      break;
 | 
			
		||||
    }
 | 
			
		||||
    case CALLSTACK_TYPE: {
 | 
			
		||||
      callstack* stack = (callstack*)obj;
 | 
			
		||||
      call_frame_code_block_visitor<Fixup> call_frame_visitor(parent, fixup);
 | 
			
		||||
      parent->iterate_callstack_object(stack, call_frame_visitor, fixup);
 | 
			
		||||
      break;
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template <typename Fixup> struct embedded_code_pointers_visitor {
 | 
			
		||||
  Fixup fixup;
 | 
			
		||||
 | 
			
		||||
  explicit embedded_code_pointers_visitor(Fixup fixup) : fixup(fixup) {}
 | 
			
		||||
 | 
			
		||||
  void operator()(instruction_operand op) {
 | 
			
		||||
    relocation_type type = op.rel_type();
 | 
			
		||||
    if (type == RT_ENTRY_POINT || type == RT_ENTRY_POINT_PIC ||
 | 
			
		||||
        type == RT_ENTRY_POINT_PIC_TAIL)
 | 
			
		||||
      op.store_code_block(fixup.fixup_code(op.load_code_block()));
 | 
			
		||||
  }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
template <typename Fixup>
 | 
			
		||||
void code_block_visitor<Fixup>::visit_embedded_code_pointers(
 | 
			
		||||
    code_block* compiled) {
 | 
			
		||||
  if (!parent->code->uninitialized_p(compiled)) {
 | 
			
		||||
    embedded_code_pointers_visitor<Fixup> operand_visitor(fixup);
 | 
			
		||||
    compiled->each_instruction_operand(operand_visitor);
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template <typename Fixup>
 | 
			
		||||
void code_block_visitor<Fixup>::visit_context_code_blocks() {
 | 
			
		||||
  call_frame_code_block_visitor<Fixup> call_frame_visitor(parent, fixup);
 | 
			
		||||
  std::set<context*>::const_iterator begin = parent->active_contexts.begin();
 | 
			
		||||
  std::set<context*>::const_iterator end = parent->active_contexts.end();
 | 
			
		||||
  while (begin != end) {
 | 
			
		||||
    parent->iterate_callstack(*begin++, call_frame_visitor, fixup);
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template <typename Fixup>
 | 
			
		||||
void code_block_visitor<Fixup>::visit_uninitialized_code_blocks() {
 | 
			
		||||
  std::map<code_block*, cell>* uninitialized_blocks =
 | 
			
		||||
      &parent->code->uninitialized_blocks;
 | 
			
		||||
  std::map<code_block*, cell>::const_iterator iter =
 | 
			
		||||
      uninitialized_blocks->begin();
 | 
			
		||||
  std::map<code_block*, cell>::const_iterator end = uninitialized_blocks->end();
 | 
			
		||||
 | 
			
		||||
  std::map<code_block*, cell> new_uninitialized_blocks;
 | 
			
		||||
  for (; iter != end; iter++) {
 | 
			
		||||
    new_uninitialized_blocks.insert(
 | 
			
		||||
        std::make_pair(fixup.fixup_code(iter->first), iter->second));
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  parent->code->uninitialized_blocks = new_uninitialized_blocks;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -67,12 +67,9 @@ struct object_compaction_updater {
 | 
			
		|||
        starts(&parent->data->tenured->starts) {}
 | 
			
		||||
 | 
			
		||||
  void operator()(object* old_address, object* new_address, cell size) {
 | 
			
		||||
    slot_visitor<compaction_fixup> slot_forwarder(parent, fixup);
 | 
			
		||||
    slot_forwarder.visit_slots(new_address);
 | 
			
		||||
 | 
			
		||||
    code_block_visitor<compaction_fixup> code_forwarder(parent, fixup);
 | 
			
		||||
    code_forwarder.visit_object_code_block(new_address);
 | 
			
		||||
 | 
			
		||||
    slot_visitor<compaction_fixup> forwarder(parent, fixup);
 | 
			
		||||
    forwarder.visit_slots(new_address);
 | 
			
		||||
    forwarder.visit_object_code_block(new_address);
 | 
			
		||||
    starts->record_object_start_offset(new_address);
 | 
			
		||||
  }
 | 
			
		||||
};
 | 
			
		||||
| 
						 | 
				
			
			@ -125,19 +122,16 @@ template <typename Fixup> struct code_block_compaction_relocation_visitor {
 | 
			
		|||
template <typename Fixup> struct code_block_compaction_updater {
 | 
			
		||||
  factor_vm* parent;
 | 
			
		||||
  Fixup fixup;
 | 
			
		||||
  slot_visitor<Fixup> data_forwarder;
 | 
			
		||||
  code_block_visitor<Fixup> code_forwarder;
 | 
			
		||||
  slot_visitor<Fixup> forwarder;
 | 
			
		||||
 | 
			
		||||
  code_block_compaction_updater(
 | 
			
		||||
      factor_vm* parent, Fixup fixup, slot_visitor<Fixup> data_forwarder,
 | 
			
		||||
      code_block_visitor<Fixup> code_forwarder)
 | 
			
		||||
      factor_vm* parent, Fixup fixup, slot_visitor<Fixup> forwarder)
 | 
			
		||||
      : parent(parent),
 | 
			
		||||
        fixup(fixup),
 | 
			
		||||
        data_forwarder(data_forwarder),
 | 
			
		||||
        code_forwarder(code_forwarder) {}
 | 
			
		||||
        forwarder(forwarder) { }
 | 
			
		||||
 | 
			
		||||
  void operator()(code_block* old_address, code_block* new_address, cell size) {
 | 
			
		||||
    data_forwarder.visit_code_block_objects(new_address);
 | 
			
		||||
    forwarder.visit_code_block_objects(new_address);
 | 
			
		||||
 | 
			
		||||
    code_block_compaction_relocation_visitor<Fixup> visitor(parent, old_address,
 | 
			
		||||
                                                            fixup);
 | 
			
		||||
| 
						 | 
				
			
			@ -195,10 +189,9 @@ void factor_vm::collect_compact_impl(bool trace_contexts_p) {
 | 
			
		|||
    compaction_fixup fixup(data_forwarding_map, code_forwarding_map, &data_finger,
 | 
			
		||||
                           &code_finger);
 | 
			
		||||
 | 
			
		||||
    slot_visitor<compaction_fixup> data_forwarder(this, fixup);
 | 
			
		||||
    code_block_visitor<compaction_fixup> code_forwarder(this, fixup);
 | 
			
		||||
    slot_visitor<compaction_fixup> forwarder(this, fixup);
 | 
			
		||||
 | 
			
		||||
    code_forwarder.visit_uninitialized_code_blocks();
 | 
			
		||||
    forwarder.visit_uninitialized_code_blocks();
 | 
			
		||||
 | 
			
		||||
    /* Object start offsets get recomputed by the object_compaction_updater */
 | 
			
		||||
    data->tenured->starts.clear_object_start_offsets();
 | 
			
		||||
| 
						 | 
				
			
			@ -214,14 +207,14 @@ void factor_vm::collect_compact_impl(bool trace_contexts_p) {
 | 
			
		|||
       pointers inside code blocks. */
 | 
			
		||||
    {
 | 
			
		||||
      code_block_compaction_updater<compaction_fixup> code_block_updater(
 | 
			
		||||
          this, fixup, data_forwarder, code_forwarder);
 | 
			
		||||
          this, fixup, forwarder);
 | 
			
		||||
      code->allocator->compact(code_block_updater, fixup, &code_finger);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    data_forwarder.visit_roots();
 | 
			
		||||
    forwarder.visit_roots();
 | 
			
		||||
    if (trace_contexts_p) {
 | 
			
		||||
      data_forwarder.visit_contexts();
 | 
			
		||||
      code_forwarder.visit_context_code_blocks();
 | 
			
		||||
      forwarder.visit_contexts();
 | 
			
		||||
      forwarder.visit_context_code_blocks();
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -270,13 +263,13 @@ struct code_compaction_fixup {
 | 
			
		|||
};
 | 
			
		||||
 | 
			
		||||
struct object_grow_heap_updater {
 | 
			
		||||
  code_block_visitor<code_compaction_fixup> code_forwarder;
 | 
			
		||||
  slot_visitor<code_compaction_fixup> forwarder;
 | 
			
		||||
 | 
			
		||||
  explicit object_grow_heap_updater(
 | 
			
		||||
      code_block_visitor<code_compaction_fixup> code_forwarder)
 | 
			
		||||
      : code_forwarder(code_forwarder) {}
 | 
			
		||||
      slot_visitor<code_compaction_fixup> forwarder)
 | 
			
		||||
      : forwarder(forwarder) {}
 | 
			
		||||
 | 
			
		||||
  void operator()(object* obj) { code_forwarder.visit_object_code_block(obj); }
 | 
			
		||||
  void operator()(object* obj) { forwarder.visit_object_code_block(obj); }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/* Compact just the code heap, after growing the data heap */
 | 
			
		||||
| 
						 | 
				
			
			@ -288,22 +281,21 @@ void factor_vm::collect_compact_code_impl(bool trace_contexts_p) {
 | 
			
		|||
  const code_block* code_finger = (code_block*)code->allocator->start;
 | 
			
		||||
 | 
			
		||||
  code_compaction_fixup fixup(code_forwarding_map, &code_finger);
 | 
			
		||||
  slot_visitor<code_compaction_fixup> data_forwarder(this, fixup);
 | 
			
		||||
  code_block_visitor<code_compaction_fixup> code_forwarder(this, fixup);
 | 
			
		||||
  slot_visitor<code_compaction_fixup> forwarder(this, fixup);
 | 
			
		||||
 | 
			
		||||
  code_forwarder.visit_uninitialized_code_blocks();
 | 
			
		||||
  forwarder.visit_uninitialized_code_blocks();
 | 
			
		||||
 | 
			
		||||
  if (trace_contexts_p)
 | 
			
		||||
    code_forwarder.visit_context_code_blocks();
 | 
			
		||||
    forwarder.visit_context_code_blocks();
 | 
			
		||||
 | 
			
		||||
  /* Update code heap references in data heap */
 | 
			
		||||
  object_grow_heap_updater object_updater(code_forwarder);
 | 
			
		||||
  object_grow_heap_updater object_updater(forwarder);
 | 
			
		||||
  each_object(object_updater);
 | 
			
		||||
 | 
			
		||||
  /* Slide everything in the code heap up, and update code heap
 | 
			
		||||
	pointers inside code blocks. */
 | 
			
		||||
  code_block_compaction_updater<code_compaction_fixup> code_block_updater(
 | 
			
		||||
      this, fixup, data_forwarder, code_forwarder);
 | 
			
		||||
      this, fixup, forwarder);
 | 
			
		||||
  code->allocator->compact(code_block_updater, fixup, &code_finger);
 | 
			
		||||
 | 
			
		||||
  update_code_roots_for_compaction();
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -25,21 +25,18 @@ void factor_vm::collect_mark_impl(bool trace_contexts_p) {
 | 
			
		|||
      workhorse(this, this->data->tenured, full_policy(this));
 | 
			
		||||
 | 
			
		||||
  slot_visitor<gc_workhorse<tenured_space, full_policy> >
 | 
			
		||||
                data_visitor(this, workhorse);
 | 
			
		||||
 | 
			
		||||
  code_block_visitor<gc_workhorse<tenured_space, full_policy> >
 | 
			
		||||
                code_visitor(this, workhorse);
 | 
			
		||||
                visitor(this, workhorse);
 | 
			
		||||
 | 
			
		||||
  mark_stack.clear();
 | 
			
		||||
 | 
			
		||||
  code->allocator->state.clear_mark_bits();
 | 
			
		||||
  data->tenured->state.clear_mark_bits();
 | 
			
		||||
 | 
			
		||||
  data_visitor.visit_roots();
 | 
			
		||||
  visitor.visit_roots();
 | 
			
		||||
  if (trace_contexts_p) {
 | 
			
		||||
    data_visitor.visit_contexts();
 | 
			
		||||
    code_visitor.visit_context_code_blocks();
 | 
			
		||||
    code_visitor.visit_uninitialized_code_blocks();
 | 
			
		||||
    visitor.visit_contexts();
 | 
			
		||||
    visitor.visit_context_code_blocks();
 | 
			
		||||
    visitor.visit_uninitialized_code_blocks();
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  while (!mark_stack.empty()) {
 | 
			
		||||
| 
						 | 
				
			
			@ -48,15 +45,15 @@ void factor_vm::collect_mark_impl(bool trace_contexts_p) {
 | 
			
		|||
 | 
			
		||||
    if (ptr & 1) {
 | 
			
		||||
      code_block* compiled = (code_block*)(ptr - 1);
 | 
			
		||||
      data_visitor.visit_code_block_objects(compiled);
 | 
			
		||||
      data_visitor.visit_embedded_literals(compiled);
 | 
			
		||||
      code_visitor.visit_embedded_code_pointers(compiled);
 | 
			
		||||
      visitor.visit_code_block_objects(compiled);
 | 
			
		||||
      visitor.visit_embedded_literals(compiled);
 | 
			
		||||
      visitor.visit_embedded_code_pointers(compiled);
 | 
			
		||||
    } else {
 | 
			
		||||
      object* obj = (object*)ptr;
 | 
			
		||||
      data_visitor.visit_slots(obj);
 | 
			
		||||
      visitor.visit_slots(obj);
 | 
			
		||||
      if (obj->type() == ALIEN_TYPE)
 | 
			
		||||
        ((alien*)obj)->update_address();
 | 
			
		||||
      code_visitor.visit_object_code_block(obj);
 | 
			
		||||
      visitor.visit_object_code_block(obj);
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
  data->reset_tenured();
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										10
									
								
								vm/image.cpp
								
								
								
								
							
							
						
						
									
										10
									
								
								vm/image.cpp
								
								
								
								
							| 
						 | 
				
			
			@ -80,19 +80,17 @@ struct startup_fixup {
 | 
			
		|||
struct start_object_updater {
 | 
			
		||||
  factor_vm* parent;
 | 
			
		||||
  startup_fixup fixup;
 | 
			
		||||
  slot_visitor<startup_fixup> data_visitor;
 | 
			
		||||
  code_block_visitor<startup_fixup> code_visitor;
 | 
			
		||||
  slot_visitor<startup_fixup> visitor;
 | 
			
		||||
 | 
			
		||||
  start_object_updater(factor_vm* parent, startup_fixup fixup)
 | 
			
		||||
      : parent(parent),
 | 
			
		||||
        fixup(fixup),
 | 
			
		||||
        data_visitor(slot_visitor<startup_fixup>(parent, fixup)),
 | 
			
		||||
        code_visitor(code_block_visitor<startup_fixup>(parent, fixup)) {}
 | 
			
		||||
        visitor(slot_visitor<startup_fixup>(parent, fixup)) { }
 | 
			
		||||
 | 
			
		||||
  void operator()(object* obj, cell size) {
 | 
			
		||||
    parent->data->tenured->starts.record_object_start_offset(obj);
 | 
			
		||||
 | 
			
		||||
    data_visitor.visit_slots(obj);
 | 
			
		||||
    visitor.visit_slots(obj);
 | 
			
		||||
 | 
			
		||||
    switch (obj->type()) {
 | 
			
		||||
      case ALIEN_TYPE: {
 | 
			
		||||
| 
						 | 
				
			
			@ -110,7 +108,7 @@ struct start_object_updater {
 | 
			
		|||
        break;
 | 
			
		||||
      }
 | 
			
		||||
      default: {
 | 
			
		||||
        code_visitor.visit_object_code_block(obj);
 | 
			
		||||
        visitor.visit_object_code_block(obj);
 | 
			
		||||
        break;
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -137,7 +137,6 @@ namespace factor { struct factor_vm; }
 | 
			
		|||
#include "nursery_collector.hpp"
 | 
			
		||||
#include "aging_collector.hpp"
 | 
			
		||||
#include "to_tenured_collector.hpp"
 | 
			
		||||
#include "code_block_visitor.hpp"
 | 
			
		||||
#include "full_collector.hpp"
 | 
			
		||||
#include "arrays.hpp"
 | 
			
		||||
#include "math.hpp"
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -103,7 +103,18 @@ of the become primitive.
 | 
			
		|||
 | 
			
		||||
Iteration is driven by visit_*() methods. Some of them define GC roots:
 | 
			
		||||
- visit_roots()
 | 
			
		||||
- visit_contexts() */
 | 
			
		||||
- visit_contexts()
 | 
			
		||||
 | 
			
		||||
Code block visitors iterate over sets of code blocks, applying a functor to
 | 
			
		||||
each one. The functor returns a new code_block pointer, which may or may not
 | 
			
		||||
equal the old one. This is stored back to the original location.
 | 
			
		||||
 | 
			
		||||
This is used by GC's sweep and compact phases, and the implementation of the
 | 
			
		||||
modify-code-heap primitive.
 | 
			
		||||
 | 
			
		||||
Iteration is driven by visit_*() methods. Some of them define GC roots:
 | 
			
		||||
- visit_context_code_blocks()
 | 
			
		||||
- visit_callback_code_blocks() */
 | 
			
		||||
 | 
			
		||||
template <typename Fixup> struct slot_visitor {
 | 
			
		||||
  factor_vm* parent;
 | 
			
		||||
| 
						 | 
				
			
			@ -130,6 +141,10 @@ template <typename Fixup> struct slot_visitor {
 | 
			
		|||
  void visit_embedded_literals(code_block* compiled);
 | 
			
		||||
  void visit_sample_callstacks();
 | 
			
		||||
  void visit_sample_threads();
 | 
			
		||||
  void visit_object_code_block(object* obj);
 | 
			
		||||
  void visit_context_code_blocks();
 | 
			
		||||
  void visit_uninitialized_code_blocks();
 | 
			
		||||
  void visit_embedded_code_pointers(code_block* compiled);
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
template <typename Fixup>
 | 
			
		||||
| 
						 | 
				
			
			@ -431,4 +446,92 @@ void slot_visitor<Fixup>::visit_embedded_literals(code_block* compiled) {
 | 
			
		|||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template <typename Fixup> struct call_frame_code_block_visitor {
 | 
			
		||||
  factor_vm* parent;
 | 
			
		||||
  Fixup fixup;
 | 
			
		||||
 | 
			
		||||
  call_frame_code_block_visitor(factor_vm* parent, Fixup fixup)
 | 
			
		||||
      : parent(parent), fixup(fixup) {}
 | 
			
		||||
 | 
			
		||||
  void operator()(cell frame_top, cell size, code_block* owner, cell addr) {
 | 
			
		||||
    code_block* compiled =
 | 
			
		||||
        Fixup::translated_code_block_map ? owner : fixup.fixup_code(owner);
 | 
			
		||||
    cell fixed_addr = compiled->address_for_offset(owner->offset(addr));
 | 
			
		||||
 | 
			
		||||
    *(cell*)frame_top = fixed_addr;
 | 
			
		||||
  }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
template <typename Fixup>
 | 
			
		||||
void slot_visitor<Fixup>::visit_object_code_block(object* obj) {
 | 
			
		||||
  switch (obj->type()) {
 | 
			
		||||
    case WORD_TYPE: {
 | 
			
		||||
      word* w = (word*)obj;
 | 
			
		||||
      if (w->entry_point)
 | 
			
		||||
        w->entry_point = fixup.fixup_code(w->code())->entry_point();
 | 
			
		||||
      break;
 | 
			
		||||
    }
 | 
			
		||||
    case QUOTATION_TYPE: {
 | 
			
		||||
      quotation* q = (quotation*)obj;
 | 
			
		||||
      if (q->entry_point)
 | 
			
		||||
        q->entry_point = fixup.fixup_code(q->code())->entry_point();
 | 
			
		||||
      break;
 | 
			
		||||
    }
 | 
			
		||||
    case CALLSTACK_TYPE: {
 | 
			
		||||
      callstack* stack = (callstack*)obj;
 | 
			
		||||
      call_frame_code_block_visitor<Fixup> call_frame_visitor(parent, fixup);
 | 
			
		||||
      parent->iterate_callstack_object(stack, call_frame_visitor, fixup);
 | 
			
		||||
      break;
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template <typename Fixup>
 | 
			
		||||
void slot_visitor<Fixup>::visit_context_code_blocks() {
 | 
			
		||||
  call_frame_code_block_visitor<Fixup> call_frame_visitor(parent, fixup);
 | 
			
		||||
  std::set<context*>::const_iterator begin = parent->active_contexts.begin();
 | 
			
		||||
  std::set<context*>::const_iterator end = parent->active_contexts.end();
 | 
			
		||||
  while (begin != end) {
 | 
			
		||||
    parent->iterate_callstack(*begin++, call_frame_visitor, fixup);
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template <typename Fixup>
 | 
			
		||||
void slot_visitor<Fixup>::visit_uninitialized_code_blocks() {
 | 
			
		||||
  std::map<code_block*, cell>* uninitialized_blocks =
 | 
			
		||||
      &parent->code->uninitialized_blocks;
 | 
			
		||||
  std::map<code_block*, cell>::const_iterator iter =
 | 
			
		||||
      uninitialized_blocks->begin();
 | 
			
		||||
  std::map<code_block*, cell>::const_iterator end = uninitialized_blocks->end();
 | 
			
		||||
 | 
			
		||||
  std::map<code_block*, cell> new_uninitialized_blocks;
 | 
			
		||||
  for (; iter != end; iter++) {
 | 
			
		||||
    new_uninitialized_blocks.insert(
 | 
			
		||||
        std::make_pair(fixup.fixup_code(iter->first), iter->second));
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  parent->code->uninitialized_blocks = new_uninitialized_blocks;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template <typename Fixup> struct embedded_code_pointers_visitor {
 | 
			
		||||
  Fixup fixup;
 | 
			
		||||
 | 
			
		||||
  explicit embedded_code_pointers_visitor(Fixup fixup) : fixup(fixup) {}
 | 
			
		||||
 | 
			
		||||
  void operator()(instruction_operand op) {
 | 
			
		||||
    relocation_type type = op.rel_type();
 | 
			
		||||
    if (type == RT_ENTRY_POINT || type == RT_ENTRY_POINT_PIC ||
 | 
			
		||||
        type == RT_ENTRY_POINT_PIC_TAIL)
 | 
			
		||||
      op.store_code_block(fixup.fixup_code(op.load_code_block()));
 | 
			
		||||
  }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
template <typename Fixup>
 | 
			
		||||
void slot_visitor<Fixup>::visit_embedded_code_pointers(code_block* compiled) {
 | 
			
		||||
  if (!parent->code->uninitialized_p(compiled)) {
 | 
			
		||||
    embedded_code_pointers_visitor<Fixup> operand_visitor(fixup);
 | 
			
		||||
    compiled->each_instruction_operand(operand_visitor);
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in New Issue