vm: data heap compaction work in progress

db4
Slava Pestov 2009-10-24 04:18:33 -05:00
parent fd1e992e7d
commit 29a27cfde4
11 changed files with 130 additions and 91 deletions

View File

@ -41,6 +41,7 @@ DLL_OBJS = $(PLAF_DLL_OBJS) \
vm/callstack.o \
vm/code_block.o \
vm/code_heap.o \
vm/compaction.o \
vm/contexts.o \
vm/data_heap.o \
vm/debug.o \

View File

@ -2,15 +2,17 @@ namespace factor
{
template<typename Visitor> struct call_frame_code_block_visitor {
factor_vm *parent;
Visitor visitor;
explicit call_frame_code_block_visitor(Visitor visitor_) : visitor(visitor_) {}
explicit call_frame_code_block_visitor(factor_vm *parent_, Visitor visitor_) :
parent(parent_), visitor(visitor_) {}
void operator()(stack_frame *frame)
{
cell offset = (cell)FRAME_RETURN_ADDRESS(frame,parent) - (cell)frame->xt;
code_block *new_block = visitor.visit_code_block(parent->frame_code(frame));
code_block *new_block = visitor(parent->frame_code(frame));
frame->xt = new_block->xt();
FRAME_RETURN_ADDRESS(frame,parent) = (void *)((cell)frame->xt + offset);
@ -25,24 +27,24 @@ template<typename Visitor> void factor_vm::visit_object_code_block(object *obj,
{
word *w = (word *)obj;
if(w->code)
w->code = visitor.visit_code_block(w->code);
w->code = visitor(w->code);
if(w->profiling)
w->code = visitor.visit_code_block(w->profiling);
w->code = visitor(w->profiling);
update_word_xt(obj);
update_word_xt(w);
break;
}
case QUOTATION_TYPE:
{
quotation *q = (quotation *)obj;
if(q->code)
set_quot_xt(visitor.visit_code_block(q->code));
set_quot_xt(q,visitor(q->code));
break;
}
case CALLSTACK_TYPE:
{
callstack *stack = (callstack *)obj;
call_frame_code_block_visitor<Visitor> call_frame_visitor(visitor);
call_frame_code_block_visitor<Visitor> call_frame_visitor(this,visitor);
iterate_callstack_object(stack,call_frame_visitor);
break;
}
@ -51,8 +53,7 @@ template<typename Visitor> void factor_vm::visit_object_code_block(object *obj,
template<typename Visitor> void factor_vm::visit_context_code_blocks(Visitor visitor)
{
callstack *stack = (callstack *)obj;
call_frame_code_block_visitor<Visitor> call_frame_visitor(visitor);
call_frame_code_block_visitor<Visitor> call_frame_visitor(this,visitor);
iterate_active_frames(call_frame_visitor);
}
@ -65,14 +66,14 @@ template<typename Visitor> struct callback_code_block_visitor {
void operator()(callback *stub)
{
stub->compiled = visitor.visit_code_block(stub->compiled);
stub->compiled = visitor(stub->compiled);
callbacks->update(stub);
}
};
template<typename Visitor> void factor_vm::visit_callback_code_blocks(Visitor visitor)
{
callback_code_block_visitor callback_visitor(callbacks,visitor);
callback_code_block_visitor<Visitor> callback_visitor(callbacks,visitor);
callbacks->iterate(callback_visitor);
}

View File

@ -205,67 +205,6 @@ void factor_vm::primitive_code_room()
dpush(tag_fixnum(max_free / 1024));
}
struct code_block_forwarder {
mark_bits<heap_block> *forwarding_map;
explicit code_block_forwarder(mark_bits<heap_block> *forwarding_map_) :
forwarding_map(forwarding_map_) {}
code_block *operator()(code_block *compiled)
{
return (code_block *)forwarding_map->forward_block(compiled);
}
};
void factor_vm::forward_object_xts()
{
code_block_forwarder forwarder(&code->allocator->state);
begin_scan();
cell obj;
while(to_boolean(obj = next_object()))
visit_object_code_block(untag<object>(obj),forwarder);
end_scan();
}
void factor_vm::forward_context_xts()
{
code_block_forwarder forwarder(&code->allocator->state);
visit_context_code_blocks(forwarder);
}
void factor_vm::forward_callback_xts()
{
code_block_forwarder forwarder(&code->allocator->state);
visit_callback_code_blocks(forwarder);
}
/* Move all free space to the end of the code heap. Live blocks must be marked
on entry to this function. XTs in code blocks must be updated after this
function returns. */
void factor_vm::compact_code_heap(bool trace_contexts_p)
{
/* Figure out where blocks are going to go */
code->allocator->state.compute_forwarding();
/* Update references to the code heap from the data heap */
forward_object_xts();
if(trace_contexts_p)
{
forward_context_xts();
forward_callback_xts();
}
/* Move code blocks and update references amongst them (this requires
that the data heap is up to date since relocation looks up object XTs) */
code_heap_relocator relocator(this);
code_heap_iterator<code_heap_relocator> iter(relocator);
code->allocator->compact(iter);
}
struct stack_trace_stripper {
explicit stack_trace_stripper() {}

View File

@ -44,7 +44,7 @@ template<typename TargetGeneration, typename Policy> struct collector_workhorse
return newpointer;
}
object *visit_handle(object *obj)
object *visit_object(object *obj)
{
if(!policy.should_copy_p(obj))
{

96
vm/compaction.cpp Normal file
View File

@ -0,0 +1,96 @@
#include "master.hpp"
namespace factor {
struct object_slot_forwarder {
mark_bits<object> *forwarding_map;
explicit object_slot_forwarder(mark_bits<object> *forwarding_map_) :
forwarding_map(forwarding_map_) {}
object *visit_object(object *obj)
{
return forwarding_map->forward_block(obj);
}
};
struct code_block_forwarder {
mark_bits<heap_block> *forwarding_map;
explicit code_block_forwarder(mark_bits<heap_block> *forwarding_map_) :
forwarding_map(forwarding_map_) {}
code_block *operator()(code_block *compiled)
{
return (code_block *)forwarding_map->forward_block(compiled);
}
};
struct object_compaction_updater {
factor_vm *parent;
slot_visitor<object_slot_forwarder> slot_forwarder;
code_block_forwarder code_forwarder;
explicit object_compaction_updater(factor_vm *parent_,
slot_visitor<object_slot_forwarder> slot_forwader_,
code_block_forwarder code_forwarder_) :
parent(parent_),
slot_forwarder(slot_forwader_),
code_forwarder(code_forwarder_) {}
void operator()(object *obj, cell size)
{
slot_forwarder.visit_slots(obj);
parent->visit_object_code_block(obj,code_forwarder);
}
};
struct code_block_compaction_updater {
factor_vm *parent;
slot_visitor<object_slot_forwarder> slot_forwarder;
explicit code_block_compaction_updater(factor_vm *parent_, slot_visitor<object_slot_forwarder> slot_forwader_) :
parent(parent_), slot_forwarder(slot_forwader_) {}
void operator()(code_block *compiled, cell size)
{
slot_forwarder.visit_literal_references(compiled);
parent->relocate_code_block(compiled);
}
};
void factor_vm::compact_full_impl(bool trace_contexts_p)
{
tenured_space *tenured = data->tenured;
mark_bits<object> *data_forwarding_map = &tenured->state;
mark_bits<heap_block> *code_forwarding_map = &code->allocator->state;
/* Figure out where blocks are going to go */
data_forwarding_map->compute_forwarding();
code_forwarding_map->compute_forwarding();
/* Update root pointers */
slot_visitor<object_slot_forwarder> slot_forwarder(this,object_slot_forwarder(data_forwarding_map));
code_block_forwarder code_forwarder(code_forwarding_map);
slot_forwarder.visit_roots();
if(trace_contexts_p)
{
slot_forwarder.visit_contexts();
visit_context_code_blocks(code_forwarder);
visit_callback_code_blocks(code_forwarder);
}
/* Slide everything in tenured space up, and update data and code heap
pointers inside objects. */
object_compaction_updater object_updater(this,slot_forwarder,code_forwarder);
tenured->compact(object_updater);
/* Slide everything in the code heap up, and update data and code heap
pointers inside code blocks. */
code_block_compaction_updater code_block_updater(this,slot_forwarder);
code_heap_iterator<code_block_compaction_updater> iter(code_block_updater);
code->allocator->compact(iter);
}
}

4
vm/compaction.hpp Normal file
View File

@ -0,0 +1,4 @@
namespace factor
{
}

View File

@ -85,7 +85,7 @@ void factor_vm::collect_full_impl(bool trace_contexts_p)
void factor_vm::collect_growing_heap(cell requested_bytes,
bool trace_contexts_p,
bool compact_code_heap_p)
bool compact_p)
{
/* Grow the data heap and copy all live objects to the new heap. */
data_heap *old = data;
@ -93,18 +93,18 @@ void factor_vm::collect_growing_heap(cell requested_bytes,
collect_full_impl(trace_contexts_p);
delete old;
if(compact_code_heap_p)
compact_code_heap(trace_contexts_p);
if(compact_p)
compact_full_impl(trace_contexts_p);
else
relocate_code_heap();
}
void factor_vm::collect_full(bool trace_contexts_p, bool compact_code_heap_p)
void factor_vm::collect_full(bool trace_contexts_p, bool compact_p)
{
collect_full_impl(trace_contexts_p);
if(compact_code_heap_p)
compact_code_heap(trace_contexts_p);
if(compact_p)
compact_full_impl(trace_contexts_p);
else
update_code_heap_words_and_literals();
}

View File

@ -28,7 +28,7 @@ void factor_vm::record_gc_stats(generation_statistics *stats)
void factor_vm::gc(gc_op op,
cell requested_bytes,
bool trace_contexts_p,
bool compact_code_heap_p)
bool compact_p)
{
assert(!gc_off);
assert(!current_gc);
@ -83,11 +83,11 @@ void factor_vm::gc(gc_op op,
record_gc_stats(&gc_stats.aging_stats);
break;
case collect_full_op:
collect_full(trace_contexts_p,compact_code_heap_p);
collect_full(trace_contexts_p,compact_p);
record_gc_stats(&gc_stats.full_stats);
break;
case collect_growing_heap_op:
collect_growing_heap(requested_bytes,trace_contexts_p,compact_code_heap_p);
collect_growing_heap(requested_bytes,trace_contexts_p,compact_p);
record_gc_stats(&gc_stats.full_stats);
break;
default:

View File

@ -79,6 +79,7 @@ namespace factor
#include "aging_collector.hpp"
#include "to_tenured_collector.hpp"
#include "code_block_visitor.hpp"
#include "compaction.hpp"
#include "full_collector.hpp"
#include "callstack.hpp"
#include "generic_arrays.hpp"

View File

@ -15,7 +15,7 @@ template<typename Visitor> struct slot_visitor {
if(immediate_p(pointer)) return;
object *untagged = untag<object>(pointer);
untagged = visitor.visit_handle(untagged);
untagged = visitor.visit_object(untagged);
*handle = RETAG(untagged,TAG(pointer));
}
@ -56,7 +56,7 @@ template<typename Visitor> struct slot_visitor {
cell *handle = (cell *)(*iter);
if(*handle)
*handle = (cell)visitor.visit_handle(*(object **)handle);
*handle = (cell)visitor.visit_object(*(object **)handle);
}
}

View File

@ -249,10 +249,11 @@ struct factor_vm
void collect_aging();
void collect_to_tenured();
void collect_full_impl(bool trace_contexts_p);
void collect_growing_heap(cell requested_bytes, bool trace_contexts_p, bool compact_code_heap_p);
void collect_full(bool trace_contexts_p, bool compact_code_heap_p);
void compact_full_impl(bool trace_contexts_p);
void collect_growing_heap(cell requested_bytes, bool trace_contexts_p, bool compact_p);
void collect_full(bool trace_contexts_p, bool compact_p);
void record_gc_stats(generation_statistics *stats);
void gc(gc_op op, cell requested_bytes, bool trace_contexts_p, bool compact_code_heap_p);
void gc(gc_op op, cell requested_bytes, bool trace_contexts_p, bool compact_p);
void primitive_minor_gc();
void primitive_full_gc();
void primitive_compact_gc();
@ -506,10 +507,6 @@ struct factor_vm
void relocate_code_heap();
void primitive_modify_code_heap();
void primitive_code_room();
void forward_object_xts();
void forward_context_xts();
void forward_callback_xts();
void compact_code_heap(bool trace_contexts_p);
void primitive_strip_stack_traces();
/* Apply a function to every code block */