]> gitweb.factorcode.org Git - factor.git/commitdiff
vm: mark sweep now traces code block references; rename embedded_pointer to instructi...
authorSlava Pestov <slava@slava-pestovs-macbook-pro.local>
Tue, 24 Nov 2009 00:51:08 +0000 (18:51 -0600)
committerSlava Pestov <slava@slava-pestovs-macbook-pro.local>
Tue, 24 Nov 2009 01:17:12 +0000 (19:17 -0600)
22 files changed:
Makefile
vm/aging_collector.cpp
vm/callbacks.cpp
vm/code_block_visitor.hpp
vm/code_blocks.cpp
vm/code_heap.cpp
vm/collector.hpp
vm/compaction.cpp
vm/data_heap.cpp
vm/embedded_pointers.cpp [deleted file]
vm/embedded_pointers.hpp [deleted file]
vm/full_collector.cpp
vm/full_collector.hpp
vm/instruction_operands.cpp [new file with mode: 0644]
vm/instruction_operands.hpp [new file with mode: 0644]
vm/master.hpp
vm/objects.cpp
vm/slot_visitor.hpp
vm/tenured_space.hpp
vm/to_tenured_collector.cpp
vm/to_tenured_collector.hpp
vm/vm.hpp

index e5229ef7dfb562cfeb4a676b7718f40a1926ef0c..80621d8f0a96c2649d23efa03d204ba0c82af301 100755 (executable)
--- a/Makefile
+++ b/Makefile
@@ -47,7 +47,6 @@ DLL_OBJS = $(PLAF_DLL_OBJS) \
        vm/data_heap_checker.o \
        vm/debug.o \
        vm/dispatch.o \
-       vm/embedded_pointers.o \
        vm/errors.o \
        vm/factor.o \
        vm/free_list.o \
@@ -55,6 +54,7 @@ DLL_OBJS = $(PLAF_DLL_OBJS) \
        vm/gc.o \
        vm/image.o \
        vm/inline_cache.o \
+       vm/instruction_operands.o \
        vm/io.o \
        vm/jit.o \
        vm/math.o \
index 1695846ee7c086bc9c9292c7479e38a7252b8d06..bef4dc6202f1f6ee390adc066045c744406db8b2 100644 (file)
@@ -22,7 +22,7 @@ void factor_vm::collect_aging()
 
                to_tenured_collector collector(this);
 
-               current_gc->event->started_code_scan();
+               current_gc->event->started_card_scan();
                collector.trace_cards(data->tenured,
                        card_points_to_aging,
                        full_unmarker());
index d6b941b93ba5922636dae5fbd9f3d2e49a601994..121913eeea2f0c875f9c30471aae19050d1e2258 100644 (file)
@@ -26,8 +26,8 @@ void callback_heap::update(callback *stub)
        cell rel_class = untag_fixnum(array_nth(code_template.untagged(),1));
        cell offset = untag_fixnum(array_nth(code_template.untagged(),3));
 
-       embedded_pointer ptr(rel_class,offset + (cell)(stub + 1));
-       ptr.store_address((cell)(stub->compiled + 1));
+       instruction_operand op(rel_class,offset + (cell)(stub + 1));
+       op.store_value((cell)(stub->compiled + 1));
 
        flush_icache((cell)stub,stub->size);
 }
index 09410d4ae4ed17d3d22f6c454082a06264b7b6f9..dbaa00e83a31c1c87a3d9d9cee0fc431219137ef 100644 (file)
@@ -1,7 +1,21 @@
 namespace factor
 {
 
-template<typename Visitor> struct call_frame_code_block_visitor {
+template<typename Visitor> struct code_block_visitor {
+       factor_vm *parent;
+       Visitor visitor;
+
+       explicit code_block_visitor(factor_vm *parent_, Visitor visitor_) :
+               parent(parent_), visitor(visitor_) {}
+
+       void visit_object_code_block(object *obj);
+       void visit_referenced_code_blocks(code_block *compiled);
+       void visit_context_code_blocks();
+       void visit_callback_code_blocks();
+};
+
+template<typename Visitor>
+struct call_frame_code_block_visitor {
        factor_vm *parent;
        Visitor visitor;
 
@@ -19,71 +33,97 @@ template<typename Visitor> struct call_frame_code_block_visitor {
        }
 };
 
-template<typename Visitor> struct callback_code_block_visitor {
-       callback_heap *callbacks;
-       Visitor visitor;
-
-       explicit callback_code_block_visitor(callback_heap *callbacks_, Visitor visitor_) :
-               callbacks(callbacks_), visitor(visitor_) {}
-
-       void operator()(callback *stub)
+template<typename Visitor>
+void code_block_visitor<Visitor>::visit_object_code_block(object *obj)
+{
+       switch(obj->type())
        {
-               stub->compiled = visitor(stub->compiled);
-               callbacks->update(stub);
+       case WORD_TYPE:
+               {
+                       word *w = (word *)obj;
+                       if(w->code)
+                               w->code = visitor(w->code);
+                       if(w->profiling)
+                               w->profiling = visitor(w->profiling);
+
+                       parent->update_word_xt(w);
+                       break;
+               }
+       case QUOTATION_TYPE:
+               {
+                       quotation *q = (quotation *)obj;
+                       if(q->code)
+                               parent->set_quot_xt(q,visitor(q->code));
+                       break;
+               }
+       case CALLSTACK_TYPE:
+               {
+                       callstack *stack = (callstack *)obj;
+                       call_frame_code_block_visitor<Visitor> call_frame_visitor(parent,visitor);
+                       parent->iterate_callstack_object(stack,call_frame_visitor);
+                       break;
+               }
        }
-};
+}
 
-template<typename Visitor> struct code_block_visitor {
-       factor_vm *parent;
+template<typename Visitor>
+struct referenced_code_blocks_visitor {
        Visitor visitor;
 
-       explicit code_block_visitor(factor_vm *parent_, Visitor visitor_) :
-               parent(parent_), visitor(visitor_) {}
+       explicit referenced_code_blocks_visitor(Visitor visitor_) : visitor(visitor_) {}
 
-       void visit_object_code_block(object *obj)
+       void operator()(relocation_entry rel, cell index, code_block *compiled)
        {
-               switch(obj->type())
+               relocation_type type = rel.rel_type();
+               if(type == RT_XT || type == RT_XT_PIC || type == RT_XT_PIC_TAIL)
                {
-               case WORD_TYPE:
-                       {
-                               word *w = (word *)obj;
-                               if(w->code)
-                                       w->code = visitor(w->code);
-                               if(w->profiling)
-                                       w->profiling = visitor(w->profiling);
-       
-                               parent->update_word_xt(w);
-                               break;
-                       }
-               case QUOTATION_TYPE:
-                       {
-                               quotation *q = (quotation *)obj;
-                               if(q->code)
-                                       parent->set_quot_xt(q,visitor(q->code));
-                               break;
-                       }
-               case CALLSTACK_TYPE:
-                       {
-                               callstack *stack = (callstack *)obj;
-                               call_frame_code_block_visitor<Visitor> call_frame_visitor(parent,visitor);
-                               parent->iterate_callstack_object(stack,call_frame_visitor);
-                               break;
-                       }
+                       instruction_operand op(rel.rel_class(),rel.rel_offset() + (cell)(compiled + 1));
+                       cell literal = op.load_value();
+                       code_block *compiled = ((code_block *)literal - 1);
+                       compiled = visitor(compiled);
+                       literal = (cell)compiled->xt();
+                       op.store_value(literal);
                }
        }
+};
 
-       void visit_context_code_blocks()
+template<typename Visitor>
+void code_block_visitor<Visitor>::visit_referenced_code_blocks(code_block *compiled)
+{
+       if(!parent->code->needs_fixup_p(compiled))
        {
-               call_frame_code_block_visitor<Visitor> call_frame_visitor(parent,visitor);
-               parent->iterate_active_frames(call_frame_visitor);
+               referenced_code_blocks_visitor<Visitor> visitor(this->visitor);
+               parent->iterate_relocations(compiled,visitor);
        }
+}
+
+template<typename Visitor>
+void code_block_visitor<Visitor>::visit_context_code_blocks()
+{
+       call_frame_code_block_visitor<Visitor> call_frame_visitor(parent,visitor);
+       parent->iterate_active_frames(call_frame_visitor);
+}
 
-       void visit_callback_code_blocks()
+template<typename Visitor>
+struct callback_code_block_visitor {
+       callback_heap *callbacks;
+       Visitor visitor;
+
+       explicit callback_code_block_visitor(callback_heap *callbacks_, Visitor visitor_) :
+               callbacks(callbacks_), visitor(visitor_) {}
+
+       void operator()(callback *stub)
        {
-               callback_code_block_visitor<Visitor> callback_visitor(parent->callbacks,visitor);
-               parent->callbacks->iterate(callback_visitor);
+               stub->compiled = visitor(stub->compiled);
+               callbacks->update(stub);
        }
-
 };
 
+template<typename Visitor>
+void code_block_visitor<Visitor>::visit_callback_code_blocks()
+{
+       callback_code_block_visitor<Visitor> callback_visitor(parent->callbacks,visitor);
+       parent->callbacks->iterate(callback_visitor);
+}
+
 }
index a7df30d4bfc32f484bc8ad2fa39fc7cd7ef9ef97..ef066f1a13f43d83df323d5a3c00f70f3e90ec9d 100755 (executable)
@@ -161,8 +161,8 @@ void factor_vm::relocate_code_block_step(relocation_entry rel, cell index, code_
                tagged<byte_array>(compiled->relocation).untag_check(this);
 #endif
 
-       embedded_pointer ptr(rel.rel_class(),rel.rel_offset() + (cell)compiled->xt());
-       ptr.store_address(compute_relocation(rel,index,compiled));
+       instruction_operand op(rel.rel_class(),rel.rel_offset() + (cell)compiled->xt());
+       op.store_value(compute_relocation(rel,index,compiled));
 }
 
 struct word_references_updater {
@@ -202,42 +202,6 @@ void factor_vm::update_word_references(code_block *compiled)
        }
 }
 
-/* This runs after a full collection */
-struct literal_and_word_references_updater {
-       factor_vm *parent;
-
-       explicit literal_and_word_references_updater(factor_vm *parent_) : parent(parent_) {}
-
-       void operator()(relocation_entry rel, cell index, code_block *compiled)
-       {
-               relocation_type type = rel.rel_type();
-
-               switch(type)
-               {
-               case RT_IMMEDIATE:
-               case RT_XT:
-               case RT_XT_PIC:
-               case RT_XT_PIC_TAIL:
-                       parent->relocate_code_block_step(rel,index,compiled);
-                       break;
-               default:
-                       break;
-               }
-       }
-};
-
-void factor_vm::update_code_block_words_and_literals(code_block *compiled)
-{
-       if(code->needs_fixup_p(compiled))
-               relocate_code_block(compiled);
-       else
-       {
-               literal_and_word_references_updater updater(this);
-               iterate_relocations(compiled,updater);
-               flush_icache_for(compiled);
-       }
-}
-
 void factor_vm::check_code_address(cell address)
 {
 #ifdef FACTOR_DEBUG
@@ -277,8 +241,8 @@ void factor_vm::fixup_labels(array *labels, code_block *compiled)
                cell offset = untag_fixnum(array_nth(labels,i + 1));
                cell target = untag_fixnum(array_nth(labels,i + 2));
 
-               embedded_pointer ptr(rel_class,offset + (cell)(compiled + 1));
-               ptr.store_address(target + (cell)(compiled + 1));
+               instruction_operand op(rel_class,offset + (cell)(compiled + 1));
+               op.store_value(target + (cell)(compiled + 1));
        }
 }
 
index 98da158b165cbe0cb011cada864658b8d37e78c5..920a6030573607a591d7d61b107d65650457adea 100755 (executable)
@@ -103,25 +103,6 @@ void factor_vm::update_code_heap_words()
        iterate_code_heap(updater);
 }
 
-/* After a full GC that did not grow the heap, we have to update references
-to literals and other words. */
-struct word_and_literal_code_heap_updater {
-       factor_vm *parent;
-
-       explicit word_and_literal_code_heap_updater(factor_vm *parent_) : parent(parent_) {}
-
-       void operator()(code_block *block, cell size)
-       {
-               parent->update_code_block_words_and_literals(block);
-       }
-};
-
-void factor_vm::update_code_heap_words_and_literals()
-{
-       word_and_literal_code_heap_updater updater(this);
-       iterate_code_heap(updater);
-}
-
 /* After growing the heap, we have to perform a full relocation to update
 references to card and deck arrays. */
 struct code_heap_relocator {
index db5b33ba23944884ae32faf093cd504876271915..c59f826225466462377b02dcd9f0f603790b57fc 100644 (file)
@@ -1,12 +1,12 @@
 namespace factor
 {
 
-template<typename TargetGeneration, typename Policy> struct collector_workhorse {
+template<typename TargetGeneration, typename Policy> struct data_workhorse {
        factor_vm *parent;
        TargetGeneration *target;
        Policy policy;
 
-       explicit collector_workhorse(factor_vm *parent_, TargetGeneration *target_, Policy policy_) :
+       explicit data_workhorse(factor_vm *parent_, TargetGeneration *target_, Policy policy_) :
                parent(parent_),
                target(target_),
                policy(policy_) {}
@@ -61,13 +61,13 @@ template<typename TargetGeneration, typename Policy> struct collector_workhorse
 };
 
 template<typename TargetGeneration, typename Policy>
-inline static slot_visitor<collector_workhorse<TargetGeneration,Policy> > make_collector_workhorse(
+inline static slot_visitor<data_workhorse<TargetGeneration,Policy> > make_data_visitor(
        factor_vm *parent,
        TargetGeneration *target,
        Policy policy)
 {
-       return slot_visitor<collector_workhorse<TargetGeneration,Policy> >(parent,
-               collector_workhorse<TargetGeneration,Policy>(parent,target,policy));
+       return slot_visitor<data_workhorse<TargetGeneration,Policy> >(parent,
+               data_workhorse<TargetGeneration,Policy>(parent,target,policy));
 }
 
 struct dummy_unmarker {
@@ -85,12 +85,13 @@ struct full_unmarker {
        void operator()(card *ptr) { *ptr = 0; }
 };
 
-template<typename TargetGeneration, typename Policy> struct collector {
+template<typename TargetGeneration, typename Policy>
+struct collector {
        factor_vm *parent;
        data_heap *data;
        code_heap *code;
        TargetGeneration *target;
-       slot_visitor<collector_workhorse<TargetGeneration,Policy> > workhorse;
+       slot_visitor<data_workhorse<TargetGeneration,Policy> > data_visitor;
        cell cards_scanned;
        cell decks_scanned;
        cell code_blocks_scanned;
@@ -100,37 +101,37 @@ template<typename TargetGeneration, typename Policy> struct collector {
                data(parent_->data),
                code(parent_->code),
                target(target_),
-               workhorse(make_collector_workhorse(parent_,target_,policy_)),
+               data_visitor(make_data_visitor(parent_,target_,policy_)),
                cards_scanned(0),
                decks_scanned(0),
                code_blocks_scanned(0) {}
 
        void trace_handle(cell *handle)
        {
-               workhorse.visit_handle(handle);
+               data_visitor.visit_handle(handle);
        }
 
        void trace_object(object *ptr)
        {
-               workhorse.visit_slots(ptr);
+               data_visitor.visit_slots(ptr);
                if(ptr->type() == ALIEN_TYPE)
                        ((alien *)ptr)->update_address();
        }
 
        void trace_roots()
        {
-               workhorse.visit_roots();
+               data_visitor.visit_roots();
        }
 
        void trace_contexts()
        {
-               workhorse.visit_contexts();
+               data_visitor.visit_contexts();
        }
 
        /* Trace all literals referenced from a code block. Only for aging and nursery collections */
-       void trace_literal_references(code_block *compiled)
+       void trace_referenced_literals(code_block *compiled)
        {
-               workhorse.visit_literal_references(compiled);
+               data_visitor.visit_referenced_literals(compiled);
        }
 
        void trace_code_heap_roots(std::set<code_block *> *remembered_set)
@@ -140,7 +141,7 @@ template<typename TargetGeneration, typename Policy> struct collector {
 
                for(; iter != end; iter++)
                {
-                       trace_literal_references(*iter);
+                       trace_referenced_literals(*iter);
                        code_blocks_scanned++;
                }
        }
@@ -183,7 +184,7 @@ template<typename TargetGeneration, typename Policy> struct collector {
                        cell *end_ptr = (cell *)end;
 
                        for(; slot_ptr < end_ptr; slot_ptr++)
-                               workhorse.visit_handle(slot_ptr);
+                               data_visitor.visit_handle(slot_ptr);
                }
        }
 
index 0bbc7c8d069a41334beadde0b642feed351de310..0c173a84f644931264d2305a72f5023a4d05a15b 100644 (file)
@@ -95,7 +95,7 @@ template<typename SlotForwarder> struct code_block_compaction_updater {
        void operator()(code_block *old_address, code_block *new_address, cell size)
        {
                memmove(new_address,old_address,size);
-               slot_forwarder.visit_literal_references(new_address);
+               slot_forwarder.visit_referenced_literals(new_address);
                parent->relocate_code_block(new_address);
        }
 };
@@ -157,7 +157,7 @@ struct object_code_block_updater {
 };
 
 struct dummy_slot_forwarder {
-       void visit_literal_references(code_block *compiled) {}
+       void visit_referenced_literals(code_block *compiled) {}
 };
 
 /* Compact just the code heap */
index c9d9ef085487bdedaa7253a8f9c223c478f7f0ba..0b79b53238322290c5dab4a4603e8a64dd18fedf 100755 (executable)
@@ -217,7 +217,7 @@ data_heap_room factor_vm::data_room()
        room.tenured_free_block_count = data->tenured->free_block_count();
        room.cards                    = data->cards_end - data->cards;
        room.decks                    = data->decks_end - data->decks;
-       room.mark_stack               = data->tenured->mark_stack.capacity() * sizeof(cell);
+       room.mark_stack               = mark_stack.capacity() * sizeof(cell);
 
        return room;
 }
diff --git a/vm/embedded_pointers.cpp b/vm/embedded_pointers.cpp
deleted file mode 100644 (file)
index 8d368e5..0000000
+++ /dev/null
@@ -1,116 +0,0 @@
-#include "master.hpp"
-
-namespace factor
-{
-
-/* Load a 32-bit value from a PowerPC LIS/ORI sequence */
-fixnum embedded_pointer::load_address_2_2()
-{
-       cell *ptr = (cell *)pointer;
-       cell hi = (ptr[-1] & 0xffff);
-       cell lo = (ptr[ 0] & 0xffff);
-       return hi << 16 | lo;
-}
-
-/* Load a value from a bitfield of a PowerPC instruction */
-fixnum embedded_pointer::load_address_masked(cell mask, fixnum shift)
-{
-       cell *ptr = (cell *)pointer;
-
-       return (*ptr & mask) << shift;
-}
-
-fixnum embedded_pointer::load_address()
-{
-       switch(rel_class)
-       {
-       case RC_ABSOLUTE_CELL:
-               return *(cell *)pointer;
-       case RC_ABSOLUTE:
-               return *(u32*)pointer;
-       case RC_RELATIVE:
-               return *(u32*)pointer + pointer + sizeof(u32);
-       case RC_ABSOLUTE_PPC_2_2:
-               return load_address_2_2();
-       case RC_ABSOLUTE_PPC_2:
-               return load_address_masked(rel_absolute_ppc_2_mask,0);
-       case RC_RELATIVE_PPC_2:
-               return load_address_masked(rel_relative_ppc_2_mask,0) + pointer;
-       case RC_RELATIVE_PPC_3:
-               return load_address_masked(rel_relative_ppc_3_mask,0) + pointer;
-       case RC_RELATIVE_ARM_3:
-               return load_address_masked(rel_relative_arm_3_mask,2) + pointer + sizeof(cell) * 2;
-       case RC_INDIRECT_ARM:
-               return load_address_masked(rel_indirect_arm_mask,0) + pointer + sizeof(cell);
-       case RC_INDIRECT_ARM_PC:
-               return load_address_masked(rel_indirect_arm_mask,0) + pointer + sizeof(cell) * 2;
-       default:
-               critical_error("Bad rel class",rel_class);
-               return 0;
-       }
-}
-
-/* Store a 32-bit value into a PowerPC LIS/ORI sequence */
-void embedded_pointer::store_address_2_2(fixnum value)
-{
-       cell *ptr = (cell *)pointer;
-       ptr[-1] = ((ptr[-1] & ~0xffff) | ((value >> 16) & 0xffff));
-       ptr[ 0] = ((ptr[ 0] & ~0xffff) | (value & 0xffff));
-}
-
-/* Store a value into a bitfield of a PowerPC instruction */
-void embedded_pointer::store_address_masked(fixnum value, cell mask, fixnum shift)
-{
-       cell *ptr = (cell *)pointer;
-
-       /* This is unaccurate but good enough */
-       fixnum test = (fixnum)mask >> 1;
-       if(value <= -test || value >= test)
-               critical_error("Value does not fit inside relocation",0);
-
-       *ptr = ((*ptr & ~mask) | ((value >> shift) & mask));
-}
-
-void embedded_pointer::store_address(fixnum absolute_value)
-{
-       fixnum relative_value = absolute_value - pointer;
-
-       switch(rel_class)
-       {
-       case RC_ABSOLUTE_CELL:
-               *(cell *)pointer = absolute_value;
-               break;
-       case RC_ABSOLUTE:
-               *(u32*)pointer = absolute_value;
-               break;
-       case RC_RELATIVE:
-               *(u32*)pointer = relative_value - sizeof(u32);
-               break;
-       case RC_ABSOLUTE_PPC_2_2:
-               store_address_2_2(absolute_value);
-               break;
-       case RC_ABSOLUTE_PPC_2:
-               store_address_masked(absolute_value,rel_absolute_ppc_2_mask,0);
-               break;
-       case RC_RELATIVE_PPC_2:
-               store_address_masked(relative_value,rel_relative_ppc_2_mask,0);
-               break;
-       case RC_RELATIVE_PPC_3:
-               store_address_masked(relative_value,rel_relative_ppc_3_mask,0);
-               break;
-       case RC_RELATIVE_ARM_3:
-               store_address_masked(relative_value - sizeof(cell) * 2,rel_relative_arm_3_mask,2);
-               break;
-       case RC_INDIRECT_ARM:
-               store_address_masked(relative_value - sizeof(cell),rel_indirect_arm_mask,0);
-               break;
-       case RC_INDIRECT_ARM_PC:
-               store_address_masked(relative_value - sizeof(cell) * 2,rel_indirect_arm_mask,0);
-               break;
-       default:
-               critical_error("Bad rel class",rel_class);
-               break;
-       }
-}
-
-}
diff --git a/vm/embedded_pointers.hpp b/vm/embedded_pointers.hpp
deleted file mode 100644 (file)
index 6943589..0000000
+++ /dev/null
@@ -1,138 +0,0 @@
-namespace factor
-{
-
-enum relocation_type {
-       /* arg is a primitive number */
-       RT_PRIMITIVE,
-       /* arg is a literal table index, holding an array pair (symbol/dll) */
-       RT_DLSYM,
-       /* a pointer to a compiled word reference */
-       RT_DISPATCH,
-       /* a word or quotation's general entry point */
-       RT_XT,
-       /* a word's PIC entry point */
-       RT_XT_PIC,
-       /* a word's tail-call PIC entry point */
-       RT_XT_PIC_TAIL,
-       /* current offset */
-       RT_HERE,
-       /* current code block */
-       RT_THIS,
-       /* immediate literal */
-       RT_IMMEDIATE,
-       /* address of ctx var */
-       RT_CONTEXT,
-       /* untagged fixnum literal */
-       RT_UNTAGGED,
-       /* address of megamorphic_cache_hits var */
-       RT_MEGAMORPHIC_CACHE_HITS,
-       /* address of vm object */
-       RT_VM,
-       /* value of vm->cards_offset */
-       RT_CARDS_OFFSET,
-       /* value of vm->decks_offset */
-       RT_DECKS_OFFSET,
-};
-
-enum relocation_class {
-       /* absolute address in a 64-bit location */
-       RC_ABSOLUTE_CELL,
-       /* absolute address in a 32-bit location */
-       RC_ABSOLUTE,
-       /* relative address in a 32-bit location */
-       RC_RELATIVE,
-       /* absolute address in a PowerPC LIS/ORI sequence */
-       RC_ABSOLUTE_PPC_2_2,
-       /* absolute address in a PowerPC LWZ instruction */
-       RC_ABSOLUTE_PPC_2,
-       /* relative address in a PowerPC LWZ/STW/BC instruction */
-       RC_RELATIVE_PPC_2,
-       /* relative address in a PowerPC B/BL instruction */
-       RC_RELATIVE_PPC_3,
-       /* relative address in an ARM B/BL instruction */
-       RC_RELATIVE_ARM_3,
-       /* pointer to address in an ARM LDR/STR instruction */
-       RC_INDIRECT_ARM,
-       /* pointer to address in an ARM LDR/STR instruction offset by 8 bytes */
-       RC_INDIRECT_ARM_PC
-};
-
-static const cell rel_absolute_ppc_2_mask = 0xffff;
-static const cell rel_relative_ppc_2_mask = 0xfffc;
-static const cell rel_relative_ppc_3_mask = 0x3fffffc;
-static const cell rel_indirect_arm_mask = 0xfff;
-static const cell rel_relative_arm_3_mask = 0xffffff;
-
-/* code relocation table consists of a table of entries for each fixup */
-struct relocation_entry {
-       u32 value;
-
-       relocation_entry(u32 value_) : value(value_) {}
-
-       relocation_entry(relocation_type rel_type,
-               relocation_class rel_class,
-               cell offset)
-       {
-               value = (rel_type << 28) | (rel_class << 24) | offset;
-       }
-
-       relocation_type rel_type()
-       {
-               return (relocation_type)((value & 0xf0000000) >> 28);
-       }
-
-       relocation_class rel_class()
-       {
-               return (relocation_class)((value & 0x0f000000) >> 24);
-       }
-
-       cell rel_offset()
-       {
-               return (value & 0x00ffffff);
-       }
-
-       int number_of_parameters()
-       {
-               switch(rel_type())
-               {
-               case RT_PRIMITIVE:
-               case RT_XT:
-               case RT_XT_PIC:
-               case RT_XT_PIC_TAIL:
-               case RT_IMMEDIATE:
-               case RT_HERE:
-               case RT_UNTAGGED:
-               case RT_VM:
-                       return 1;
-               case RT_DLSYM:
-                       return 2;
-               case RT_THIS:
-               case RT_CONTEXT:
-               case RT_MEGAMORPHIC_CACHE_HITS:
-               case RT_CARDS_OFFSET:
-               case RT_DECKS_OFFSET:
-                       return 0;
-               default:
-                       critical_error("Bad rel type",rel_type());
-                       return -1; /* Can't happen */
-               }
-       }
-};
-
-struct embedded_pointer {
-       cell rel_class;
-       cell pointer;
-
-       embedded_pointer(cell rel_class_, cell pointer_) :
-               rel_class(rel_class_), pointer(pointer_) {}
-
-       fixnum load_address_2_2();
-       fixnum load_address_masked(cell mask, fixnum shift);
-       fixnum load_address();
-
-       void store_address_2_2(fixnum value);
-       void store_address_masked(fixnum value, cell mask, fixnum shift);
-       void store_address(fixnum value);
-};
-
-}
index e6f155e58a020568dba952170cd177c5cdff5ca2..22fb21e2422a006e2669c76df441fe92206851fe 100644 (file)
@@ -3,11 +3,38 @@
 namespace factor
 {
 
+inline static code_block_visitor<code_workhorse> make_code_visitor(factor_vm *parent)
+{
+       return code_block_visitor<code_workhorse>(parent,code_workhorse(parent));
+}
+
 full_collector::full_collector(factor_vm *parent_) :
        collector<tenured_space,full_policy>(
                parent_,
                parent_->data->tenured,
-               full_policy(parent_)) {}
+               full_policy(parent_)),
+       code_visitor(make_code_visitor(parent_)) {}
+
+void full_collector::trace_code_block(code_block *compiled)
+{
+       data_visitor.visit_referenced_literals(compiled);
+       code_visitor.visit_referenced_code_blocks(compiled);
+}
+
+void full_collector::trace_context_code_blocks()
+{
+       code_visitor.visit_context_code_blocks();
+}
+
+void full_collector::trace_callback_code_blocks()
+{
+       code_visitor.visit_callback_code_blocks();
+}
+
+void full_collector::trace_object_code_block(object *obj)
+{
+       code_visitor.visit_object_code_block(obj);
+}
 
 /* After a sweep, invalidate any code heap roots which are not marked,
 so that if a block makes a tail call to a generic word, and the PIC
@@ -57,51 +84,39 @@ void factor_vm::update_code_roots_for_compaction()
        }
 }
 
-struct code_block_marker {
-       code_heap *code;
-       full_collector *collector;
-
-       explicit code_block_marker(code_heap *code_, full_collector *collector_) :
-               code(code_), collector(collector_) {}
-
-       code_block *operator()(code_block *compiled)
-       {
-               if(!code->marked_p(compiled))
-               {
-                       code->set_marked_p(compiled);
-                       collector->trace_literal_references(compiled);
-               }
-
-               return compiled;
-       }
-};
-
 void factor_vm::collect_mark_impl(bool trace_contexts_p)
 {
        full_collector collector(this);
 
+       mark_stack.clear();
+
        code->clear_mark_bits();
        data->tenured->clear_mark_bits();
-       data->tenured->clear_mark_stack();
-
-       code_block_visitor<code_block_marker> code_marker(this,code_block_marker(code,&collector));
 
        collector.trace_roots();
         if(trace_contexts_p)
        {
                collector.trace_contexts();
-               code_marker.visit_context_code_blocks();
-               code_marker.visit_callback_code_blocks();
+               collector.trace_context_code_blocks();
+               collector.trace_callback_code_blocks();
        }
 
-       std::vector<object *> *mark_stack = &data->tenured->mark_stack;
-
-       while(!mark_stack->empty())
+       while(!mark_stack.empty())
        {
-               object *obj = mark_stack->back();
-               mark_stack->pop_back();
-               collector.trace_object(obj);
-               code_marker.visit_object_code_block(obj);
+               cell ptr = mark_stack.back();
+               mark_stack.pop_back();
+
+               if(ptr & 1)
+               {
+                       code_block *compiled = (code_block *)(ptr - 1);
+                       collector.trace_code_block(compiled);
+               }
+               else
+               {
+                       object *obj = (object *)ptr;
+                       collector.trace_object(obj);
+                       collector.trace_object_code_block(obj);
+               }
        }
 
        data->reset_generation(data->tenured);
@@ -133,8 +148,6 @@ void factor_vm::collect_full(bool trace_contexts_p)
                current_gc->event->op = collect_compact_op;
                collect_compact_impl(trace_contexts_p);
        }
-       else
-               update_code_heap_words_and_literals();
 }
 
 void factor_vm::collect_compact(bool trace_contexts_p)
index eb125b7429e9a8c4f3abeca3af3477e6abb1c9aa..e4f1147cbcee5b1b9e493cfa4633de180f730130 100644 (file)
@@ -14,20 +14,43 @@ struct full_policy {
 
        void promoted_object(object *obj)
        {
-               tenured->mark_and_push(obj);
+               tenured->set_marked_p(obj);
+               parent->mark_stack.push_back((cell)obj);
        }
 
        void visited_object(object *obj)
        {
                if(!tenured->marked_p(obj))
-                       tenured->mark_and_push(obj);
+                       promoted_object(obj);
+       }
+};
+
+struct code_workhorse {
+       factor_vm *parent;
+       code_heap *code;
+
+       explicit code_workhorse(factor_vm *parent_) : parent(parent_), code(parent->code) {}
+
+       code_block *operator()(code_block *compiled)
+       {
+               if(!code->marked_p(compiled))
+               {
+                       code->set_marked_p(compiled);
+                       parent->mark_stack.push_back((cell)compiled + 1);
+               }
+
+               return compiled;
        }
 };
 
 struct full_collector : collector<tenured_space,full_policy> {
-       bool trace_contexts_p;
+       code_block_visitor<code_workhorse> code_visitor;
 
        explicit full_collector(factor_vm *parent_);
+       void trace_code_block(code_block *compiled);
+       void trace_context_code_blocks();
+       void trace_callback_code_blocks();
+       void trace_object_code_block(object *obj);
 };
 
 }
diff --git a/vm/instruction_operands.cpp b/vm/instruction_operands.cpp
new file mode 100644 (file)
index 0000000..cc46140
--- /dev/null
@@ -0,0 +1,116 @@
+#include "master.hpp"
+
+namespace factor
+{
+
+/* Load a 32-bit value from a PowerPC LIS/ORI sequence */
+fixnum instruction_operand::load_value_2_2()
+{
+       cell *ptr = (cell *)pointer;
+       cell hi = (ptr[-1] & 0xffff);
+       cell lo = (ptr[ 0] & 0xffff);
+       return hi << 16 | lo;
+}
+
+/* Load a value from a bitfield of a PowerPC instruction */
+fixnum instruction_operand::load_value_masked(cell mask, fixnum shift)
+{
+       cell *ptr = (cell *)pointer;
+
+       return (*ptr & mask) << shift;
+}
+
+fixnum instruction_operand::load_value()
+{
+       switch(rel_class)
+       {
+       case RC_ABSOLUTE_CELL:
+               return *(cell *)pointer;
+       case RC_ABSOLUTE:
+               return *(u32*)pointer;
+       case RC_RELATIVE:
+               return *(s32*)pointer + pointer + sizeof(u32);
+       case RC_ABSOLUTE_PPC_2_2:
+               return load_value_2_2();
+       case RC_ABSOLUTE_PPC_2:
+               return load_value_masked(rel_absolute_ppc_2_mask,0);
+       case RC_RELATIVE_PPC_2:
+               return load_value_masked(rel_relative_ppc_2_mask,0) + pointer;
+       case RC_RELATIVE_PPC_3:
+               return load_value_masked(rel_relative_ppc_3_mask,0) + pointer;
+       case RC_RELATIVE_ARM_3:
+               return load_value_masked(rel_relative_arm_3_mask,2) + pointer + sizeof(cell) * 2;
+       case RC_INDIRECT_ARM:
+               return load_value_masked(rel_indirect_arm_mask,0) + pointer + sizeof(cell);
+       case RC_INDIRECT_ARM_PC:
+               return load_value_masked(rel_indirect_arm_mask,0) + pointer + sizeof(cell) * 2;
+       default:
+               critical_error("Bad rel class",rel_class);
+               return 0;
+       }
+}
+
+/* Store a 32-bit value into a PowerPC LIS/ORI sequence */
+void instruction_operand::store_value_2_2(fixnum value)
+{
+       cell *ptr = (cell *)pointer;
+       ptr[-1] = ((ptr[-1] & ~0xffff) | ((value >> 16) & 0xffff));
+       ptr[ 0] = ((ptr[ 0] & ~0xffff) | (value & 0xffff));
+}
+
+/* Store a value into a bitfield of a PowerPC instruction */
+void instruction_operand::store_value_masked(fixnum value, cell mask, fixnum shift)
+{
+       cell *ptr = (cell *)pointer;
+
+       /* This is unaccurate but good enough */
+       fixnum test = (fixnum)mask >> 1;
+       if(value <= -test || value >= test)
+               critical_error("Value does not fit inside relocation",0);
+
+       *ptr = ((*ptr & ~mask) | ((value >> shift) & mask));
+}
+
+void instruction_operand::store_value(fixnum absolute_value)
+{
+       fixnum relative_value = absolute_value - pointer;
+
+       switch(rel_class)
+       {
+       case RC_ABSOLUTE_CELL:
+               *(cell *)pointer = absolute_value;
+               break;
+       case RC_ABSOLUTE:
+               *(u32*)pointer = absolute_value;
+               break;
+       case RC_RELATIVE:
+               *(s32*)pointer = relative_value - sizeof(u32);
+               break;
+       case RC_ABSOLUTE_PPC_2_2:
+               store_value_2_2(absolute_value);
+               break;
+       case RC_ABSOLUTE_PPC_2:
+               store_value_masked(absolute_value,rel_absolute_ppc_2_mask,0);
+               break;
+       case RC_RELATIVE_PPC_2:
+               store_value_masked(relative_value,rel_relative_ppc_2_mask,0);
+               break;
+       case RC_RELATIVE_PPC_3:
+               store_value_masked(relative_value,rel_relative_ppc_3_mask,0);
+               break;
+       case RC_RELATIVE_ARM_3:
+               store_value_masked(relative_value - sizeof(cell) * 2,rel_relative_arm_3_mask,2);
+               break;
+       case RC_INDIRECT_ARM:
+               store_value_masked(relative_value - sizeof(cell),rel_indirect_arm_mask,0);
+               break;
+       case RC_INDIRECT_ARM_PC:
+               store_value_masked(relative_value - sizeof(cell) * 2,rel_indirect_arm_mask,0);
+               break;
+       default:
+               critical_error("Bad rel class",rel_class);
+               break;
+       }
+}
+
+}
diff --git a/vm/instruction_operands.hpp b/vm/instruction_operands.hpp
new file mode 100644 (file)
index 0000000..554c870
--- /dev/null
@@ -0,0 +1,138 @@
+namespace factor
+{
+
+enum relocation_type {
+       /* arg is a primitive number */
+       RT_PRIMITIVE,
+       /* arg is a literal table index, holding an array pair (symbol/dll) */
+       RT_DLSYM,
+       /* a pointer to a compiled word reference */
+       RT_DISPATCH,
+       /* a word or quotation's general entry point */
+       RT_XT,
+       /* a word's PIC entry point */
+       RT_XT_PIC,
+       /* a word's tail-call PIC entry point */
+       RT_XT_PIC_TAIL,
+       /* current offset */
+       RT_HERE,
+       /* current code block */
+       RT_THIS,
+       /* immediate literal */
+       RT_IMMEDIATE,
+       /* address of ctx var */
+       RT_CONTEXT,
+       /* untagged fixnum literal */
+       RT_UNTAGGED,
+       /* address of megamorphic_cache_hits var */
+       RT_MEGAMORPHIC_CACHE_HITS,
+       /* address of vm object */
+       RT_VM,
+       /* value of vm->cards_offset */
+       RT_CARDS_OFFSET,
+       /* value of vm->decks_offset */
+       RT_DECKS_OFFSET,
+};
+
+enum relocation_class {
+       /* absolute address in a 64-bit location */
+       RC_ABSOLUTE_CELL,
+       /* absolute address in a 32-bit location */
+       RC_ABSOLUTE,
+       /* relative address in a 32-bit location */
+       RC_RELATIVE,
+       /* absolute address in a PowerPC LIS/ORI sequence */
+       RC_ABSOLUTE_PPC_2_2,
+       /* absolute address in a PowerPC LWZ instruction */
+       RC_ABSOLUTE_PPC_2,
+       /* relative address in a PowerPC LWZ/STW/BC instruction */
+       RC_RELATIVE_PPC_2,
+       /* relative address in a PowerPC B/BL instruction */
+       RC_RELATIVE_PPC_3,
+       /* relative address in an ARM B/BL instruction */
+       RC_RELATIVE_ARM_3,
+       /* pointer to address in an ARM LDR/STR instruction */
+       RC_INDIRECT_ARM,
+       /* pointer to address in an ARM LDR/STR instruction offset by 8 bytes */
+       RC_INDIRECT_ARM_PC
+};
+
+static const cell rel_absolute_ppc_2_mask = 0xffff;
+static const cell rel_relative_ppc_2_mask = 0xfffc;
+static const cell rel_relative_ppc_3_mask = 0x3fffffc;
+static const cell rel_indirect_arm_mask = 0xfff;
+static const cell rel_relative_arm_3_mask = 0xffffff;
+
+/* code relocation table consists of a table of entries for each fixup */
+struct relocation_entry {
+       u32 value;
+
+       relocation_entry(u32 value_) : value(value_) {}
+
+       relocation_entry(relocation_type rel_type,
+               relocation_class rel_class,
+               cell offset)
+       {
+               value = (rel_type << 28) | (rel_class << 24) | offset;
+       }
+
+       relocation_type rel_type()
+       {
+               return (relocation_type)((value & 0xf0000000) >> 28);
+       }
+
+       relocation_class rel_class()
+       {
+               return (relocation_class)((value & 0x0f000000) >> 24);
+       }
+
+       cell rel_offset()
+       {
+               return (value & 0x00ffffff);
+       }
+
+       int number_of_parameters()
+       {
+               switch(rel_type())
+               {
+               case RT_PRIMITIVE:
+               case RT_XT:
+               case RT_XT_PIC:
+               case RT_XT_PIC_TAIL:
+               case RT_IMMEDIATE:
+               case RT_HERE:
+               case RT_UNTAGGED:
+               case RT_VM:
+                       return 1;
+               case RT_DLSYM:
+                       return 2;
+               case RT_THIS:
+               case RT_CONTEXT:
+               case RT_MEGAMORPHIC_CACHE_HITS:
+               case RT_CARDS_OFFSET:
+               case RT_DECKS_OFFSET:
+                       return 0;
+               default:
+                       critical_error("Bad rel type",rel_type());
+                       return -1; /* Can't happen */
+               }
+       }
+};
+
+struct instruction_operand {
+       cell rel_class;
+       cell pointer;
+
+       instruction_operand(cell rel_class_, cell pointer_) :
+               rel_class(rel_class_), pointer(pointer_) {}
+
+       fixnum load_value_2_2();
+       fixnum load_value_masked(cell mask, fixnum shift);
+       fixnum load_value();
+
+       void store_value_2_2(fixnum value);
+       void store_value_masked(fixnum value, cell mask, fixnum shift);
+       void store_value(fixnum value);
+};
+
+}
index ba782c3bd78953e7930d3c4fa57cb3c103a5ae5a..7c8598f6e377eac8fe7fa172103c6cd01dc142c4 100755 (executable)
@@ -49,7 +49,7 @@ namespace factor
 #include "errors.hpp"
 #include "bignumint.hpp"
 #include "bignum.hpp"
-#include "embedded_pointers.hpp"
+#include "instruction_operands.hpp"
 #include "code_blocks.hpp"
 #include "bump_allocator.hpp"
 #include "bitwise_hacks.hpp"
index b034eaf803b713fca5f2097212c136f7444f9569..15a74d0312789e2ebdc1e47646baf9a8da67fb83 100644 (file)
@@ -151,9 +151,7 @@ void factor_vm::primitive_become()
           by referencing the old quotation unless we recompile all
           unoptimized words. */
        compile_all_words();
-
-       /* Update references to old objects in the code heap */
-       update_code_heap_words_and_literals();
+       update_code_heap_words();
 }
 
 }
index aa2751d690b3975ae7d73245c6683f04b949d2df..9a403043d1d653e2cfba6bf46e47dbf15ea8eb54 100644 (file)
@@ -17,7 +17,7 @@ template<typename Visitor> struct slot_visitor {
        void visit_bignum_roots();
        void visit_roots();
        void visit_contexts();
-       void visit_literal_references(code_block *compiled);
+       void visit_referenced_literals(code_block *compiled);
 };
 
 template<typename Visitor>
@@ -125,33 +125,34 @@ void slot_visitor<Visitor>::visit_contexts()
 
 template<typename Visitor>
 struct literal_references_visitor {
-       factor_vm *parent;
        slot_visitor<Visitor> *visitor;
 
-       explicit literal_references_visitor(factor_vm *parent_, slot_visitor<Visitor> *visitor_)
-               : parent(parent_), visitor(visitor_) {}
+       explicit literal_references_visitor(slot_visitor<Visitor> *visitor_) : visitor(visitor_) {}
 
        void operator()(relocation_entry rel, cell index, code_block *compiled)
        {
                if(rel.rel_type() == RT_IMMEDIATE)
                {
-                       embedded_pointer ptr(rel.rel_class(),rel.rel_offset() + (cell)(compiled + 1));
-                       cell literal = ptr.load_address();
+                       instruction_operand op(rel.rel_class(),rel.rel_offset() + (cell)(compiled + 1));
+                       cell literal = op.load_address();
                        literal = visitor->visit_pointer(literal);
-                       ptr.store_address(literal);
+                       op.store_address(literal);
                }
        }
 };
 
 template<typename Visitor>
-void slot_visitor<Visitor>::visit_literal_references(code_block *compiled)
+void slot_visitor<Visitor>::visit_referenced_literals(code_block *compiled)
 {
        visit_handle(&compiled->owner);
        visit_handle(&compiled->literals);
        visit_handle(&compiled->relocation);
 
-       literal_references_visitor<Visitor> visitor(parent,this);
-       parent->iterate_relocations(compiled,visitor);
+       if(!parent->code->needs_fixup_p(compiled))
+       {
+               literal_references_visitor<Visitor> visitor(this);
+               parent->iterate_relocations(compiled,visitor);
+       }
 }
 
 }
index baab47e383f3bc3c5435158634ba6795bdcde44e..1b1ff5369c82dbd74e3e2fe5ff8b99ccceeb2ccf 100644 (file)
@@ -3,7 +3,6 @@ namespace factor
 
 struct tenured_space : free_list_allocator<object> {
        object_start_map starts;
-       std::vector<object *> mark_stack;
 
        explicit tenured_space(cell size, cell start) :
                free_list_allocator<object>(size,start), starts(size,start) {}
@@ -37,20 +36,14 @@ struct tenured_space : free_list_allocator<object> {
                state.clear_mark_bits();
        }
 
-       void clear_mark_stack()
-       {
-               mark_stack.clear();
-       }
-
        bool marked_p(object *obj)
        {
                return this->state.marked_p(obj);
        }
 
-       void mark_and_push(object *obj)
+       void set_marked_p(object *obj)
        {
                this->state.set_marked_p(obj);
-               this->mark_stack.push_back(obj);
        }
 
        void sweep()
index b2fe3461b9ffdd02be319a9223d69c7f8b28d1ea..b29affc480ccfbbd3d26d8e2dbf0f8c37b8d593f 100644 (file)
@@ -3,20 +3,20 @@
 namespace factor
 {
 
-to_tenured_collector::to_tenured_collector(factor_vm *myvm_) :
+to_tenured_collector::to_tenured_collector(factor_vm *parent_) :
        collector<tenured_space,to_tenured_policy>(
-               myvm_,
-               myvm_->data->tenured,
-               to_tenured_policy(myvm_)) {}
+               parent_,
+               parent_->data->tenured,
+               to_tenured_policy(parent_)) {}
 
 void to_tenured_collector::tenure_reachable_objects()
 {
-       std::vector<object *> *mark_stack = &this->target->mark_stack;
+       std::vector<cell> *mark_stack = &parent->mark_stack;
        while(!mark_stack->empty())
        {
-               object *obj = mark_stack->back();
+               cell ptr = mark_stack->back();
                mark_stack->pop_back();
-               this->trace_object(obj);
+               this->trace_object((object *)ptr);
        }
 }
 
@@ -25,7 +25,7 @@ void factor_vm::collect_to_tenured()
        /* Copy live objects from aging space to tenured space. */
        to_tenured_collector collector(this);
 
-       data->tenured->clear_mark_stack();
+       mark_stack.clear();
 
        collector.trace_roots();
        collector.trace_contexts();
index 2f2717efd1c2b2cc69dc94576c0748a4506c52a0..8709b9a221855a5dd2aa96d7cb937a1af8582f66 100644 (file)
@@ -2,10 +2,10 @@ namespace factor
 {
 
 struct to_tenured_policy {
-       factor_vm *myvm;
+       factor_vm *parent;
        tenured_space *tenured;
 
-       explicit to_tenured_policy(factor_vm *myvm_) : myvm(myvm_), tenured(myvm->data->tenured) {}
+       explicit to_tenured_policy(factor_vm *parent_) : parent(parent_), tenured(parent->data->tenured) {}
 
        bool should_copy_p(object *untagged)
        {
@@ -14,14 +14,14 @@ struct to_tenured_policy {
 
        void promoted_object(object *obj)
        {
-               tenured->mark_stack.push_back(obj);
+               parent->mark_stack.push_back((cell)obj);
        }
 
        void visited_object(object *obj) {}
 };
 
 struct to_tenured_collector : collector<tenured_space,to_tenured_policy> {
-       explicit to_tenured_collector(factor_vm *myvm_);
+       explicit to_tenured_collector(factor_vm *parent_);
        void tenure_reachable_objects();
 };
 
index 5548f7190581cfc32740110ada713e2b8b0d8b7d..e63202f09e46f27cc4a5ec661f4f586677f33e57 100755 (executable)
--- a/vm/vm.hpp
+++ b/vm/vm.hpp
@@ -55,6 +55,9 @@ struct factor_vm
        /* Only set if we're performing a GC */
        gc_state *current_gc;
 
+       /* Mark stack */
+       std::vector<cell> mark_stack;
+
        /* If not NULL, we push GC events here */
        std::vector<gc_event> *gc_events;
 
@@ -525,7 +528,6 @@ struct factor_vm
 
        void relocate_code_block_step(relocation_entry rel, cell index, code_block *compiled);
        void update_word_references(code_block *compiled);
-       void update_code_block_words_and_literals(code_block *compiled);
        void check_code_address(cell address);
        void relocate_code_block(code_block *compiled);
        void fixup_labels(array *labels, code_block *compiled);
@@ -544,7 +546,6 @@ struct factor_vm
        bool in_code_heap_p(cell ptr);
        void jit_compile_word(cell word_, cell def_, bool relocate);
        void update_code_heap_words();
-       void update_code_heap_words_and_literals();
        void primitive_modify_code_heap();
        code_heap_room code_room();
        void primitive_code_room();