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);
|
||||
|
||||
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. */
|
||||
|
|
|
@ -151,51 +151,6 @@ cell factor_vm::compute_relocation(relocation_entry rel, cell index, code_block
|
|||
#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 */
|
||||
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();
|
||||
data->tenured->sweep();
|
||||
update_code_roots_for_sweep();
|
||||
current_gc->event->ended_data_sweep();
|
||||
|
||||
update_code_roots_for_sweep();
|
||||
|
||||
current_gc->event->started_code_sweep();
|
||||
code->allocator->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);
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
assert(!gc_off);
|
||||
|
|
|
@ -79,6 +79,7 @@ namespace factor
|
|||
#include "tagged.hpp"
|
||||
#include "data_roots.hpp"
|
||||
#include "code_roots.hpp"
|
||||
#include "generic_arrays.hpp"
|
||||
#include "slot_visitor.hpp"
|
||||
#include "collector.hpp"
|
||||
#include "copying_collector.hpp"
|
||||
|
@ -89,7 +90,6 @@ namespace factor
|
|||
#include "compaction.hpp"
|
||||
#include "full_collector.hpp"
|
||||
#include "callstack.hpp"
|
||||
#include "generic_arrays.hpp"
|
||||
#include "arrays.hpp"
|
||||
#include "math.hpp"
|
||||
#include "booleans.hpp"
|
||||
|
|
|
@ -36,10 +36,6 @@ void factor_vm::collect_nursery()
|
|||
|
||||
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);
|
||||
code->points_to_nursery.clear();
|
||||
}
|
||||
|
|
|
@ -8,106 +8,150 @@ template<typename Visitor> struct slot_visitor {
|
|||
explicit slot_visitor<Visitor>(factor_vm *parent_, Visitor visitor_) :
|
||||
parent(parent_), visitor(visitor_) {}
|
||||
|
||||
cell visit_pointer(cell pointer)
|
||||
{
|
||||
if(immediate_p(pointer)) return 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);
|
||||
};
|
||||
|
||||
object *untagged = untag<object>(pointer);
|
||||
untagged = visitor(untagged);
|
||||
return RETAG(untagged,TAG(pointer));
|
||||
template<typename Visitor>
|
||||
cell slot_visitor<Visitor>::visit_pointer(cell pointer)
|
||||
{
|
||||
if(immediate_p(pointer)) return pointer;
|
||||
|
||||
object *untagged = untag<object>(pointer);
|
||||
untagged = visitor(untagged);
|
||||
return RETAG(untagged,TAG(pointer));
|
||||
}
|
||||
|
||||
template<typename Visitor>
|
||||
void slot_visitor<Visitor>::visit_handle(cell *handle)
|
||||
{
|
||||
*handle = visit_pointer(*handle);
|
||||
}
|
||||
|
||||
template<typename Visitor>
|
||||
void slot_visitor<Visitor>::visit_slots(object *ptr, cell payload_start)
|
||||
{
|
||||
cell *slot = (cell *)ptr;
|
||||
cell *end = (cell *)((cell)ptr + payload_start);
|
||||
|
||||
if(slot != end)
|
||||
{
|
||||
slot++;
|
||||
for(; slot < end; slot++) visit_handle(slot);
|
||||
}
|
||||
}
|
||||
|
||||
void visit_handle(cell *handle)
|
||||
template<typename Visitor>
|
||||
void slot_visitor<Visitor>::visit_slots(object *ptr)
|
||||
{
|
||||
visit_slots(ptr,ptr->binary_payload_start());
|
||||
}
|
||||
|
||||
template<typename Visitor>
|
||||
void slot_visitor<Visitor>::visit_stack_elements(segment *region, cell *top)
|
||||
{
|
||||
for(cell *ptr = (cell *)region->start; ptr <= top; ptr++)
|
||||
visit_handle(ptr);
|
||||
}
|
||||
|
||||
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 end = parent->data_roots.end();
|
||||
|
||||
for(; iter < end; iter++)
|
||||
{
|
||||
*handle = visit_pointer(*handle);
|
||||
data_root_range r = *iter;
|
||||
for(cell index = 0; index < r.len; index++)
|
||||
visit_handle(r.start + index);
|
||||
}
|
||||
}
|
||||
|
||||
void visit_slots(object *ptr, cell payload_start)
|
||||
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 end = parent->bignum_roots.end();
|
||||
|
||||
for(; iter < end; iter++)
|
||||
{
|
||||
cell *slot = (cell *)ptr;
|
||||
cell *end = (cell *)((cell)ptr + payload_start);
|
||||
cell *handle = (cell *)(*iter);
|
||||
|
||||
if(slot != end)
|
||||
if(*handle)
|
||||
*handle = (cell)visitor(*(object **)handle);
|
||||
}
|
||||
}
|
||||
|
||||
template<typename Visitor>
|
||||
void slot_visitor<Visitor>::visit_roots()
|
||||
{
|
||||
visit_handle(&parent->true_object);
|
||||
visit_handle(&parent->bignum_zero);
|
||||
visit_handle(&parent->bignum_pos_one);
|
||||
visit_handle(&parent->bignum_neg_one);
|
||||
|
||||
visit_data_roots();
|
||||
visit_bignum_roots();
|
||||
|
||||
for(cell i = 0; i < special_object_count; i++)
|
||||
visit_handle(&parent->special_objects[i]);
|
||||
}
|
||||
|
||||
template<typename Visitor>
|
||||
void slot_visitor<Visitor>::visit_contexts()
|
||||
{
|
||||
context *ctx = parent->ctx;
|
||||
|
||||
while(ctx)
|
||||
{
|
||||
visit_stack_elements(ctx->datastack_region,(cell *)ctx->datastack);
|
||||
visit_stack_elements(ctx->retainstack_region,(cell *)ctx->retainstack);
|
||||
|
||||
visit_handle(&ctx->catchstack_save);
|
||||
visit_handle(&ctx->current_callback_save);
|
||||
|
||||
ctx = ctx->next;
|
||||
}
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
if(rel.rel_type() == RT_IMMEDIATE)
|
||||
{
|
||||
slot++;
|
||||
for(; slot < end; slot++) visit_handle(slot);
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
void visit_slots(object *ptr)
|
||||
{
|
||||
visit_slots(ptr,ptr->binary_payload_start());
|
||||
}
|
||||
|
||||
void visit_stack_elements(segment *region, cell *top)
|
||||
{
|
||||
for(cell *ptr = (cell *)region->start; ptr <= top; ptr++)
|
||||
visit_handle(ptr);
|
||||
}
|
||||
|
||||
void visit_data_roots()
|
||||
{
|
||||
std::vector<data_root_range>::const_iterator iter = parent->data_roots.begin();
|
||||
std::vector<data_root_range>::const_iterator end = parent->data_roots.end();
|
||||
|
||||
for(; iter < end; iter++)
|
||||
{
|
||||
data_root_range r = *iter;
|
||||
for(cell index = 0; index < r.len; index++)
|
||||
visit_handle(r.start + index);
|
||||
}
|
||||
}
|
||||
|
||||
void visit_bignum_roots()
|
||||
{
|
||||
std::vector<cell>::const_iterator iter = parent->bignum_roots.begin();
|
||||
std::vector<cell>::const_iterator end = parent->bignum_roots.end();
|
||||
|
||||
for(; iter < end; iter++)
|
||||
{
|
||||
cell *handle = (cell *)(*iter);
|
||||
|
||||
if(*handle)
|
||||
*handle = (cell)visitor(*(object **)handle);
|
||||
}
|
||||
}
|
||||
|
||||
void visit_roots()
|
||||
{
|
||||
visit_handle(&parent->true_object);
|
||||
visit_handle(&parent->bignum_zero);
|
||||
visit_handle(&parent->bignum_pos_one);
|
||||
visit_handle(&parent->bignum_neg_one);
|
||||
|
||||
visit_data_roots();
|
||||
visit_bignum_roots();
|
||||
|
||||
for(cell i = 0; i < special_object_count; i++)
|
||||
visit_handle(&parent->special_objects[i]);
|
||||
}
|
||||
|
||||
void visit_contexts()
|
||||
{
|
||||
context *ctx = parent->ctx;
|
||||
|
||||
while(ctx)
|
||||
{
|
||||
visit_stack_elements(ctx->datastack_region,(cell *)ctx->datastack);
|
||||
visit_stack_elements(ctx->retainstack_region,(cell *)ctx->retainstack);
|
||||
|
||||
visit_handle(&ctx->catchstack_save);
|
||||
visit_handle(&ctx->current_callback_save);
|
||||
|
||||
ctx = ctx->next;
|
||||
}
|
||||
}
|
||||
|
||||
void visit_literal_references(code_block *compiled)
|
||||
{
|
||||
visit_handle(&compiled->owner);
|
||||
visit_handle(&compiled->literals);
|
||||
visit_handle(&compiled->relocation);
|
||||
}
|
||||
};
|
||||
|
||||
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();
|
||||
|
||||
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(data->aging);
|
||||
code->clear_remembered_set();
|
||||
|
|
21
vm/vm.hpp
21
vm/vm.hpp
|
@ -504,8 +504,25 @@ struct factor_vm
|
|||
void undefined_symbol();
|
||||
void *get_rel_symbol(array *literals, cell index);
|
||||
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 update_word_references(code_block *compiled);
|
||||
void update_code_block_words_and_literals(code_block *compiled);
|
||||
|
|
Loading…
Reference in New Issue