vm: mark sweep now traces code block references; rename embedded_pointer to instruction_operand

db4
Slava Pestov 2009-11-23 18:51:08 -06:00
parent f96b127ba9
commit 001a3f2847
20 changed files with 254 additions and 239 deletions

View File

@ -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 \

View 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());

View 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);
}

View 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,7 +33,79 @@ template<typename Visitor> struct call_frame_code_block_visitor {
}
};
template<typename Visitor> struct callback_code_block_visitor {
template<typename Visitor>
void code_block_visitor<Visitor>::visit_object_code_block(object *obj)
{
switch(obj->type())
{
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 referenced_code_blocks_visitor {
Visitor visitor;
explicit referenced_code_blocks_visitor(Visitor visitor_) : visitor(visitor_) {}
void operator()(relocation_entry rel, cell index, code_block *compiled)
{
relocation_type type = rel.rel_type();
if(type == RT_XT || type == RT_XT_PIC || type == RT_XT_PIC_TAIL)
{
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);
}
}
};
template<typename Visitor>
void code_block_visitor<Visitor>::visit_referenced_code_blocks(code_block *compiled)
{
if(!parent->code->needs_fixup_p(compiled))
{
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);
}
template<typename Visitor>
struct callback_code_block_visitor {
callback_heap *callbacks;
Visitor visitor;
@ -33,57 +119,11 @@ template<typename Visitor> struct callback_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)
{
switch(obj->type())
{
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;
}
}
}
void 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()
{
callback_code_block_visitor<Visitor> callback_visitor(parent->callbacks,visitor);
parent->callbacks->iterate(callback_visitor);
}
};
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);
}
}

View File

@ -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));
}
}

View File

@ -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 {

View 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);
}
}

View 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 */

View File

@ -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;
}

View 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)

View 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);
};
}

View File

@ -4,7 +4,7 @@ namespace factor
{
/* Load a 32-bit value from a PowerPC LIS/ORI sequence */
fixnum embedded_pointer::load_address_2_2()
fixnum instruction_operand::load_value_2_2()
{
cell *ptr = (cell *)pointer;
cell hi = (ptr[-1] & 0xffff);
@ -13,14 +13,14 @@ fixnum embedded_pointer::load_address_2_2()
}
/* Load a value from a bitfield of a PowerPC instruction */
fixnum embedded_pointer::load_address_masked(cell mask, fixnum shift)
fixnum instruction_operand::load_value_masked(cell mask, fixnum shift)
{
cell *ptr = (cell *)pointer;
return (*ptr & mask) << shift;
}
fixnum embedded_pointer::load_address()
fixnum instruction_operand::load_value()
{
switch(rel_class)
{
@ -29,21 +29,21 @@ fixnum embedded_pointer::load_address()
case RC_ABSOLUTE:
return *(u32*)pointer;
case RC_RELATIVE:
return *(u32*)pointer + pointer + sizeof(u32);
return *(s32*)pointer + pointer + sizeof(u32);
case RC_ABSOLUTE_PPC_2_2:
return load_address_2_2();
return load_value_2_2();
case RC_ABSOLUTE_PPC_2:
return load_address_masked(rel_absolute_ppc_2_mask,0);
return load_value_masked(rel_absolute_ppc_2_mask,0);
case RC_RELATIVE_PPC_2:
return load_address_masked(rel_relative_ppc_2_mask,0) + pointer;
return load_value_masked(rel_relative_ppc_2_mask,0) + pointer;
case RC_RELATIVE_PPC_3:
return load_address_masked(rel_relative_ppc_3_mask,0) + pointer;
return load_value_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;
return load_value_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);
return load_value_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;
return load_value_masked(rel_indirect_arm_mask,0) + pointer + sizeof(cell) * 2;
default:
critical_error("Bad rel class",rel_class);
return 0;
@ -51,7 +51,7 @@ fixnum embedded_pointer::load_address()
}
/* Store a 32-bit value into a PowerPC LIS/ORI sequence */
void embedded_pointer::store_address_2_2(fixnum value)
void instruction_operand::store_value_2_2(fixnum value)
{
cell *ptr = (cell *)pointer;
ptr[-1] = ((ptr[-1] & ~0xffff) | ((value >> 16) & 0xffff));
@ -59,7 +59,7 @@ void embedded_pointer::store_address_2_2(fixnum value)
}
/* Store a value into a bitfield of a PowerPC instruction */
void embedded_pointer::store_address_masked(fixnum value, cell mask, fixnum shift)
void instruction_operand::store_value_masked(fixnum value, cell mask, fixnum shift)
{
cell *ptr = (cell *)pointer;
@ -71,7 +71,7 @@ void embedded_pointer::store_address_masked(fixnum value, cell mask, fixnum shif
*ptr = ((*ptr & ~mask) | ((value >> shift) & mask));
}
void embedded_pointer::store_address(fixnum absolute_value)
void instruction_operand::store_value(fixnum absolute_value)
{
fixnum relative_value = absolute_value - pointer;
@ -84,28 +84,28 @@ void embedded_pointer::store_address(fixnum absolute_value)
*(u32*)pointer = absolute_value;
break;
case RC_RELATIVE:
*(u32*)pointer = relative_value - sizeof(u32);
*(s32*)pointer = relative_value - sizeof(u32);
break;
case RC_ABSOLUTE_PPC_2_2:
store_address_2_2(absolute_value);
store_value_2_2(absolute_value);
break;
case RC_ABSOLUTE_PPC_2:
store_address_masked(absolute_value,rel_absolute_ppc_2_mask,0);
store_value_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);
store_value_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);
store_value_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);
store_value_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);
store_value_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);
store_value_masked(relative_value - sizeof(cell) * 2,rel_indirect_arm_mask,0);
break;
default:
critical_error("Bad rel class",rel_class);

View File

@ -119,20 +119,20 @@ struct relocation_entry {
}
};
struct embedded_pointer {
struct instruction_operand {
cell rel_class;
cell pointer;
embedded_pointer(cell rel_class_, cell pointer_) :
instruction_operand(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();
fixnum load_value_2_2();
fixnum load_value_masked(cell mask, fixnum shift);
fixnum load_value();
void store_address_2_2(fixnum value);
void store_address_masked(fixnum value, cell mask, fixnum shift);
void store_address(fixnum value);
void store_value_2_2(fixnum value);
void store_value_masked(fixnum value, cell mask, fixnum shift);
void store_value(fixnum value);
};
}

View File

@ -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"

View 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();
}
}

View 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);
}
}
}

View 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()

View 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();

View 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();
};

View File

@ -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();