vm: minor GC traces embedded pointers
parent
57fe0dea48
commit
b28619ce2f
|
@ -33,10 +33,6 @@ void factor_vm::collect_aging()
|
||||||
current_gc->event->ended_code_scan(collector.code_blocks_scanned);
|
current_gc->event->ended_code_scan(collector.code_blocks_scanned);
|
||||||
|
|
||||||
collector.tenure_reachable_objects();
|
collector.tenure_reachable_objects();
|
||||||
|
|
||||||
current_gc->event->started_code_sweep();
|
|
||||||
update_code_heap_for_minor_gc(&code->points_to_aging);
|
|
||||||
current_gc->event->ended_code_sweep();
|
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
/* If collection fails here, do a to_tenured collection. */
|
/* If collection fails here, do a to_tenured collection. */
|
||||||
|
|
|
@ -151,51 +151,6 @@ cell factor_vm::compute_relocation(relocation_entry rel, cell index, code_block
|
||||||
#undef ARG
|
#undef ARG
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename Iterator> void factor_vm::iterate_relocations(code_block *compiled, Iterator &iter)
|
|
||||||
{
|
|
||||||
if(to_boolean(compiled->relocation))
|
|
||||||
{
|
|
||||||
byte_array *relocation = untag<byte_array>(compiled->relocation);
|
|
||||||
|
|
||||||
cell index = 0;
|
|
||||||
cell length = array_capacity(relocation) / sizeof(relocation_entry);
|
|
||||||
|
|
||||||
for(cell i = 0; i < length; i++)
|
|
||||||
{
|
|
||||||
relocation_entry rel = relocation->data<relocation_entry>()[i];
|
|
||||||
iter(rel,index,compiled);
|
|
||||||
index += rel.number_of_parameters();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
struct literal_references_updater {
|
|
||||||
factor_vm *parent;
|
|
||||||
|
|
||||||
explicit literal_references_updater(factor_vm *parent_) : parent(parent_) {}
|
|
||||||
|
|
||||||
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));
|
|
||||||
array *literals = untag<array>(compiled->literals);
|
|
||||||
ptr.store_address(array_nth(literals,index));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
/* Update pointers to literals from compiled code. */
|
|
||||||
void factor_vm::update_literal_references(code_block *compiled)
|
|
||||||
{
|
|
||||||
if(!code->needs_fixup_p(compiled))
|
|
||||||
{
|
|
||||||
literal_references_updater updater(this);
|
|
||||||
iterate_relocations(compiled,updater);
|
|
||||||
flush_icache_for(compiled);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Compute an address to store at a relocation */
|
/* Compute an address to store at a relocation */
|
||||||
void factor_vm::relocate_code_block_step(relocation_entry rel, cell index, code_block *compiled)
|
void factor_vm::relocate_code_block_step(relocation_entry rel, cell index, code_block *compiled)
|
||||||
{
|
{
|
||||||
|
|
|
@ -114,9 +114,10 @@ void factor_vm::collect_sweep_impl()
|
||||||
{
|
{
|
||||||
current_gc->event->started_data_sweep();
|
current_gc->event->started_data_sweep();
|
||||||
data->tenured->sweep();
|
data->tenured->sweep();
|
||||||
update_code_roots_for_sweep();
|
|
||||||
current_gc->event->ended_data_sweep();
|
current_gc->event->ended_data_sweep();
|
||||||
|
|
||||||
|
update_code_roots_for_sweep();
|
||||||
|
|
||||||
current_gc->event->started_code_sweep();
|
current_gc->event->started_code_sweep();
|
||||||
code->allocator->sweep();
|
code->allocator->sweep();
|
||||||
current_gc->event->ended_code_sweep();
|
current_gc->event->ended_code_sweep();
|
||||||
|
|
|
@ -126,15 +126,6 @@ void factor_vm::start_gc_again()
|
||||||
current_gc->event = new gc_event(current_gc->op,this);
|
current_gc->event = new gc_event(current_gc->op,this);
|
||||||
}
|
}
|
||||||
|
|
||||||
void factor_vm::update_code_heap_for_minor_gc(std::set<code_block *> *remembered_set)
|
|
||||||
{
|
|
||||||
/* The youngest generation that any code block can now reference */
|
|
||||||
std::set<code_block *>::const_iterator iter = remembered_set->begin();
|
|
||||||
std::set<code_block *>::const_iterator end = remembered_set->end();
|
|
||||||
|
|
||||||
for(; iter != end; iter++) update_literal_references(*iter);
|
|
||||||
}
|
|
||||||
|
|
||||||
void factor_vm::gc(gc_op op, cell requested_bytes, bool trace_contexts_p)
|
void factor_vm::gc(gc_op op, cell requested_bytes, bool trace_contexts_p)
|
||||||
{
|
{
|
||||||
assert(!gc_off);
|
assert(!gc_off);
|
||||||
|
|
|
@ -79,6 +79,7 @@ namespace factor
|
||||||
#include "tagged.hpp"
|
#include "tagged.hpp"
|
||||||
#include "data_roots.hpp"
|
#include "data_roots.hpp"
|
||||||
#include "code_roots.hpp"
|
#include "code_roots.hpp"
|
||||||
|
#include "generic_arrays.hpp"
|
||||||
#include "slot_visitor.hpp"
|
#include "slot_visitor.hpp"
|
||||||
#include "collector.hpp"
|
#include "collector.hpp"
|
||||||
#include "copying_collector.hpp"
|
#include "copying_collector.hpp"
|
||||||
|
@ -89,7 +90,6 @@ namespace factor
|
||||||
#include "compaction.hpp"
|
#include "compaction.hpp"
|
||||||
#include "full_collector.hpp"
|
#include "full_collector.hpp"
|
||||||
#include "callstack.hpp"
|
#include "callstack.hpp"
|
||||||
#include "generic_arrays.hpp"
|
|
||||||
#include "arrays.hpp"
|
#include "arrays.hpp"
|
||||||
#include "math.hpp"
|
#include "math.hpp"
|
||||||
#include "booleans.hpp"
|
#include "booleans.hpp"
|
||||||
|
|
|
@ -36,10 +36,6 @@ void factor_vm::collect_nursery()
|
||||||
|
|
||||||
collector.cheneys_algorithm();
|
collector.cheneys_algorithm();
|
||||||
|
|
||||||
current_gc->event->started_code_sweep();
|
|
||||||
update_code_heap_for_minor_gc(&code->points_to_nursery);
|
|
||||||
current_gc->event->ended_code_sweep();
|
|
||||||
|
|
||||||
data->reset_generation(&nursery);
|
data->reset_generation(&nursery);
|
||||||
code->points_to_nursery.clear();
|
code->points_to_nursery.clear();
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,22 +8,37 @@ template<typename Visitor> struct slot_visitor {
|
||||||
explicit slot_visitor<Visitor>(factor_vm *parent_, Visitor visitor_) :
|
explicit slot_visitor<Visitor>(factor_vm *parent_, Visitor visitor_) :
|
||||||
parent(parent_), visitor(visitor_) {}
|
parent(parent_), visitor(visitor_) {}
|
||||||
|
|
||||||
cell visit_pointer(cell pointer)
|
cell visit_pointer(cell pointer);
|
||||||
{
|
void visit_handle(cell *handle);
|
||||||
|
void visit_slots(object *ptr, cell payload_start);
|
||||||
|
void visit_slots(object *ptr);
|
||||||
|
void visit_stack_elements(segment *region, cell *top);
|
||||||
|
void visit_data_roots();
|
||||||
|
void visit_bignum_roots();
|
||||||
|
void visit_roots();
|
||||||
|
void visit_contexts();
|
||||||
|
void visit_literal_references(code_block *compiled);
|
||||||
|
};
|
||||||
|
|
||||||
|
template<typename Visitor>
|
||||||
|
cell slot_visitor<Visitor>::visit_pointer(cell pointer)
|
||||||
|
{
|
||||||
if(immediate_p(pointer)) return pointer;
|
if(immediate_p(pointer)) return pointer;
|
||||||
|
|
||||||
object *untagged = untag<object>(pointer);
|
object *untagged = untag<object>(pointer);
|
||||||
untagged = visitor(untagged);
|
untagged = visitor(untagged);
|
||||||
return RETAG(untagged,TAG(pointer));
|
return RETAG(untagged,TAG(pointer));
|
||||||
}
|
}
|
||||||
|
|
||||||
void visit_handle(cell *handle)
|
template<typename Visitor>
|
||||||
{
|
void slot_visitor<Visitor>::visit_handle(cell *handle)
|
||||||
|
{
|
||||||
*handle = visit_pointer(*handle);
|
*handle = visit_pointer(*handle);
|
||||||
}
|
}
|
||||||
|
|
||||||
void visit_slots(object *ptr, cell payload_start)
|
template<typename Visitor>
|
||||||
{
|
void slot_visitor<Visitor>::visit_slots(object *ptr, cell payload_start)
|
||||||
|
{
|
||||||
cell *slot = (cell *)ptr;
|
cell *slot = (cell *)ptr;
|
||||||
cell *end = (cell *)((cell)ptr + payload_start);
|
cell *end = (cell *)((cell)ptr + payload_start);
|
||||||
|
|
||||||
|
@ -32,21 +47,24 @@ template<typename Visitor> struct slot_visitor {
|
||||||
slot++;
|
slot++;
|
||||||
for(; slot < end; slot++) visit_handle(slot);
|
for(; slot < end; slot++) visit_handle(slot);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void visit_slots(object *ptr)
|
template<typename Visitor>
|
||||||
{
|
void slot_visitor<Visitor>::visit_slots(object *ptr)
|
||||||
|
{
|
||||||
visit_slots(ptr,ptr->binary_payload_start());
|
visit_slots(ptr,ptr->binary_payload_start());
|
||||||
}
|
}
|
||||||
|
|
||||||
void visit_stack_elements(segment *region, cell *top)
|
template<typename Visitor>
|
||||||
{
|
void slot_visitor<Visitor>::visit_stack_elements(segment *region, cell *top)
|
||||||
|
{
|
||||||
for(cell *ptr = (cell *)region->start; ptr <= top; ptr++)
|
for(cell *ptr = (cell *)region->start; ptr <= top; ptr++)
|
||||||
visit_handle(ptr);
|
visit_handle(ptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
void visit_data_roots()
|
template<typename Visitor>
|
||||||
{
|
void slot_visitor<Visitor>::visit_data_roots()
|
||||||
|
{
|
||||||
std::vector<data_root_range>::const_iterator iter = parent->data_roots.begin();
|
std::vector<data_root_range>::const_iterator iter = parent->data_roots.begin();
|
||||||
std::vector<data_root_range>::const_iterator end = parent->data_roots.end();
|
std::vector<data_root_range>::const_iterator end = parent->data_roots.end();
|
||||||
|
|
||||||
|
@ -56,10 +74,11 @@ template<typename Visitor> struct slot_visitor {
|
||||||
for(cell index = 0; index < r.len; index++)
|
for(cell index = 0; index < r.len; index++)
|
||||||
visit_handle(r.start + index);
|
visit_handle(r.start + index);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void visit_bignum_roots()
|
template<typename Visitor>
|
||||||
{
|
void slot_visitor<Visitor>::visit_bignum_roots()
|
||||||
|
{
|
||||||
std::vector<cell>::const_iterator iter = parent->bignum_roots.begin();
|
std::vector<cell>::const_iterator iter = parent->bignum_roots.begin();
|
||||||
std::vector<cell>::const_iterator end = parent->bignum_roots.end();
|
std::vector<cell>::const_iterator end = parent->bignum_roots.end();
|
||||||
|
|
||||||
|
@ -70,10 +89,11 @@ template<typename Visitor> struct slot_visitor {
|
||||||
if(*handle)
|
if(*handle)
|
||||||
*handle = (cell)visitor(*(object **)handle);
|
*handle = (cell)visitor(*(object **)handle);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void visit_roots()
|
template<typename Visitor>
|
||||||
{
|
void slot_visitor<Visitor>::visit_roots()
|
||||||
|
{
|
||||||
visit_handle(&parent->true_object);
|
visit_handle(&parent->true_object);
|
||||||
visit_handle(&parent->bignum_zero);
|
visit_handle(&parent->bignum_zero);
|
||||||
visit_handle(&parent->bignum_pos_one);
|
visit_handle(&parent->bignum_pos_one);
|
||||||
|
@ -84,10 +104,11 @@ template<typename Visitor> struct slot_visitor {
|
||||||
|
|
||||||
for(cell i = 0; i < special_object_count; i++)
|
for(cell i = 0; i < special_object_count; i++)
|
||||||
visit_handle(&parent->special_objects[i]);
|
visit_handle(&parent->special_objects[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
void visit_contexts()
|
template<typename Visitor>
|
||||||
{
|
void slot_visitor<Visitor>::visit_contexts()
|
||||||
|
{
|
||||||
context *ctx = parent->ctx;
|
context *ctx = parent->ctx;
|
||||||
|
|
||||||
while(ctx)
|
while(ctx)
|
||||||
|
@ -100,14 +121,37 @@ template<typename Visitor> struct slot_visitor {
|
||||||
|
|
||||||
ctx = ctx->next;
|
ctx = ctx->next;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void visit_literal_references(code_block *compiled)
|
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_) {}
|
||||||
|
|
||||||
|
void operator()(relocation_entry rel, cell index, code_block *compiled)
|
||||||
{
|
{
|
||||||
visit_handle(&compiled->owner);
|
if(rel.rel_type() == RT_IMMEDIATE)
|
||||||
visit_handle(&compiled->literals);
|
{
|
||||||
visit_handle(&compiled->relocation);
|
embedded_pointer ptr(rel.rel_class(),rel.rel_offset() + (cell)(compiled + 1));
|
||||||
|
cell literal = ptr.load_address();
|
||||||
|
literal = visitor->visit_pointer(literal);
|
||||||
|
ptr.store_address(literal);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
template<typename Visitor>
|
||||||
|
void slot_visitor<Visitor>::visit_literal_references(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);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -42,10 +42,6 @@ void factor_vm::collect_to_tenured()
|
||||||
|
|
||||||
collector.tenure_reachable_objects();
|
collector.tenure_reachable_objects();
|
||||||
|
|
||||||
current_gc->event->started_code_sweep();
|
|
||||||
update_code_heap_for_minor_gc(&code->points_to_aging);
|
|
||||||
current_gc->event->ended_code_sweep();
|
|
||||||
|
|
||||||
data->reset_generation(&nursery);
|
data->reset_generation(&nursery);
|
||||||
data->reset_generation(data->aging);
|
data->reset_generation(data->aging);
|
||||||
code->clear_remembered_set();
|
code->clear_remembered_set();
|
||||||
|
|
21
vm/vm.hpp
21
vm/vm.hpp
|
@ -504,8 +504,25 @@ struct factor_vm
|
||||||
void undefined_symbol();
|
void undefined_symbol();
|
||||||
void *get_rel_symbol(array *literals, cell index);
|
void *get_rel_symbol(array *literals, cell index);
|
||||||
cell compute_relocation(relocation_entry rel, cell index, code_block *compiled);
|
cell compute_relocation(relocation_entry rel, cell index, code_block *compiled);
|
||||||
template<typename Iterator> void iterate_relocations(code_block *compiled, Iterator &iter);
|
|
||||||
void update_literal_references(code_block *compiled);
|
template<typename Iterator> void iterate_relocations(code_block *compiled, Iterator &iter)
|
||||||
|
{
|
||||||
|
if(to_boolean(compiled->relocation))
|
||||||
|
{
|
||||||
|
byte_array *relocation = (byte_array *)UNTAG(compiled->relocation);
|
||||||
|
|
||||||
|
cell index = 0;
|
||||||
|
cell length = (relocation->capacity >> TAG_BITS) / sizeof(relocation_entry);
|
||||||
|
|
||||||
|
for(cell i = 0; i < length; i++)
|
||||||
|
{
|
||||||
|
relocation_entry rel = relocation->data<relocation_entry>()[i];
|
||||||
|
iter(rel,index,compiled);
|
||||||
|
index += rel.number_of_parameters();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
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 update_code_block_words_and_literals(code_block *compiled);
|
||||||
|
|
Loading…
Reference in New Issue