vm: factor out code that visits object slots and code heap blocks into slot_visitor and code_block_visitor

db4
Slava Pestov 2009-10-24 03:54:53 -05:00
parent 9abe29bebc
commit fd1e992e7d
12 changed files with 310 additions and 291 deletions

79
vm/code_block_visitor.hpp Normal file
View File

@ -0,0 +1,79 @@
namespace factor
{
template<typename Visitor> struct call_frame_code_block_visitor {
Visitor visitor;
explicit call_frame_code_block_visitor(Visitor visitor_) : 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));
frame->xt = new_block->xt();
FRAME_RETURN_ADDRESS(frame,parent) = (void *)((cell)frame->xt + offset);
}
};
template<typename Visitor> void factor_vm::visit_object_code_block(object *obj, Visitor visitor)
{
switch(obj->h.hi_tag())
{
case WORD_TYPE:
{
word *w = (word *)obj;
if(w->code)
w->code = visitor.visit_code_block(w->code);
if(w->profiling)
w->code = visitor.visit_code_block(w->profiling);
update_word_xt(obj);
break;
}
case QUOTATION_TYPE:
{
quotation *q = (quotation *)obj;
if(q->code)
set_quot_xt(visitor.visit_code_block(q->code));
break;
}
case CALLSTACK_TYPE:
{
callstack *stack = (callstack *)obj;
call_frame_code_block_visitor<Visitor> call_frame_visitor(visitor);
iterate_callstack_object(stack,call_frame_visitor);
break;
}
}
}
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);
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.visit_code_block(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);
callbacks->iterate(callback_visitor);
}
}

View File

@ -188,7 +188,7 @@ void factor_vm::primitive_modify_code_heap()
break; break;
} }
update_word_xt(word.value()); update_word_xt(word.untagged());
} }
update_code_heap_words(); update_code_heap_words();
@ -205,99 +205,42 @@ void factor_vm::primitive_code_room()
dpush(tag_fixnum(max_free / 1024)); dpush(tag_fixnum(max_free / 1024));
} }
code_block *code_heap::forward_code_block(code_block *compiled) struct code_block_forwarder {
{ mark_bits<heap_block> *forwarding_map;
return (code_block *)allocator->state.forward_block(compiled);
}
struct callframe_forwarder { explicit code_block_forwarder(mark_bits<heap_block> *forwarding_map_) :
factor_vm *parent; forwarding_map(forwarding_map_) {}
explicit callframe_forwarder(factor_vm *parent_) : parent(parent_) {} code_block *operator()(code_block *compiled)
void operator()(stack_frame *frame)
{ {
cell offset = (cell)FRAME_RETURN_ADDRESS(frame,parent) - (cell)frame->xt; return (code_block *)forwarding_map->forward_block(compiled);
code_block *forwarded = parent->code->forward_code_block(parent->frame_code(frame));
frame->xt = forwarded->xt();
FRAME_RETURN_ADDRESS(frame,parent) = (void *)((cell)frame->xt + offset);
} }
}; };
void factor_vm::forward_object_xts() void factor_vm::forward_object_xts()
{ {
code_block_forwarder forwarder(&code->allocator->state);
begin_scan(); begin_scan();
cell obj; cell obj;
while(to_boolean(obj = next_object())) while(to_boolean(obj = next_object()))
{ visit_object_code_block(untag<object>(obj),forwarder);
switch(tagged<object>(obj).type())
{
case WORD_TYPE:
{
word *w = untag<word>(obj);
if(w->code)
w->code = code->forward_code_block(w->code);
if(w->profiling)
w->profiling = code->forward_code_block(w->profiling);
update_word_xt(obj);
}
break;
case QUOTATION_TYPE:
{
quotation *quot = untag<quotation>(obj);
if(quot->code)
{
quot->code = code->forward_code_block(quot->code);
set_quot_xt(quot,quot->code);
}
}
break;
case CALLSTACK_TYPE:
{
callstack *stack = untag<callstack>(obj);
callframe_forwarder forwarder(this);
iterate_callstack_object(stack,forwarder);
}
break;
default:
break;
}
}
end_scan(); end_scan();
} }
void factor_vm::forward_context_xts() void factor_vm::forward_context_xts()
{ {
callframe_forwarder forwarder(this); code_block_forwarder forwarder(&code->allocator->state);
iterate_active_frames(forwarder); visit_context_code_blocks(forwarder);
} }
struct callback_forwarder {
code_heap *code;
callback_heap *callbacks;
callback_forwarder(code_heap *code_, callback_heap *callbacks_) :
code(code_), callbacks(callbacks_) {}
void operator()(callback *stub)
{
stub->compiled = code->forward_code_block(stub->compiled);
callbacks->update(stub);
}
};
void factor_vm::forward_callback_xts() void factor_vm::forward_callback_xts()
{ {
callback_forwarder forwarder(code,callbacks); code_block_forwarder forwarder(&code->allocator->state);
callbacks->iterate(forwarder); visit_callback_code_blocks(forwarder);
} }
/* Move all free space to the end of the code heap. Live blocks must be marked /* Move all free space to the end of the code heap. Live blocks must be marked

View File

@ -26,7 +26,6 @@ struct code_heap {
void set_marked_p(code_block *compiled); void set_marked_p(code_block *compiled);
void clear_mark_bits(); void clear_mark_bits();
void code_heap_free(code_block *compiled); void code_heap_free(code_block *compiled);
code_block *forward_code_block(code_block *compiled);
}; };
} }

View File

@ -1,20 +1,14 @@
namespace factor namespace factor
{ {
template<typename TargetGeneration, typename Policy> struct collector { template<typename TargetGeneration, typename Policy> struct collector_workhorse {
factor_vm *parent; factor_vm *parent;
data_heap *data;
code_heap *code;
gc_state *current_gc;
generation_statistics *stats; generation_statistics *stats;
TargetGeneration *target; TargetGeneration *target;
Policy policy; Policy policy;
explicit collector(factor_vm *parent_, generation_statistics *stats_, TargetGeneration *target_, Policy policy_) : explicit collector_workhorse(factor_vm *parent_, generation_statistics *stats_, TargetGeneration *target_, Policy policy_) :
parent(parent_), parent(parent_),
data(parent_->data),
code(parent_->code),
current_gc(parent_->current_gc),
stats(stats_), stats(stats_),
target(target_), target(target_),
policy(policy_) {} policy(policy_) {}
@ -32,52 +26,12 @@ template<typename TargetGeneration, typename Policy> struct collector {
return untagged; return untagged;
} }
void trace_handle(cell *handle)
{
cell pointer = *handle;
if(immediate_p(pointer)) return;
object *untagged = untag<object>(pointer);
if(!policy.should_copy_p(untagged))
{
policy.visited_object(untagged);
return;
}
object *forwarding = resolve_forwarding(untagged);
if(forwarding == untagged)
untagged = promote_object(untagged);
else if(policy.should_copy_p(forwarding))
untagged = promote_object(forwarding);
else
{
untagged = forwarding;
policy.visited_object(untagged);
}
*handle = RETAG(untagged,TAG(pointer));
}
void trace_slots(object *ptr)
{
cell *slot = (cell *)ptr;
cell *end = (cell *)((cell)ptr + parent->binary_payload_start(ptr));
if(slot != end)
{
slot++;
for(; slot < end; slot++) trace_handle(slot);
}
}
object *promote_object(object *untagged) object *promote_object(object *untagged)
{ {
cell size = untagged->size(); cell size = untagged->size();
object *newpointer = target->allot(size); object *newpointer = target->allot(size);
/* XXX not exception-safe */ /* XXX not exception-safe */
if(!newpointer) longjmp(current_gc->gc_unwind,1); if(!newpointer) longjmp(parent->current_gc->gc_unwind,1);
memcpy(newpointer,untagged,size); memcpy(newpointer,untagged,size);
untagged->h.forward_to(newpointer); untagged->h.forward_to(newpointer);
@ -90,68 +44,90 @@ template<typename TargetGeneration, typename Policy> struct collector {
return newpointer; return newpointer;
} }
void trace_stack_elements(segment *region, cell *top) object *visit_handle(object *obj)
{ {
for(cell *ptr = (cell *)region->start; ptr <= top; ptr++) if(!policy.should_copy_p(obj))
trace_handle(ptr); {
policy.visited_object(obj);
return obj;
} }
void trace_registered_locals() object *forwarding = resolve_forwarding(obj);
{
std::vector<cell>::const_iterator iter = parent->gc_locals.begin();
std::vector<cell>::const_iterator end = parent->gc_locals.end();
for(; iter < end; iter++) if(forwarding == obj)
trace_handle((cell *)(*iter)); return promote_object(obj);
} else if(policy.should_copy_p(forwarding))
return promote_object(forwarding);
void trace_registered_bignums() else
{ {
std::vector<cell>::const_iterator iter = parent->gc_bignums.begin(); policy.visited_object(forwarding);
std::vector<cell>::const_iterator end = parent->gc_bignums.end(); return forwarding;
for(; iter < end; iter++)
{
cell *handle = (cell *)(*iter);
if(*handle)
{
*handle |= BIGNUM_TYPE;
trace_handle(handle);
*handle &= ~BIGNUM_TYPE;
} }
} }
};
template<typename TargetGeneration, typename Policy>
inline static slot_visitor<collector_workhorse<TargetGeneration,Policy> > make_collector_workhorse(
factor_vm *parent,
generation_statistics *stats,
TargetGeneration *target,
Policy policy)
{
return slot_visitor<collector_workhorse<TargetGeneration,Policy> >(parent,
collector_workhorse<TargetGeneration,Policy>(parent,stats,target,policy));
}
template<typename TargetGeneration, typename Policy> struct collector {
factor_vm *parent;
data_heap *data;
code_heap *code;
generation_statistics *stats;
TargetGeneration *target;
slot_visitor<collector_workhorse<TargetGeneration,Policy> > workhorse;
explicit collector(factor_vm *parent_, generation_statistics *stats_, TargetGeneration *target_, Policy policy_) :
parent(parent_),
data(parent_->data),
code(parent_->code),
stats(stats_),
target(target_),
workhorse(make_collector_workhorse(parent_,stats_,target_,policy_)) {}
void trace_handle(cell *handle)
{
workhorse.visit_handle(handle);
}
void trace_slots(object *ptr)
{
workhorse.visit_slots(ptr);
} }
/* Copy roots over at the start of GC, namely various constants, stacks,
the user environment and extra roots registered by local_roots.hpp */
void trace_roots() void trace_roots()
{ {
trace_handle(&parent->true_object); workhorse.visit_roots();
trace_handle(&parent->bignum_zero);
trace_handle(&parent->bignum_pos_one);
trace_handle(&parent->bignum_neg_one);
trace_registered_locals();
trace_registered_bignums();
for(cell i = 0; i < special_object_count; i++)
trace_handle(&parent->special_objects[i]);
} }
void trace_contexts() void trace_contexts()
{ {
context *ctx = parent->ctx; workhorse.visit_contexts();
}
while(ctx) /* Trace all literals referenced from a code block. Only for aging and nursery collections */
void trace_literal_references(code_block *compiled)
{ {
trace_stack_elements(ctx->datastack_region,(cell *)ctx->datastack); workhorse.visit_literal_references(compiled);
trace_stack_elements(ctx->retainstack_region,(cell *)ctx->retainstack); }
trace_handle(&ctx->catchstack_save); void trace_code_heap_roots(std::set<code_block *> *remembered_set)
trace_handle(&ctx->current_callback_save); {
std::set<code_block *>::const_iterator iter = remembered_set->begin();
std::set<code_block *>::const_iterator end = remembered_set->end();
ctx = ctx->next; for(; iter != end; iter++)
{
trace_literal_references(*iter);
parent->gc_stats.code_blocks_scanned++;
} }
} }
@ -167,17 +143,17 @@ template<typename TargetGeneration, typename Policy> struct collector {
inline cell card_deck_for_address(cell a) inline cell card_deck_for_address(cell a)
{ {
return addr_to_deck(a - this->data->start); return addr_to_deck(a - data->start);
} }
inline cell card_start_address(cell card) inline cell card_start_address(cell card)
{ {
return (card << card_bits) + this->data->start; return (card << card_bits) + data->start;
} }
inline cell card_end_address(cell card) inline cell card_end_address(cell card)
{ {
return ((card + 1) << card_bits) + this->data->start; return ((card + 1) << card_bits) + data->start;
} }
void trace_partial_objects(cell start, cell end, cell card_start, cell card_end) void trace_partial_objects(cell start, cell end, cell card_start, cell card_end)
@ -195,7 +171,7 @@ template<typename TargetGeneration, typename Policy> struct collector {
if(slot_ptr != end_ptr) if(slot_ptr != end_ptr)
{ {
for(; slot_ptr < end_ptr; slot_ptr++) for(; slot_ptr < end_ptr; slot_ptr++)
this->trace_handle(slot_ptr); workhorse.visit_handle(slot_ptr);
} }
} }
} }
@ -205,10 +181,10 @@ template<typename TargetGeneration, typename Policy> struct collector {
{ {
u64 start_time = current_micros(); u64 start_time = current_micros();
card_deck *decks = this->data->decks; card_deck *decks = data->decks;
card_deck *cards = this->data->cards; card_deck *cards = data->cards;
cell gen_start_card = addr_to_card(gen->start - this->data->start); cell gen_start_card = addr_to_card(gen->start - data->start);
cell first_deck = card_deck_for_address(gen->start); cell first_deck = card_deck_for_address(gen->start);
cell last_deck = card_deck_for_address(gen->end); cell last_deck = card_deck_for_address(gen->end);
@ -219,7 +195,7 @@ template<typename TargetGeneration, typename Policy> struct collector {
{ {
if(decks[deck_index] & mask) if(decks[deck_index] & mask)
{ {
this->parent->gc_stats.decks_scanned++; parent->gc_stats.decks_scanned++;
cell first_card = first_card_in_deck(deck_index); cell first_card = first_card_in_deck(deck_index);
cell last_card = last_card_in_deck(deck_index); cell last_card = last_card_in_deck(deck_index);
@ -228,17 +204,17 @@ template<typename TargetGeneration, typename Policy> struct collector {
{ {
if(cards[card_index] & mask) if(cards[card_index] & mask)
{ {
this->parent->gc_stats.cards_scanned++; parent->gc_stats.cards_scanned++;
if(end < card_start_address(card_index)) if(end < card_start_address(card_index))
{ {
start = gen->starts.find_object_containing_card(card_index - gen_start_card); start = gen->starts.find_object_containing_card(card_index - gen_start_card);
binary_start = start + this->parent->binary_payload_start((object *)start); binary_start = start + parent->binary_payload_start((object *)start);
end = start + ((object *)start)->size(); end = start + ((object *)start)->size();
} }
#ifdef FACTOR_DEBUG #ifdef FACTOR_DEBUG
assert(addr_to_card(start - this->data->start) <= card_index); assert(addr_to_card(start - data->start) <= card_index);
assert(start < card_end_address(card_index)); assert(start < card_end_address(card_index));
#endif #endif
@ -253,7 +229,7 @@ scan_next_object: {
start = gen->next_object_after(start); start = gen->next_object_after(start);
if(start) if(start)
{ {
binary_start = start + this->parent->binary_payload_start((object *)start); binary_start = start + parent->binary_payload_start((object *)start);
end = start + ((object *)start)->size(); end = start + ((object *)start)->size();
goto scan_next_object; goto scan_next_object;
} }
@ -270,24 +246,7 @@ scan_next_object: {
} }
} }
end: this->parent->gc_stats.card_scan_time += (current_micros() - start_time); end: parent->gc_stats.card_scan_time += (current_micros() - start_time);
}
/* Trace all literals referenced from a code block. Only for aging and nursery collections */
void trace_literal_references(code_block *compiled)
{
this->trace_handle(&compiled->owner);
this->trace_handle(&compiled->literals);
this->trace_handle(&compiled->relocation);
this->parent->gc_stats.code_blocks_scanned++;
}
void trace_code_heap_roots(std::set<code_block *> *remembered_set)
{
std::set<code_block *>::const_iterator iter = remembered_set->begin();
std::set<code_block *>::const_iterator end = remembered_set->end();
for(; iter != end; iter++) trace_literal_references(*iter);
} }
}; };

View File

@ -10,101 +10,36 @@ full_collector::full_collector(factor_vm *parent_) :
parent_->data->tenured, parent_->data->tenured,
full_policy(parent_)) {} full_policy(parent_)) {}
struct stack_frame_marker { struct code_block_marker {
factor_vm *parent; code_heap *code;
full_collector *collector; full_collector *collector;
explicit stack_frame_marker(full_collector *collector_) : explicit code_block_marker(code_heap *code_, full_collector *collector_) :
parent(collector_->parent), collector(collector_) {} code(code_), collector(collector_) {}
void operator()(stack_frame *frame) code_block *operator()(code_block *compiled)
{ {
collector->mark_code_block(parent->frame_code(frame)); if(!code->marked_p(compiled))
{
code->set_marked_p(compiled);
collector->trace_literal_references(compiled);
}
return compiled;
} }
}; };
/* Mark code blocks executing in currently active stack frames. */
void full_collector::mark_active_blocks()
{
stack_frame_marker marker(this);
parent->iterate_active_frames(marker);
}
void full_collector::mark_object_code_block(object *obj)
{
switch(obj->h.hi_tag())
{
case WORD_TYPE:
{
word *w = (word *)obj;
if(w->code)
mark_code_block(w->code);
if(w->profiling)
mark_code_block(w->profiling);
break;
}
case QUOTATION_TYPE:
{
quotation *q = (quotation *)obj;
if(q->code)
mark_code_block(q->code);
break;
}
case CALLSTACK_TYPE:
{
callstack *stack = (callstack *)obj;
stack_frame_marker marker(this);
parent->iterate_callstack_object(stack,marker);
break;
}
}
}
struct callback_tracer {
full_collector *collector;
callback_tracer(full_collector *collector_) : collector(collector_) {}
void operator()(callback *stub)
{
collector->mark_code_block(stub->compiled);
}
};
void full_collector::trace_callbacks()
{
callback_tracer tracer(this);
parent->callbacks->iterate(tracer);
}
/* Trace all literals referenced from a code block. Only for aging and nursery collections */
void full_collector::trace_literal_references(code_block *compiled)
{
this->trace_handle(&compiled->owner);
this->trace_handle(&compiled->literals);
this->trace_handle(&compiled->relocation);
}
/* Mark all literals referenced from a word XT. Only for tenured
collections */
void full_collector::mark_code_block(code_block *compiled)
{
if(!this->code->marked_p(compiled))
{
this->code->set_marked_p(compiled);
trace_literal_references(compiled);
}
}
void full_collector::mark_reachable_objects() void full_collector::mark_reachable_objects()
{ {
code_block_marker marker(code,this);
std::vector<object *> *mark_stack = &this->target->mark_stack; std::vector<object *> *mark_stack = &this->target->mark_stack;
while(!mark_stack->empty()) while(!mark_stack->empty())
{ {
object *obj = mark_stack->back(); object *obj = mark_stack->back();
mark_stack->pop_back(); mark_stack->pop_back();
this->trace_slots(obj); this->trace_slots(obj);
this->mark_object_code_block(obj); parent->visit_object_code_block(obj,marker);
} }
} }
@ -131,8 +66,9 @@ void factor_vm::collect_full_impl(bool trace_contexts_p)
if(trace_contexts_p) if(trace_contexts_p)
{ {
collector.trace_contexts(); collector.trace_contexts();
collector.mark_active_blocks(); code_block_marker marker(code,&collector);
collector.trace_callbacks(); visit_context_code_blocks(marker);
visit_callback_code_blocks(marker);
} }
collector.mark_reachable_objects(); collector.mark_reachable_objects();

View File

@ -28,11 +28,6 @@ struct full_collector : collector<tenured_space,full_policy> {
bool trace_contexts_p; bool trace_contexts_p;
full_collector(factor_vm *parent_); full_collector(factor_vm *parent_);
void mark_active_blocks();
void mark_object_code_block(object *object);
void trace_callbacks();
void trace_literal_references(code_block *compiled);
void mark_code_block(code_block *compiled);
void mark_reachable_objects(); void mark_reachable_objects();
}; };

View File

@ -72,11 +72,13 @@ namespace factor
#include "vm.hpp" #include "vm.hpp"
#include "tagged.hpp" #include "tagged.hpp"
#include "local_roots.hpp" #include "local_roots.hpp"
#include "slot_visitor.hpp"
#include "collector.hpp" #include "collector.hpp"
#include "copying_collector.hpp" #include "copying_collector.hpp"
#include "nursery_collector.hpp" #include "nursery_collector.hpp"
#include "aging_collector.hpp" #include "aging_collector.hpp"
#include "to_tenured_collector.hpp" #include "to_tenured_collector.hpp"
#include "code_block_visitor.hpp"
#include "full_collector.hpp" #include "full_collector.hpp"
#include "callstack.hpp" #include "callstack.hpp"
#include "generic_arrays.hpp" #include "generic_arrays.hpp"

View File

@ -40,7 +40,7 @@ void factor_vm::set_profiling(bool profiling)
tagged<word> word(array_nth(words.untagged(),i)); tagged<word> word(array_nth(words.untagged(),i));
if(profiling) if(profiling)
word->counter = tag_fixnum(0); word->counter = tag_fixnum(0);
update_word_xt(word.value()); update_word_xt(word.untagged());
} }
update_code_heap_words(); update_code_heap_words();

View File

@ -338,7 +338,7 @@ void factor_vm::compile_all_words()
if(!word->code || !word->code->optimized_p()) if(!word->code || !word->code->optimized_p())
jit_compile_word(word.value(),word->def,false); jit_compile_word(word.value(),word->def,false);
update_word_xt(word.value()); update_word_xt(word.untagged());
} }

101
vm/slot_visitor.hpp Normal file
View File

@ -0,0 +1,101 @@
namespace factor
{
template<typename Visitor> struct slot_visitor {
factor_vm *parent;
Visitor visitor;
slot_visitor<Visitor>(factor_vm *parent_, Visitor visitor_) :
parent(parent_), visitor(visitor_) {}
void visit_handle(cell *handle)
{
cell pointer = *handle;
if(immediate_p(pointer)) return;
object *untagged = untag<object>(pointer);
untagged = visitor.visit_handle(untagged);
*handle = RETAG(untagged,TAG(pointer));
}
void visit_slots(object *ptr)
{
cell *slot = (cell *)ptr;
cell *end = (cell *)((cell)ptr + parent->binary_payload_start(ptr));
if(slot != end)
{
slot++;
for(; slot < end; slot++) visit_handle(slot);
}
}
void visit_stack_elements(segment *region, cell *top)
{
for(cell *ptr = (cell *)region->start; ptr <= top; ptr++)
visit_handle(ptr);
}
void visit_registered_locals()
{
std::vector<cell>::const_iterator iter = parent->gc_locals.begin();
std::vector<cell>::const_iterator end = parent->gc_locals.end();
for(; iter < end; iter++)
visit_handle((cell *)(*iter));
}
void visit_registered_bignums()
{
std::vector<cell>::const_iterator iter = parent->gc_bignums.begin();
std::vector<cell>::const_iterator end = parent->gc_bignums.end();
for(; iter < end; iter++)
{
cell *handle = (cell *)(*iter);
if(*handle)
*handle = (cell)visitor.visit_handle(*(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_registered_locals();
visit_registered_bignums();
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);
}
};
}

View File

@ -353,7 +353,7 @@ struct factor_vm
word *allot_word(cell name_, cell vocab_, cell hashcode_); word *allot_word(cell name_, cell vocab_, cell hashcode_);
void primitive_word(); void primitive_word();
void primitive_word_xt(); void primitive_word_xt();
void update_word_xt(cell w_); void update_word_xt(word *w_);
void primitive_optimized_p(); void primitive_optimized_p();
void primitive_wrapper(); void primitive_wrapper();
@ -485,6 +485,11 @@ struct factor_vm
code_block *allot_code_block(cell size, code_block_type type); code_block *allot_code_block(cell size, code_block_type type);
code_block *add_code_block(code_block_type type, cell code_, cell labels_, cell owner_, cell relocation_, cell literals_); code_block *add_code_block(code_block_type type, cell code_, cell labels_, cell owner_, cell relocation_, cell literals_);
//code_block_visitor
template<typename Visitor> void visit_object_code_block(object *obj, Visitor visitor);
template<typename Visitor> void visit_context_code_blocks(Visitor visitor);
template<typename Visitor> void visit_callback_code_blocks(Visitor visitor);
//code heap //code heap
inline void check_code_pointer(cell ptr) inline void check_code_pointer(cell ptr)
{ {

View File

@ -23,7 +23,7 @@ word *factor_vm::allot_word(cell name_, cell vocab_, cell hashcode_)
new_word->code = NULL; new_word->code = NULL;
jit_compile_word(new_word.value(),new_word->def,true); jit_compile_word(new_word.value(),new_word->def,true);
update_word_xt(new_word.value()); update_word_xt(new_word.untagged());
if(profiling_p) if(profiling_p)
relocate_code_block(new_word->profiling); relocate_code_block(new_word->profiling);
@ -59,7 +59,7 @@ void factor_vm::primitive_word_xt()
} }
/* Allocates memory */ /* Allocates memory */
void factor_vm::update_word_xt(cell w_) void factor_vm::update_word_xt(word *w_)
{ {
gc_root<word> w(w_,this); gc_root<word> w(w_,this);