vm: mark sweep now traces code block references; rename embedded_pointer to instruction_operand
parent
f96b127ba9
commit
001a3f2847
2
Makefile
2
Makefile
|
@ -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 \
|
||||||
|
|
|
@ -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());
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
|
@ -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);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -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));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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 {
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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 */
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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);
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -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);
|
|
@ -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);
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
|
@ -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"
|
||||||
|
|
|
@ -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();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -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);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -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()
|
||||||
|
|
|
@ -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();
|
||||||
|
|
|
@ -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();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -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();
|
||||||
|
|
Loading…
Reference in New Issue