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/data_heap_checker.o \
vm/debug.o \ vm/debug.o \
vm/dispatch.o \ vm/dispatch.o \
vm/embedded_pointers.o \
vm/errors.o \ vm/errors.o \
vm/factor.o \ vm/factor.o \
vm/free_list.o \ vm/free_list.o \
@ -55,6 +54,7 @@ DLL_OBJS = $(PLAF_DLL_OBJS) \
vm/gc.o \ vm/gc.o \
vm/image.o \ vm/image.o \
vm/inline_cache.o \ vm/inline_cache.o \
vm/instruction_operands.o \
vm/io.o \ vm/io.o \
vm/jit.o \ vm/jit.o \
vm/math.o \ vm/math.o \

View File

@ -22,7 +22,7 @@ void factor_vm::collect_aging()
to_tenured_collector collector(this); to_tenured_collector collector(this);
current_gc->event->started_code_scan(); current_gc->event->started_card_scan();
collector.trace_cards(data->tenured, collector.trace_cards(data->tenured,
card_points_to_aging, card_points_to_aging,
full_unmarker()); 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 rel_class = untag_fixnum(array_nth(code_template.untagged(),1));
cell offset = untag_fixnum(array_nth(code_template.untagged(),3)); cell offset = untag_fixnum(array_nth(code_template.untagged(),3));
embedded_pointer ptr(rel_class,offset + (cell)(stub + 1)); instruction_operand op(rel_class,offset + (cell)(stub + 1));
ptr.store_address((cell)(stub->compiled + 1)); op.store_value((cell)(stub->compiled + 1));
flush_icache((cell)stub,stub->size); flush_icache((cell)stub,stub->size);
} }

View File

@ -1,7 +1,21 @@
namespace factor 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; factor_vm *parent;
Visitor visitor; Visitor visitor;
@ -19,29 +33,9 @@ template<typename Visitor> struct call_frame_code_block_visitor {
} }
}; };
template<typename Visitor> struct callback_code_block_visitor { template<typename Visitor>
callback_heap *callbacks; void code_block_visitor<Visitor>::visit_object_code_block(object *obj)
Visitor visitor; {
explicit callback_code_block_visitor(callback_heap *callbacks_, Visitor visitor_) :
callbacks(callbacks_), visitor(visitor_) {}
void operator()(callback *stub)
{
stub->compiled = visitor(stub->compiled);
callbacks->update(stub);
}
};
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()) switch(obj->type())
{ {
case WORD_TYPE: case WORD_TYPE:
@ -70,20 +64,66 @@ template<typename Visitor> struct code_block_visitor {
break; break;
} }
} }
} }
void visit_context_code_blocks() 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)
{ {
call_frame_code_block_visitor<Visitor> call_frame_visitor(parent,visitor); relocation_type type = rel.rel_type();
parent->iterate_active_frames(call_frame_visitor); if(type == RT_XT || type == RT_XT_PIC || type == RT_XT_PIC_TAIL)
}
void visit_callback_code_blocks()
{ {
callback_code_block_visitor<Visitor> callback_visitor(parent->callbacks,visitor); instruction_operand op(rel.rel_class(),rel.rel_offset() + (cell)(compiled + 1));
parent->callbacks->iterate(callback_visitor); 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;
explicit callback_code_block_visitor(callback_heap *callbacks_, Visitor visitor_) :
callbacks(callbacks_), visitor(visitor_) {}
void operator()(callback *stub)
{
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);
}
} }

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); tagged<byte_array>(compiled->relocation).untag_check(this);
#endif #endif
embedded_pointer ptr(rel.rel_class(),rel.rel_offset() + (cell)compiled->xt()); instruction_operand op(rel.rel_class(),rel.rel_offset() + (cell)compiled->xt());
ptr.store_address(compute_relocation(rel,index,compiled)); op.store_value(compute_relocation(rel,index,compiled));
} }
struct word_references_updater { 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) void factor_vm::check_code_address(cell address)
{ {
#ifdef FACTOR_DEBUG #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 offset = untag_fixnum(array_nth(labels,i + 1));
cell target = untag_fixnum(array_nth(labels,i + 2)); cell target = untag_fixnum(array_nth(labels,i + 2));
embedded_pointer ptr(rel_class,offset + (cell)(compiled + 1)); instruction_operand op(rel_class,offset + (cell)(compiled + 1));
ptr.store_address(target + (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); 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 /* After growing the heap, we have to perform a full relocation to update
references to card and deck arrays. */ references to card and deck arrays. */
struct code_heap_relocator { struct code_heap_relocator {

View File

@ -1,12 +1,12 @@
namespace factor namespace factor
{ {
template<typename TargetGeneration, typename Policy> struct collector_workhorse { template<typename TargetGeneration, typename Policy> struct data_workhorse {
factor_vm *parent; factor_vm *parent;
TargetGeneration *target; TargetGeneration *target;
Policy policy; Policy policy;
explicit collector_workhorse(factor_vm *parent_, TargetGeneration *target_, Policy policy_) : explicit data_workhorse(factor_vm *parent_, TargetGeneration *target_, Policy policy_) :
parent(parent_), parent(parent_),
target(target_), target(target_),
policy(policy_) {} policy(policy_) {}
@ -61,13 +61,13 @@ template<typename TargetGeneration, typename Policy> struct collector_workhorse
}; };
template<typename TargetGeneration, typename Policy> 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, factor_vm *parent,
TargetGeneration *target, TargetGeneration *target,
Policy policy) Policy policy)
{ {
return slot_visitor<collector_workhorse<TargetGeneration,Policy> >(parent, return slot_visitor<data_workhorse<TargetGeneration,Policy> >(parent,
collector_workhorse<TargetGeneration,Policy>(parent,target,policy)); data_workhorse<TargetGeneration,Policy>(parent,target,policy));
} }
struct dummy_unmarker { struct dummy_unmarker {
@ -85,12 +85,13 @@ struct full_unmarker {
void operator()(card *ptr) { *ptr = 0; } void operator()(card *ptr) { *ptr = 0; }
}; };
template<typename TargetGeneration, typename Policy> struct collector { template<typename TargetGeneration, typename Policy>
struct collector {
factor_vm *parent; factor_vm *parent;
data_heap *data; data_heap *data;
code_heap *code; code_heap *code;
TargetGeneration *target; TargetGeneration *target;
slot_visitor<collector_workhorse<TargetGeneration,Policy> > workhorse; slot_visitor<data_workhorse<TargetGeneration,Policy> > data_visitor;
cell cards_scanned; cell cards_scanned;
cell decks_scanned; cell decks_scanned;
cell code_blocks_scanned; cell code_blocks_scanned;
@ -100,37 +101,37 @@ template<typename TargetGeneration, typename Policy> struct collector {
data(parent_->data), data(parent_->data),
code(parent_->code), code(parent_->code),
target(target_), target(target_),
workhorse(make_collector_workhorse(parent_,target_,policy_)), data_visitor(make_data_visitor(parent_,target_,policy_)),
cards_scanned(0), cards_scanned(0),
decks_scanned(0), decks_scanned(0),
code_blocks_scanned(0) {} code_blocks_scanned(0) {}
void trace_handle(cell *handle) void trace_handle(cell *handle)
{ {
workhorse.visit_handle(handle); data_visitor.visit_handle(handle);
} }
void trace_object(object *ptr) void trace_object(object *ptr)
{ {
workhorse.visit_slots(ptr); data_visitor.visit_slots(ptr);
if(ptr->type() == ALIEN_TYPE) if(ptr->type() == ALIEN_TYPE)
((alien *)ptr)->update_address(); ((alien *)ptr)->update_address();
} }
void trace_roots() void trace_roots()
{ {
workhorse.visit_roots(); data_visitor.visit_roots();
} }
void trace_contexts() void trace_contexts()
{ {
workhorse.visit_contexts(); data_visitor.visit_contexts();
} }
/* Trace all literals referenced from a code block. Only for aging and nursery collections */ /* 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) 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++) for(; iter != end; iter++)
{ {
trace_literal_references(*iter); trace_referenced_literals(*iter);
code_blocks_scanned++; code_blocks_scanned++;
} }
} }
@ -183,7 +184,7 @@ template<typename TargetGeneration, typename Policy> struct collector {
cell *end_ptr = (cell *)end; cell *end_ptr = (cell *)end;
for(; slot_ptr < end_ptr; slot_ptr++) 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) void operator()(code_block *old_address, code_block *new_address, cell size)
{ {
memmove(new_address,old_address,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); parent->relocate_code_block(new_address);
} }
}; };
@ -157,7 +157,7 @@ struct object_code_block_updater {
}; };
struct dummy_slot_forwarder { struct dummy_slot_forwarder {
void visit_literal_references(code_block *compiled) {} void visit_referenced_literals(code_block *compiled) {}
}; };
/* Compact just the code heap */ /* 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.tenured_free_block_count = data->tenured->free_block_count();
room.cards = data->cards_end - data->cards; room.cards = data->cards_end - data->cards;
room.decks = data->decks_end - data->decks; 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; return room;
} }

View File

@ -3,11 +3,38 @@
namespace factor 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_) : full_collector::full_collector(factor_vm *parent_) :
collector<tenured_space,full_policy>( collector<tenured_space,full_policy>(
parent_, parent_,
parent_->data->tenured, 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, /* 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 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) void factor_vm::collect_mark_impl(bool trace_contexts_p)
{ {
full_collector collector(this); full_collector collector(this);
mark_stack.clear();
code->clear_mark_bits(); code->clear_mark_bits();
data->tenured->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(); collector.trace_roots();
if(trace_contexts_p) if(trace_contexts_p)
{ {
collector.trace_contexts(); collector.trace_contexts();
code_marker.visit_context_code_blocks(); collector.trace_context_code_blocks();
code_marker.visit_callback_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(); cell ptr = mark_stack.back();
mark_stack->pop_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(obj);
code_marker.visit_object_code_block(obj); collector.trace_object_code_block(obj);
}
} }
data->reset_generation(data->tenured); 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; current_gc->event->op = collect_compact_op;
collect_compact_impl(trace_contexts_p); collect_compact_impl(trace_contexts_p);
} }
else
update_code_heap_words_and_literals();
} }
void factor_vm::collect_compact(bool trace_contexts_p) void factor_vm::collect_compact(bool trace_contexts_p)

View File

@ -14,20 +14,43 @@ struct full_policy {
void promoted_object(object *obj) 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) void visited_object(object *obj)
{ {
if(!tenured->marked_p(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> { 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_); 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 */ /* 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 *ptr = (cell *)pointer;
cell hi = (ptr[-1] & 0xffff); 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 */ /* 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; cell *ptr = (cell *)pointer;
return (*ptr & mask) << shift; return (*ptr & mask) << shift;
} }
fixnum embedded_pointer::load_address() fixnum instruction_operand::load_value()
{ {
switch(rel_class) switch(rel_class)
{ {
@ -29,21 +29,21 @@ fixnum embedded_pointer::load_address()
case RC_ABSOLUTE: case RC_ABSOLUTE:
return *(u32*)pointer; return *(u32*)pointer;
case RC_RELATIVE: case RC_RELATIVE:
return *(u32*)pointer + pointer + sizeof(u32); return *(s32*)pointer + pointer + sizeof(u32);
case RC_ABSOLUTE_PPC_2_2: case RC_ABSOLUTE_PPC_2_2:
return load_address_2_2(); return load_value_2_2();
case RC_ABSOLUTE_PPC_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: 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: 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: 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: 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: 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: default:
critical_error("Bad rel class",rel_class); critical_error("Bad rel class",rel_class);
return 0; return 0;
@ -51,7 +51,7 @@ fixnum embedded_pointer::load_address()
} }
/* Store a 32-bit value into a PowerPC LIS/ORI sequence */ /* 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; cell *ptr = (cell *)pointer;
ptr[-1] = ((ptr[-1] & ~0xffff) | ((value >> 16) & 0xffff)); 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 */ /* 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; 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)); *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; fixnum relative_value = absolute_value - pointer;
@ -84,28 +84,28 @@ void embedded_pointer::store_address(fixnum absolute_value)
*(u32*)pointer = absolute_value; *(u32*)pointer = absolute_value;
break; break;
case RC_RELATIVE: case RC_RELATIVE:
*(u32*)pointer = relative_value - sizeof(u32); *(s32*)pointer = relative_value - sizeof(u32);
break; break;
case RC_ABSOLUTE_PPC_2_2: case RC_ABSOLUTE_PPC_2_2:
store_address_2_2(absolute_value); store_value_2_2(absolute_value);
break; break;
case RC_ABSOLUTE_PPC_2: 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; break;
case RC_RELATIVE_PPC_2: 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; break;
case RC_RELATIVE_PPC_3: 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; break;
case RC_RELATIVE_ARM_3: 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; break;
case RC_INDIRECT_ARM: 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; break;
case RC_INDIRECT_ARM_PC: 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; break;
default: default:
critical_error("Bad rel class",rel_class); 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 rel_class;
cell pointer; cell pointer;
embedded_pointer(cell rel_class_, cell pointer_) : instruction_operand(cell rel_class_, cell pointer_) :
rel_class(rel_class_), pointer(pointer_) {} rel_class(rel_class_), pointer(pointer_) {}
fixnum load_address_2_2(); fixnum load_value_2_2();
fixnum load_address_masked(cell mask, fixnum shift); fixnum load_value_masked(cell mask, fixnum shift);
fixnum load_address(); fixnum load_value();
void store_address_2_2(fixnum value); void store_value_2_2(fixnum value);
void store_address_masked(fixnum value, cell mask, fixnum shift); void store_value_masked(fixnum value, cell mask, fixnum shift);
void store_address(fixnum value); void store_value(fixnum value);
}; };
} }

View File

@ -49,7 +49,7 @@ namespace factor
#include "errors.hpp" #include "errors.hpp"
#include "bignumint.hpp" #include "bignumint.hpp"
#include "bignum.hpp" #include "bignum.hpp"
#include "embedded_pointers.hpp" #include "instruction_operands.hpp"
#include "code_blocks.hpp" #include "code_blocks.hpp"
#include "bump_allocator.hpp" #include "bump_allocator.hpp"
#include "bitwise_hacks.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 by referencing the old quotation unless we recompile all
unoptimized words. */ unoptimized words. */
compile_all_words(); compile_all_words();
update_code_heap_words();
/* Update references to old objects in the code heap */
update_code_heap_words_and_literals();
} }
} }

View File

@ -17,7 +17,7 @@ template<typename Visitor> struct slot_visitor {
void visit_bignum_roots(); void visit_bignum_roots();
void visit_roots(); void visit_roots();
void visit_contexts(); void visit_contexts();
void visit_literal_references(code_block *compiled); void visit_referenced_literals(code_block *compiled);
}; };
template<typename Visitor> template<typename Visitor>
@ -125,33 +125,34 @@ void slot_visitor<Visitor>::visit_contexts()
template<typename Visitor> template<typename Visitor>
struct literal_references_visitor { struct literal_references_visitor {
factor_vm *parent;
slot_visitor<Visitor> *visitor; slot_visitor<Visitor> *visitor;
explicit literal_references_visitor(factor_vm *parent_, slot_visitor<Visitor> *visitor_) explicit literal_references_visitor(slot_visitor<Visitor> *visitor_) : visitor(visitor_) {}
: parent(parent_), visitor(visitor_) {}
void operator()(relocation_entry rel, cell index, code_block *compiled) void operator()(relocation_entry rel, cell index, code_block *compiled)
{ {
if(rel.rel_type() == RT_IMMEDIATE) if(rel.rel_type() == RT_IMMEDIATE)
{ {
embedded_pointer ptr(rel.rel_class(),rel.rel_offset() + (cell)(compiled + 1)); instruction_operand op(rel.rel_class(),rel.rel_offset() + (cell)(compiled + 1));
cell literal = ptr.load_address(); cell literal = op.load_address();
literal = visitor->visit_pointer(literal); literal = visitor->visit_pointer(literal);
ptr.store_address(literal); op.store_address(literal);
} }
} }
}; };
template<typename Visitor> 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->owner);
visit_handle(&compiled->literals); visit_handle(&compiled->literals);
visit_handle(&compiled->relocation); visit_handle(&compiled->relocation);
literal_references_visitor<Visitor> visitor(parent,this); if(!parent->code->needs_fixup_p(compiled))
{
literal_references_visitor<Visitor> visitor(this);
parent->iterate_relocations(compiled,visitor); parent->iterate_relocations(compiled,visitor);
}
} }
} }

View File

@ -3,7 +3,6 @@ namespace factor
struct tenured_space : free_list_allocator<object> { struct tenured_space : free_list_allocator<object> {
object_start_map starts; object_start_map starts;
std::vector<object *> mark_stack;
explicit tenured_space(cell size, cell start) : explicit tenured_space(cell size, cell start) :
free_list_allocator<object>(size,start), starts(size,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(); state.clear_mark_bits();
} }
void clear_mark_stack()
{
mark_stack.clear();
}
bool marked_p(object *obj) bool marked_p(object *obj)
{ {
return this->state.marked_p(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->state.set_marked_p(obj);
this->mark_stack.push_back(obj);
} }
void sweep() void sweep()

View File

@ -3,20 +3,20 @@
namespace factor 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>( collector<tenured_space,to_tenured_policy>(
myvm_, parent_,
myvm_->data->tenured, parent_->data->tenured,
to_tenured_policy(myvm_)) {} to_tenured_policy(parent_)) {}
void to_tenured_collector::tenure_reachable_objects() 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()) while(!mark_stack->empty())
{ {
object *obj = mark_stack->back(); cell ptr = mark_stack->back();
mark_stack->pop_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. */ /* Copy live objects from aging space to tenured space. */
to_tenured_collector collector(this); to_tenured_collector collector(this);
data->tenured->clear_mark_stack(); mark_stack.clear();
collector.trace_roots(); collector.trace_roots();
collector.trace_contexts(); collector.trace_contexts();

View File

@ -2,10 +2,10 @@ namespace factor
{ {
struct to_tenured_policy { struct to_tenured_policy {
factor_vm *myvm; factor_vm *parent;
tenured_space *tenured; 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) bool should_copy_p(object *untagged)
{ {
@ -14,14 +14,14 @@ struct to_tenured_policy {
void promoted_object(object *obj) void promoted_object(object *obj)
{ {
tenured->mark_stack.push_back(obj); parent->mark_stack.push_back((cell)obj);
} }
void visited_object(object *obj) {} void visited_object(object *obj) {}
}; };
struct to_tenured_collector : collector<tenured_space,to_tenured_policy> { 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(); void tenure_reachable_objects();
}; };

View File

@ -55,6 +55,9 @@ struct factor_vm
/* Only set if we're performing a GC */ /* Only set if we're performing a GC */
gc_state *current_gc; gc_state *current_gc;
/* Mark stack */
std::vector<cell> mark_stack;
/* If not NULL, we push GC events here */ /* If not NULL, we push GC events here */
std::vector<gc_event> *gc_events; 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 relocate_code_block_step(relocation_entry rel, cell index, code_block *compiled);
void update_word_references(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 check_code_address(cell address);
void relocate_code_block(code_block *compiled); void relocate_code_block(code_block *compiled);
void fixup_labels(array *labels, 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); bool in_code_heap_p(cell ptr);
void jit_compile_word(cell word_, cell def_, bool relocate); void jit_compile_word(cell word_, cell def_, bool relocate);
void update_code_heap_words(); void update_code_heap_words();
void update_code_heap_words_and_literals();
void primitive_modify_code_heap(); void primitive_modify_code_heap();
code_heap_room code_room(); code_heap_room code_room();
void primitive_code_room(); void primitive_code_room();