]> gitweb.factorcode.org Git - factor.git/commitdiff
VM: new method visit_instruction_operands(), it replaces the instruction
authorBjörn Lindqvist <bjourne@gmail.com>
Sat, 1 Aug 2015 14:47:04 +0000 (16:47 +0200)
committerBjörn Lindqvist <bjourne@gmail.com>
Tue, 4 Aug 2015 14:02:09 +0000 (16:02 +0200)
operand iteration code in compaction.cpp and image.cpp

vm/compaction.cpp
vm/image.cpp
vm/slot_visitor.hpp

index 48b45ab9d6dfd757a647b479c4382166d319aceb..3e606ca52b59e872f42252ec5b8eea47c19012b1 100644 (file)
@@ -52,37 +52,6 @@ struct compaction_fixup {
   }
 };
 
-template <typename Fixup>
-fixnum compute_operand_value(factor_vm* parent,
-                             cell old_entry_point,
-                             Fixup fixup,
-                             instruction_operand op) {
-  cell old_offset = op.rel_offset() + old_entry_point;
-  switch (op.rel_type()) {
-    case RT_LITERAL: {
-      cell value = op.load_value(old_offset);
-      if (immediate_p(value))
-        return value;
-      return RETAG(fixup.fixup_data(untag<object>(value)), TAG(value));
-    }
-    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);
-      return (cell)fixup.fixup_code(compiled) + offset;
-    }
-    case RT_THIS:
-    case RT_CARDS_OFFSET:
-    case RT_DECKS_OFFSET:
-      return parent->compute_external_address(op);
-    default:
-      return op.load_value(old_offset);
-  }
-}
-
 /* After a compaction, invalidate any code heap roots which are not
 marked, and also slide the valid roots up so that call sites can be updated
 correctly in case an inline cache compilation triggered compaction. */
@@ -148,20 +117,14 @@ void factor_vm::collect_compact_impl() {
 
     /* Slide everything in the code heap up, and update data and code heap
        pointers inside code blocks. */
-    auto compact_data_func = [&](code_block* old_addr,
+    auto compact_code_func = [&](code_block* old_addr,
                                  code_block* new_addr,
                                  cell size) {
       forwarder.visit_code_block_objects(new_addr);
       cell old_entry_point = old_addr->entry_point();
-      auto update_func = [&](instruction_operand op) {
-        op.store_value(compute_operand_value(this,
-                                             old_entry_point,
-                                             forwarder.fixup,
-                                             op));
-      };
-      new_addr->each_instruction_operand(update_func);
+      forwarder.visit_instruction_operands(new_addr, old_entry_point);
     };
-    code->allocator->compact(compact_data_func, fixup, &code_finger);
+    code->allocator->compact(compact_code_func, fixup, &code_finger);
 
     forwarder.visit_all_roots();
     forwarder.visit_context_code_blocks();
index d4d6a8e4c5609917c429ba6c19f02c4c513d1c0f..2c59dc27ca2ee2a14d9109f77b1b46de87bd727e 100644 (file)
@@ -109,57 +109,13 @@ void factor_vm::fixup_data(cell data_offset, cell code_offset) {
   data->tenured->iterate(start_object_updater, fixup);
 }
 
-struct startup_code_block_relocation_visitor {
-  factor_vm* parent;
-  startup_fixup fixup;
-  slot_visitor<startup_fixup> visitor;
-
-  startup_code_block_relocation_visitor(factor_vm* parent,
-                                        startup_fixup fixup)
-      : parent(parent),
-        fixup(fixup),
-        visitor(slot_visitor<startup_fixup>(parent, fixup)) {}
-
-  fixnum compute_operand_value(instruction_operand op) {
-    code_block* compiled = op.compiled;
-    cell old_offset =
-        op.rel_offset() + compiled->entry_point() - fixup.code_offset;
-    switch (op.rel_type()) {
-      case RT_LITERAL: {
-        cell value = op.load_value(old_offset);
-        if (immediate_p(value))
-          return value;
-        return RETAG(fixup.fixup_data(untag<object>(value)), TAG(value));
-      }
-      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);
-        return (cell)fixup.fixup_code(compiled) + offset;
-      }
-      case RT_UNTAGGED:
-        return op.load_value(old_offset);
-      default:
-        return parent->compute_external_address(op);
-    }
-  }
-
-  void operator()(instruction_operand op) {
-    op.store_value(compute_operand_value(op));
-  }
-};
-
 void factor_vm::fixup_code(cell data_offset, cell code_offset) {
   startup_fixup fixup(data_offset, code_offset);
   auto updater = [&](code_block* compiled, cell size) {
     slot_visitor<startup_fixup> visitor(this, fixup);
     visitor.visit_code_block_objects(compiled);
-
-    startup_code_block_relocation_visitor code_visitor(this, fixup);
-    compiled->each_instruction_operand(code_visitor);
+    cell rel_base = compiled->entry_point() - fixup.code_offset;
+    visitor.visit_instruction_operands(compiled, rel_base);
   };
   code->allocator->iterate(updater, fixup);
 }
index 7552b21c9488b3968e8ad43cd5387bcc4526cfee..5128c39e2c909202a88056f6c6b01a335b69f763 100644 (file)
@@ -141,6 +141,7 @@ template <typename Fixup> struct slot_visitor {
   void visit_embedded_code_pointers(code_block* compiled);
   void visit_object(object* obj);
   void visit_mark_stack(std::vector<cell>* mark_stack);
+  void visit_instruction_operands(code_block* block, cell rel_base);
 };
 
 template <typename Fixup>
@@ -466,4 +467,40 @@ void slot_visitor<Fixup>::visit_mark_stack(std::vector<cell>* mark_stack) {
   }
 }
 
+/* Visits the instruction operands in a code block. If the operand is
+   a pointer to a code block or data object, then the fixup is applied
+   to it. Otherwise, if it is an external addess, that address is
+   recomputed. If it is an untagged number literal (RT_UNTAGGED) or an
+   immediate value, then nothing is done with it. */
+template <typename Fixup>
+void slot_visitor<Fixup>::visit_instruction_operands(code_block* block,
+                                                     cell rel_base) {
+  auto visit_func = [&](instruction_operand op){
+    cell old_offset = rel_base + op.rel_offset();
+    cell value = op.load_value(old_offset);
+    switch (op.rel_type()) {
+      case RT_LITERAL: {
+        value = visit_pointer(value);
+        break;
+      }
+      case RT_ENTRY_POINT:
+      case RT_ENTRY_POINT_PIC:
+      case RT_ENTRY_POINT_PIC_TAIL:
+      case RT_HERE: {
+        cell offset = TAG(value);
+        code_block* compiled = (code_block*)UNTAG(value);
+        value = RETAG(fixup.fixup_code(compiled), offset);
+        break;
+      }
+      case RT_UNTAGGED:
+        break;
+      default:
+        value = parent->compute_external_address(op);
+        break;
+    }
+    op.store_value(value);
+  };
+  block->each_instruction_operand(visit_func);
+}
+
 }