vm: minor GC traces embedded pointers

db4
Slava Pestov 2009-11-22 13:37:39 -06:00
parent 57fe0dea48
commit b28619ce2f
9 changed files with 155 additions and 159 deletions

View File

@ -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. */

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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