Split literal table into literal and parameter tables, literal table is discarded after code block initialization

db4
Slava Pestov 2009-12-02 04:28:15 -06:00
parent 147edb1ce9
commit 68c09f0e93
25 changed files with 174 additions and 101 deletions

View File

@ -113,25 +113,32 @@ SYMBOL: jit-relocations
: jit-rel ( rc rt -- ) : jit-rel ( rc rt -- )
over compute-offset 3array jit-relocations get push-all ; over compute-offset 3array jit-relocations get push-all ;
SYMBOL: jit-parameters
: jit-parameter ( parameter -- )
jit-parameters get push ;
SYMBOL: jit-literals SYMBOL: jit-literals
: jit-literal ( literal -- ) : jit-literal ( literal -- )
jit-literals get push ; jit-literals get push ;
: make-jit ( quot -- jit-literals jit-data ) : make-jit ( quot -- jit-parameters jit-literals jit-data )
[ [
V{ } clone jit-parameters set
V{ } clone jit-literals set V{ } clone jit-literals set
V{ } clone jit-relocations set V{ } clone jit-relocations set
call( -- ) call( -- )
jit-parameters get >array
jit-literals get >array jit-literals get >array
jit-relocations get >array jit-relocations get >array
] B{ } make prefix ; ] B{ } make prefix ;
: jit-define ( quot name -- ) : jit-define ( quot name -- )
[ make-jit nip ] dip set ; [ make-jit 2nip ] dip set ;
: define-sub-primitive ( quot word -- ) : define-sub-primitive ( quot word -- )
[ make-jit 2array ] dip sub-primitives get set-at ; [ make-jit 3array ] dip sub-primitives get set-at ;
! The image being constructed; a vector of word-size integers ! The image being constructed; a vector of word-size integers
SYMBOL: image SYMBOL: image

View File

@ -63,7 +63,7 @@ M: ##no-tco generate-insn drop ;
M: ##call generate-insn M: ##call generate-insn
word>> dup sub-primitive>> word>> dup sub-primitive>>
[ second first % ] [ [ add-call ] [ %call ] bi ] ?if ; [ third first % ] [ [ add-call ] [ %call ] bi ] ?if ;
M: ##jump generate-insn word>> [ add-call ] [ %jump ] bi ; M: ##jump generate-insn word>> [ add-call ] [ %jump ] bi ;

View File

@ -3,13 +3,18 @@
USING: arrays byte-arrays byte-vectors generic assocs hashtables USING: arrays byte-arrays byte-vectors generic assocs hashtables
io.binary kernel kernel.private math namespaces make sequences io.binary kernel kernel.private math namespaces make sequences
words quotations strings alien.accessors alien.strings layouts words quotations strings alien.accessors alien.strings layouts
system combinators math.bitwise math.order system combinators math.bitwise math.order generalizations
accessors growable fry compiler.constants ; accessors growable fry compiler.constants ;
IN: compiler.codegen.fixup IN: compiler.codegen.fixup
! Owner ! Owner
SYMBOL: compiling-word SYMBOL: compiling-word
! Parameter table
SYMBOL: parameter-table
: add-parameter ( obj -- ) parameter-table get push ;
! Literal table ! Literal table
SYMBOL: literal-table SYMBOL: literal-table
@ -50,11 +55,11 @@ SYMBOL: relocation-table
: rel-fixup ( class type -- ) : rel-fixup ( class type -- )
swap dup offset-for-class add-relocation-entry ; swap dup offset-for-class add-relocation-entry ;
: add-dlsym-literals ( symbol dll -- ) : add-dlsym-parameters ( symbol dll -- )
[ string>symbol add-literal ] [ add-literal ] bi* ; [ string>symbol add-parameter ] [ add-parameter ] bi* ;
: rel-dlsym ( name dll class -- ) : rel-dlsym ( name dll class -- )
[ add-dlsym-literals ] dip rt-dlsym rel-fixup ; [ add-dlsym-parameters ] dip rt-dlsym rel-fixup ;
: rel-word ( word class -- ) : rel-word ( word class -- )
[ add-literal ] dip rt-xt rel-fixup ; [ add-literal ] dip rt-xt rel-fixup ;
@ -66,7 +71,7 @@ SYMBOL: relocation-table
[ add-literal ] dip rt-xt-pic-tail rel-fixup ; [ add-literal ] dip rt-xt-pic-tail rel-fixup ;
: rel-primitive ( word class -- ) : rel-primitive ( word class -- )
[ def>> first add-literal ] dip rt-primitive rel-fixup ; [ def>> first add-parameter ] dip rt-primitive rel-fixup ;
: rel-immediate ( literal class -- ) : rel-immediate ( literal class -- )
[ add-literal ] dip rt-immediate rel-fixup ; [ add-literal ] dip rt-immediate rel-fixup ;
@ -75,10 +80,10 @@ SYMBOL: relocation-table
rt-this rel-fixup ; rt-this rel-fixup ;
: rel-here ( offset class -- ) : rel-here ( offset class -- )
[ add-literal ] dip rt-here rel-fixup ; [ add-parameter ] dip rt-here rel-fixup ;
: rel-vm ( offset class -- ) : rel-vm ( offset class -- )
[ add-literal ] dip rt-vm rel-fixup ; [ add-parameter ] dip rt-vm rel-fixup ;
: rel-cards-offset ( class -- ) : rel-cards-offset ( class -- )
rt-cards-offset rel-fixup ; rt-cards-offset rel-fixup ;
@ -91,7 +96,7 @@ SYMBOL: relocation-table
label>> offset>> [ "Unresolved label" throw ] unless* ; label>> offset>> [ "Unresolved label" throw ] unless* ;
: resolve-absolute-label ( label-fixup -- ) : resolve-absolute-label ( label-fixup -- )
dup resolve-offset neg add-literal dup resolve-offset neg add-parameter
[ rt-here ] dip [ class>> ] [ offset>> ] bi add-relocation-entry ; [ rt-here ] dip [ class>> ] [ offset>> ] bi add-relocation-entry ;
: resolve-relative-label ( label-fixup -- label ) : resolve-relative-label ( label-fixup -- label )
@ -105,6 +110,7 @@ SYMBOL: relocation-table
: init-fixup ( word -- ) : init-fixup ( word -- )
compiling-word set compiling-word set
V{ } clone parameter-table set
V{ } clone literal-table set V{ } clone literal-table set
V{ } clone label-table set V{ } clone label-table set
BV{ } clone relocation-table set ; BV{ } clone relocation-table set ;
@ -114,7 +120,8 @@ SYMBOL: relocation-table
init-fixup init-fixup
@ @
label-table [ resolve-labels ] change label-table [ resolve-labels ] change
parameter-table get >array
literal-table get >array literal-table get >array
relocation-table get >byte-array relocation-table get >byte-array
label-table get label-table get
] B{ } make 4array ; inline ] B{ } make 5 narray ; inline

View File

@ -236,7 +236,7 @@ CONSTANT: rs-reg 14
[ [
3 ds-reg 0 LWZ 3 ds-reg 0 LWZ
ds-reg dup 4 SUBI ds-reg dup 4 SUBI
4 0 swap LOAD32 0 jit-literal rc-absolute-ppc-2/2 rt-vm jit-rel 4 0 swap LOAD32 0 jit-parameter rc-absolute-ppc-2/2 rt-vm jit-rel
5 3 quot-xt-offset LWZ 5 3 quot-xt-offset LWZ
5 MTCTR 5 MTCTR
BCTR BCTR

View File

@ -231,7 +231,7 @@ big-endian off
! pop stack ! pop stack
ds-reg bootstrap-cell SUB ds-reg bootstrap-cell SUB
! pass vm pointer ! pass vm pointer
arg2 0 MOV 0 jit-literal rc-absolute-cell rt-vm jit-rel arg2 0 MOV 0 jit-parameter rc-absolute-cell rt-vm jit-rel
! call quotation ! call quotation
arg1 quot-xt-offset [+] JMP arg1 quot-xt-offset [+] JMP
] \ (call) define-sub-primitive ] \ (call) define-sub-primitive

View File

@ -53,7 +53,7 @@ code_block *callback_heap::add(cell owner)
code_block *stub = (code_block *)free_block; code_block *stub = (code_block *)free_block;
stub->owner = owner; stub->owner = owner;
stub->literals = false_object; stub->parameters = false_object;
stub->relocation = false_object; stub->relocation = false_object;
memcpy(stub->xt(),insns->data<void>(),size); memcpy(stub->xt(),insns->data<void>(),size);

View File

@ -23,6 +23,7 @@ template<typename Visitor> struct code_block_visitor {
void visit_object_code_block(object *obj); void visit_object_code_block(object *obj);
void visit_embedded_code_pointers(code_block *compiled); void visit_embedded_code_pointers(code_block *compiled);
void visit_context_code_blocks(); void visit_context_code_blocks();
void visit_uninitialized_code_blocks();
}; };
template<typename Visitor> template<typename Visitor>
@ -102,7 +103,7 @@ struct embedded_code_pointers_visitor {
template<typename Visitor> template<typename Visitor>
void code_block_visitor<Visitor>::visit_embedded_code_pointers(code_block *compiled) void code_block_visitor<Visitor>::visit_embedded_code_pointers(code_block *compiled)
{ {
if(!parent->code->needs_fixup_p(compiled)) if(!parent->code->uninitialized_p(compiled))
{ {
embedded_code_pointers_visitor<Visitor> visitor(this->visitor); embedded_code_pointers_visitor<Visitor> visitor(this->visitor);
compiled->each_instruction_operand(visitor); compiled->each_instruction_operand(visitor);
@ -116,4 +117,22 @@ void code_block_visitor<Visitor>::visit_context_code_blocks()
parent->iterate_active_frames(call_frame_visitor); parent->iterate_active_frames(call_frame_visitor);
} }
template<typename Visitor>
void code_block_visitor<Visitor>::visit_uninitialized_code_blocks()
{
std::map<code_block *, cell> *uninitialized_blocks = &parent->code->uninitialized_blocks;
std::map<code_block *, cell>::const_iterator iter = uninitialized_blocks->begin();
std::map<code_block *, cell>::const_iterator end = uninitialized_blocks->end();
std::map<code_block *, cell> new_uninitialized_blocks;
for(; iter != end; iter++)
{
new_uninitialized_blocks.insert(std::make_pair(
visitor(iter->first),
iter->second));
}
parent->code->uninitialized_blocks = new_uninitialized_blocks;
}
} }

View File

@ -109,7 +109,7 @@ to update references to other words, without worrying about literals
or dlsyms. */ or dlsyms. */
void factor_vm::update_word_references(code_block *compiled) void factor_vm::update_word_references(code_block *compiled)
{ {
if(code->needs_fixup_p(compiled)) if(code->uninitialized_p(compiled))
initialize_code_block(compiled); initialize_code_block(compiled);
/* update_word_references() is always applied to every block in /* update_word_references() is always applied to every block in
the code heap. Since it resets all call sites to point to the code heap. Since it resets all call sites to point to
@ -213,19 +213,19 @@ cell factor_vm::compute_vm_address(cell arg)
void factor_vm::store_external_address(instruction_operand op) void factor_vm::store_external_address(instruction_operand op)
{ {
code_block *compiled = op.parent_code_block(); code_block *compiled = op.parent_code_block();
array *literals = (to_boolean(compiled->literals) ? untag<array>(compiled->literals) : NULL); array *parameters = (to_boolean(compiled->parameters) ? untag<array>(compiled->parameters) : NULL);
cell index = op.parameter_index(); cell index = op.parameter_index();
switch(op.rel_type()) switch(op.rel_type())
{ {
case RT_PRIMITIVE: case RT_PRIMITIVE:
op.store_value(compute_primitive_address(array_nth(literals,index))); op.store_value(compute_primitive_address(array_nth(parameters,index)));
break; break;
case RT_DLSYM: case RT_DLSYM:
op.store_value(compute_dlsym_address(literals,index)); op.store_value(compute_dlsym_address(parameters,index));
break; break;
case RT_HERE: case RT_HERE:
op.store_value(compute_here_address(array_nth(literals,index),op.rel_offset(),compiled)); op.store_value(compute_here_address(array_nth(parameters,index),op.rel_offset(),compiled));
break; break;
case RT_THIS: case RT_THIS:
op.store_value((cell)compiled->xt()); op.store_value((cell)compiled->xt());
@ -233,14 +233,11 @@ void factor_vm::store_external_address(instruction_operand op)
case RT_CONTEXT: case RT_CONTEXT:
op.store_value(compute_context_address()); op.store_value(compute_context_address());
break; break;
case RT_UNTAGGED:
op.store_value(untag_fixnum(array_nth(literals,index)));
break;
case RT_MEGAMORPHIC_CACHE_HITS: case RT_MEGAMORPHIC_CACHE_HITS:
op.store_value((cell)&dispatch_stats.megamorphic_cache_hits); op.store_value((cell)&dispatch_stats.megamorphic_cache_hits);
break; break;
case RT_VM: case RT_VM:
op.store_value(compute_vm_address(array_nth(literals,index))); op.store_value(compute_vm_address(array_nth(parameters,index)));
break; break;
case RT_CARDS_OFFSET: case RT_CARDS_OFFSET:
op.store_value(cards_offset); op.store_value(cards_offset);
@ -256,28 +253,35 @@ void factor_vm::store_external_address(instruction_operand op)
struct initial_code_block_visitor { struct initial_code_block_visitor {
factor_vm *parent; factor_vm *parent;
cell literals;
cell literal_index;
explicit initial_code_block_visitor(factor_vm *parent_) : parent(parent_) {} explicit initial_code_block_visitor(factor_vm *parent_, cell literals_)
: parent(parent_), literals(literals_), literal_index(0) {}
cell next_literal()
{
return array_nth(untag<array>(literals),literal_index++);
}
void operator()(instruction_operand op) void operator()(instruction_operand op)
{ {
code_block *compiled = op.parent_code_block();
array *literals = (to_boolean(compiled->literals) ? untag<array>(compiled->literals) : NULL);
cell index = op.parameter_index();
switch(op.rel_type()) switch(op.rel_type())
{ {
case RT_IMMEDIATE: case RT_IMMEDIATE:
op.store_value(array_nth(literals,index)); op.store_value(next_literal());
break; break;
case RT_XT: case RT_XT:
op.store_value(parent->compute_xt_address(array_nth(literals,index))); op.store_value(parent->compute_xt_address(next_literal()));
break; break;
case RT_XT_PIC: case RT_XT_PIC:
op.store_value(parent->compute_xt_pic_address(array_nth(literals,index))); op.store_value(parent->compute_xt_pic_address(next_literal()));
break; break;
case RT_XT_PIC_TAIL: case RT_XT_PIC_TAIL:
op.store_value(parent->compute_xt_pic_tail_address(array_nth(literals,index))); op.store_value(parent->compute_xt_pic_tail_address(next_literal()));
break;
case RT_UNTAGGED:
op.store_value(untag_fixnum(next_literal()));
break; break;
default: default:
parent->store_external_address(op); parent->store_external_address(op);
@ -289,10 +293,11 @@ struct initial_code_block_visitor {
/* Perform all fixups on a code block */ /* Perform all fixups on a code block */
void factor_vm::initialize_code_block(code_block *compiled) void factor_vm::initialize_code_block(code_block *compiled)
{ {
code->needs_fixup.erase(compiled); std::map<code_block *,cell>::iterator iter = code->uninitialized_blocks.find(compiled);
initial_code_block_visitor visitor(this); initial_code_block_visitor visitor(this,iter->second);
compiled->each_instruction_operand(visitor); compiled->each_instruction_operand(visitor);
compiled->flush_icache(); compiled->flush_icache();
code->uninitialized_blocks.erase(iter);
} }
/* Fixup labels. This is done at compile time, not image load time */ /* Fixup labels. This is done at compile time, not image load time */
@ -342,12 +347,13 @@ code_block *factor_vm::allot_code_block(cell size, code_block_type type)
} }
/* Might GC */ /* Might GC */
code_block *factor_vm::add_code_block(code_block_type type, cell code_, cell labels_, cell owner_, cell relocation_, cell literals_) code_block *factor_vm::add_code_block(code_block_type type, cell code_, cell labels_, cell owner_, cell relocation_, cell parameters_, cell literals_)
{ {
data_root<byte_array> code(code_,this); data_root<byte_array> code(code_,this);
data_root<object> labels(labels_,this); data_root<object> labels(labels_,this);
data_root<object> owner(owner_,this); data_root<object> owner(owner_,this);
data_root<byte_array> relocation(relocation_,this); data_root<byte_array> relocation(relocation_,this);
data_root<array> parameters(parameters_,this);
data_root<array> literals(literals_,this); data_root<array> literals(literals_,this);
cell code_length = array_capacity(code.untagged()); cell code_length = array_capacity(code.untagged());
@ -361,10 +367,10 @@ code_block *factor_vm::add_code_block(code_block_type type, cell code_, cell lab
else else
compiled->relocation = relocation.value(); compiled->relocation = relocation.value();
if(literals.type() == ARRAY_TYPE && array_capacity(literals.untagged()) == 0) if(parameters.type() == ARRAY_TYPE && array_capacity(parameters.untagged()) == 0)
compiled->literals = false_object; compiled->parameters = false_object;
else else
compiled->literals = literals.value(); compiled->parameters = parameters.value();
/* code */ /* code */
memcpy(compiled + 1,code.untagged() + 1,code_length); memcpy(compiled + 1,code.untagged() + 1,code_length);
@ -376,7 +382,7 @@ code_block *factor_vm::add_code_block(code_block_type type, cell code_, cell lab
/* next time we do a minor GC, we have to scan the code heap for /* next time we do a minor GC, we have to scan the code heap for
literals */ literals */
this->code->write_barrier(compiled); this->code->write_barrier(compiled);
this->code->needs_fixup.insert(compiled); this->code->uninitialized_blocks.insert(std::make_pair(compiled,literals.value()));
return compiled; return compiled;
} }

View File

@ -6,7 +6,7 @@ struct code_block
{ {
cell header; cell header;
cell owner; /* tagged pointer to word, quotation or f */ cell owner; /* tagged pointer to word, quotation or f */
cell literals; /* tagged pointer to array or f */ cell parameters; /* tagged pointer to array or f */
cell relocation; /* tagged pointer to byte-array or f */ cell relocation; /* tagged pointer to byte-array or f */
bool free_p() const bool free_p() const

View File

@ -31,9 +31,9 @@ void code_heap::clear_remembered_set()
points_to_aging.clear(); points_to_aging.clear();
} }
bool code_heap::needs_fixup_p(code_block *compiled) bool code_heap::uninitialized_p(code_block *compiled)
{ {
return needs_fixup.count(compiled) > 0; return uninitialized_blocks.count(compiled) > 0;
} }
bool code_heap::marked_p(code_block *compiled) bool code_heap::marked_p(code_block *compiled)
@ -55,7 +55,7 @@ void code_heap::code_heap_free(code_block *compiled)
{ {
points_to_nursery.erase(compiled); points_to_nursery.erase(compiled);
points_to_aging.erase(compiled); points_to_aging.erase(compiled);
needs_fixup.erase(compiled); uninitialized_blocks.erase(compiled);
allocator->free(compiled); allocator->free(compiled);
} }
@ -118,10 +118,11 @@ void factor_vm::primitive_modify_code_heap()
case ARRAY_TYPE: case ARRAY_TYPE:
{ {
array *compiled_data = data.as<array>().untagged(); array *compiled_data = data.as<array>().untagged();
cell literals = array_nth(compiled_data,0); cell parameters = array_nth(compiled_data,0);
cell relocation = array_nth(compiled_data,1); cell literals = array_nth(compiled_data,1);
cell labels = array_nth(compiled_data,2); cell relocation = array_nth(compiled_data,2);
cell code = array_nth(compiled_data,3); cell labels = array_nth(compiled_data,3);
cell code = array_nth(compiled_data,4);
code_block *compiled = add_code_block( code_block *compiled = add_code_block(
code_block_optimized, code_block_optimized,
@ -129,6 +130,7 @@ void factor_vm::primitive_modify_code_heap()
labels, labels,
word.value(), word.value(),
relocation, relocation,
parameters,
literals); literals);
word->code = compiled; word->code = compiled;

View File

@ -8,8 +8,10 @@ struct code_heap {
/* Memory allocator */ /* Memory allocator */
free_list_allocator<code_block> *allocator; free_list_allocator<code_block> *allocator;
/* Set of blocks which need to be initialized by initialize_code_block(). */ /* Keys are blocks which need to be initialized by initialize_code_block().
std::set<code_block *> needs_fixup; Values are literal tables. Literal table arrays are GC roots until the
time the block is initialized, after which point they are discarded. */
std::map<code_block *, cell> uninitialized_blocks;
/* Code blocks which may reference objects in the nursery */ /* Code blocks which may reference objects in the nursery */
std::set<code_block *> points_to_nursery; std::set<code_block *> points_to_nursery;
@ -21,7 +23,7 @@ struct code_heap {
~code_heap(); ~code_heap();
void write_barrier(code_block *compiled); void write_barrier(code_block *compiled);
void clear_remembered_set(); void clear_remembered_set();
bool needs_fixup_p(code_block *compiled); bool uninitialized_p(code_block *compiled);
bool marked_p(code_block *compiled); bool marked_p(code_block *compiled);
void set_marked_p(code_block *compiled); void set_marked_p(code_block *compiled);
void clear_mark_bits(); void clear_mark_bits();

View File

@ -2,18 +2,6 @@
namespace factor { namespace factor {
void factor_vm::update_fixup_set_for_compaction(mark_bits<code_block> *forwarding_map)
{
std::set<code_block *>::const_iterator iter = code->needs_fixup.begin();
std::set<code_block *>::const_iterator end = code->needs_fixup.end();
std::set<code_block *> new_needs_fixup;
for(; iter != end; iter++)
new_needs_fixup.insert(forwarding_map->forward_block(*iter));
code->needs_fixup = new_needs_fixup;
}
template<typename Block> struct forwarder { template<typename Block> struct forwarder {
mark_bits<Block> *forwarding_map; mark_bits<Block> *forwarding_map;
@ -178,11 +166,11 @@ void factor_vm::collect_compact_impl(bool trace_contexts_p)
data_forwarding_map->compute_forwarding(); data_forwarding_map->compute_forwarding();
code_forwarding_map->compute_forwarding(); code_forwarding_map->compute_forwarding();
update_fixup_set_for_compaction(code_forwarding_map);
slot_visitor<forwarder<object> > slot_forwarder(this,forwarder<object>(data_forwarding_map)); slot_visitor<forwarder<object> > slot_forwarder(this,forwarder<object>(data_forwarding_map));
code_block_visitor<forwarder<code_block> > code_forwarder(this,forwarder<code_block>(code_forwarding_map)); code_block_visitor<forwarder<code_block> > code_forwarder(this,forwarder<code_block>(code_forwarding_map));
code_forwarder.visit_uninitialized_code_blocks();
/* Object start offsets get recomputed by the object_compaction_updater */ /* Object start offsets get recomputed by the object_compaction_updater */
data->tenured->starts.clear_object_start_offsets(); data->tenured->starts.clear_object_start_offsets();
@ -234,11 +222,11 @@ void factor_vm::collect_compact_code_impl(bool trace_contexts_p)
mark_bits<code_block> *code_forwarding_map = &code->allocator->state; mark_bits<code_block> *code_forwarding_map = &code->allocator->state;
code_forwarding_map->compute_forwarding(); code_forwarding_map->compute_forwarding();
update_fixup_set_for_compaction(code_forwarding_map);
slot_visitor<dummy_slot_forwarder> slot_forwarder(this,dummy_slot_forwarder()); slot_visitor<dummy_slot_forwarder> slot_forwarder(this,dummy_slot_forwarder());
code_block_visitor<forwarder<code_block> > code_forwarder(this,forwarder<code_block>(code_forwarding_map)); code_block_visitor<forwarder<code_block> > code_forwarder(this,forwarder<code_block>(code_forwarding_map));
code_forwarder.visit_uninitialized_code_blocks();
if(trace_contexts_p) if(trace_contexts_p)
code_forwarder.visit_context_code_blocks(); code_forwarder.visit_context_code_blocks();

View File

@ -300,10 +300,10 @@ void factor_vm::find_data_references(cell look_for)
struct code_block_printer { struct code_block_printer {
factor_vm *parent; factor_vm *parent;
cell reloc_size, literal_size; cell reloc_size, parameter_size;
explicit code_block_printer(factor_vm *parent_) : explicit code_block_printer(factor_vm *parent_) :
parent(parent_), reloc_size(0), literal_size(0) {} parent(parent_), reloc_size(0), parameter_size(0) {}
void operator()(code_block *scan, cell size) void operator()(code_block *scan, cell size)
{ {
@ -313,7 +313,7 @@ struct code_block_printer {
else else
{ {
reloc_size += parent->object_size(scan->relocation); reloc_size += parent->object_size(scan->relocation);
literal_size += parent->object_size(scan->literals); parameter_size += parent->object_size(scan->parameters);
if(parent->code->marked_p(scan)) if(parent->code->marked_p(scan))
status = "marked"; status = "marked";
@ -332,8 +332,8 @@ void factor_vm::dump_code_heap()
{ {
code_block_printer printer(this); code_block_printer printer(this);
code->allocator->iterate(printer); code->allocator->iterate(printer);
std::cout << printer.reloc_size << " bytes of relocation data\n"; std::cout << printer.reloc_size << " bytes used by relocation tables\n";
std::cout << printer.literal_size << " bytes of literal data\n"; std::cout << printer.parameter_size << " bytes used by parameter tables\n";
} }
void factor_vm::factorbug() void factor_vm::factorbug()

View File

@ -152,7 +152,7 @@ void quotation_jit::emit_mega_cache_lookup(cell methods_, fixnum index, cell cac
emit_class_lookup(index,PIC_TUPLE); emit_class_lookup(index,PIC_TUPLE);
/* Do a cache lookup. */ /* Do a cache lookup. */
emit_with(parent->special_objects[MEGA_LOOKUP],cache.value()); emit_with_literal(parent->special_objects[MEGA_LOOKUP],cache.value());
/* If we end up here, the cache missed. */ /* If we end up here, the cache missed. */
emit(parent->special_objects[JIT_PROLOG]); emit(parent->special_objects[JIT_PROLOG]);

View File

@ -27,6 +27,11 @@ void full_collector::trace_context_code_blocks()
code_visitor.visit_context_code_blocks(); code_visitor.visit_context_code_blocks();
} }
void full_collector::trace_uninitialized_code_blocks()
{
code_visitor.visit_uninitialized_code_blocks();
}
void full_collector::trace_object_code_block(object *obj) void full_collector::trace_object_code_block(object *obj)
{ {
code_visitor.visit_object_code_block(obj); code_visitor.visit_object_code_block(obj);
@ -94,6 +99,7 @@ void factor_vm::collect_mark_impl(bool trace_contexts_p)
{ {
collector.trace_contexts(); collector.trace_contexts();
collector.trace_context_code_blocks(); collector.trace_context_code_blocks();
collector.trace_uninitialized_code_blocks();
} }
while(!mark_stack.empty()) while(!mark_stack.empty())

View File

@ -49,6 +49,7 @@ struct full_collector : collector<tenured_space,full_policy> {
explicit full_collector(factor_vm *parent_); explicit full_collector(factor_vm *parent_);
void trace_code_block(code_block *compiled); void trace_code_block(code_block *compiled);
void trace_context_code_blocks(); void trace_context_code_blocks();
void trace_uninitialized_code_blocks();
void trace_object_code_block(object *obj); void trace_object_code_block(object *obj);
}; };

View File

@ -190,6 +190,8 @@ struct code_block_fixup_relocation_visitor {
case RT_XT_PIC_TAIL: case RT_XT_PIC_TAIL:
op.store_code_block(code_visitor(op.load_code_block(old_offset))); op.store_code_block(code_visitor(op.load_code_block(old_offset)));
break; break;
case RT_UNTAGGED:
break;
default: default:
parent->store_external_address(op); parent->store_external_address(op);
break; break;

View File

@ -70,7 +70,7 @@ void inline_cache_jit::emit_check(cell klass)
else else
code_template = parent->special_objects[PIC_CHECK_TUPLE]; code_template = parent->special_objects[PIC_CHECK_TUPLE];
emit_with(code_template,klass); emit_with_literal(code_template,klass);
} }
/* index: 0 = top of stack, 1 = item underneath, etc /* index: 0 = top of stack, 1 = item underneath, etc
@ -101,7 +101,7 @@ void inline_cache_jit::compile_inline_cache(fixnum index,
/* Yes? Jump to method */ /* Yes? Jump to method */
cell method = array_nth(cache_entries.untagged(),i + 1); cell method = array_nth(cache_entries.untagged(),i + 1);
emit_with(parent->special_objects[PIC_HIT],method); emit_with_literal(parent->special_objects[PIC_HIT],method);
} }
/* Generate machine code to handle a cache miss, which ultimately results in /* Generate machine code to handle a cache miss, which ultimately results in

View File

@ -96,16 +96,16 @@ struct relocation_entry {
switch(rel_type()) switch(rel_type())
{ {
case RT_PRIMITIVE: case RT_PRIMITIVE:
case RT_XT:
case RT_XT_PIC:
case RT_XT_PIC_TAIL:
case RT_IMMEDIATE:
case RT_HERE: case RT_HERE:
case RT_UNTAGGED:
case RT_VM: case RT_VM:
return 1; return 1;
case RT_DLSYM: case RT_DLSYM:
return 2; return 2;
case RT_XT:
case RT_XT_PIC:
case RT_XT_PIC_TAIL:
case RT_IMMEDIATE:
case RT_UNTAGGED:
case RT_THIS: case RT_THIS:
case RT_CONTEXT: case RT_CONTEXT:
case RT_MEGAMORPHIC_CACHE_HITS: case RT_MEGAMORPHIC_CACHE_HITS:

View File

@ -15,6 +15,7 @@ jit::jit(code_block_type type_, cell owner_, factor_vm *vm)
owner(owner_,vm), owner(owner_,vm),
code(vm), code(vm),
relocation(vm), relocation(vm),
parameters(vm),
literals(vm), literals(vm),
computing_offset_p(false), computing_offset_p(false),
position(0), position(0),
@ -67,16 +68,23 @@ void jit::emit(cell code_template_)
code.append_byte_array(insns.value()); code.append_byte_array(insns.value());
} }
void jit::emit_with(cell code_template_, cell argument_) { void jit::emit_with_literal(cell code_template_, cell argument_) {
data_root<array> code_template(code_template_,parent); data_root<array> code_template(code_template_,parent);
data_root<object> argument(argument_,parent); data_root<object> argument(argument_,parent);
literal(argument.value()); literal(argument.value());
emit(code_template.value()); emit(code_template.value());
} }
void jit::emit_with_parameter(cell code_template_, cell argument_) {
data_root<array> code_template(code_template_,parent);
data_root<object> argument(argument_,parent);
parameter(argument.value());
emit(code_template.value());
}
void jit::emit_class_lookup(fixnum index, cell type) void jit::emit_class_lookup(fixnum index, cell type)
{ {
emit_with(parent->special_objects[PIC_LOAD],tag_fixnum(-index * sizeof(cell))); emit_with_literal(parent->special_objects[PIC_LOAD],tag_fixnum(-index * sizeof(cell)));
emit(parent->special_objects[type]); emit(parent->special_objects[type]);
} }
@ -95,6 +103,7 @@ code_block *jit::to_code_block()
{ {
code.trim(); code.trim();
relocation.trim(); relocation.trim();
parameters.trim();
literals.trim(); literals.trim();
return parent->add_code_block( return parent->add_code_block(
@ -103,6 +112,7 @@ code_block *jit::to_code_block()
false_object, /* no labels */ false_object, /* no labels */
owner.value(), owner.value(),
relocation.elements.value(), relocation.elements.value(),
parameters.elements.value(),
literals.elements.value()); literals.elements.value());
} }

View File

@ -6,6 +6,7 @@ struct jit {
data_root<object> owner; data_root<object> owner;
growable_byte_array code; growable_byte_array code;
growable_byte_array relocation; growable_byte_array relocation;
growable_array parameters;
growable_array literals; growable_array literals;
bool computing_offset_p; bool computing_offset_p;
fixnum position; fixnum position;
@ -18,38 +19,41 @@ struct jit {
void emit_relocation(cell code_template); void emit_relocation(cell code_template);
void emit(cell code_template); void emit(cell code_template);
void parameter(cell parameter) { parameters.add(parameter); }
void emit_with_parameter(cell code_template_, cell parameter_);
void literal(cell literal) { literals.add(literal); } void literal(cell literal) { literals.add(literal); }
void emit_with(cell code_template_, cell literal_); void emit_with_literal(cell code_template_, cell literal_);
void push(cell literal) void push(cell literal)
{ {
emit_with(parent->special_objects[JIT_PUSH_IMMEDIATE],literal); emit_with_literal(parent->special_objects[JIT_PUSH_IMMEDIATE],literal);
} }
void word_jump(cell word_) void word_jump(cell word_)
{ {
data_root<word> word(word_,parent); data_root<word> word(word_,parent);
literal(tag_fixnum(xt_tail_pic_offset)); parameter(tag_fixnum(xt_tail_pic_offset));
literal(word.value()); emit_with_literal(parent->special_objects[JIT_WORD_JUMP],word.value());
emit(parent->special_objects[JIT_WORD_JUMP]);
} }
void word_call(cell word) void word_call(cell word)
{ {
emit_with(parent->special_objects[JIT_WORD_CALL],word); emit_with_literal(parent->special_objects[JIT_WORD_CALL],word);
} }
void word_special(cell word) void word_special(cell word)
{ {
emit_with(parent->special_objects[JIT_WORD_SPECIAL],word); emit_with_literal(parent->special_objects[JIT_WORD_SPECIAL],word);
} }
void emit_subprimitive(cell word_) void emit_subprimitive(cell word_)
{ {
data_root<word> word(word_,parent); data_root<word> word(word_,parent);
data_root<array> code_pair(word->subprimitive,parent); data_root<array> code_triple(word->subprimitive,parent);
literals.append(untag<array>(array_nth(code_pair.untagged(),0))); parameters.append(untag<array>(array_nth(code_triple.untagged(),0)));
emit(array_nth(code_pair.untagged(),1)); literals.append(untag<array>(array_nth(code_triple.untagged(),1)));
emit(array_nth(code_triple.untagged(),2));
} }
void emit_class_lookup(fixnum index, cell type); void emit_class_lookup(fixnum index, cell type);

View File

@ -14,7 +14,7 @@ code_block *factor_vm::compile_profiling_stub(cell word_)
data_root<word> word(word_,this); data_root<word> word(word_,this);
jit jit(code_block_profiling,word.value(),this); jit jit(code_block_profiling,word.value(),this);
jit.emit_with(special_objects[JIT_PROFILING],word.value()); jit.emit_with_literal(special_objects[JIT_PROFILING],word.value());
return jit.to_code_block(); return jit.to_code_block();
} }

View File

@ -204,8 +204,8 @@ void quotation_jit::iterate_quotation()
/* Primitive calls */ /* Primitive calls */
if(primitive_call_p(i,length)) if(primitive_call_p(i,length))
{ {
literal(tag_fixnum(0)); parameter(tag_fixnum(0));
literal(obj.value()); parameter(obj.value());
emit(parent->special_objects[JIT_PRIMITIVE]); emit(parent->special_objects[JIT_PRIMITIVE]);
i++; i++;

View File

@ -32,6 +32,7 @@ template<typename Visitor> struct slot_visitor {
void visit_data_roots(); void visit_data_roots();
void visit_bignum_roots(); void visit_bignum_roots();
void visit_callback_roots(); void visit_callback_roots();
void visit_literal_table_roots();
void visit_roots(); void visit_roots();
void visit_contexts(); void visit_contexts();
void visit_code_block_objects(code_block *compiled); void visit_code_block_objects(code_block *compiled);
@ -130,6 +131,24 @@ void slot_visitor<Visitor>::visit_callback_roots()
parent->callbacks->each_callback(callback_visitor); parent->callbacks->each_callback(callback_visitor);
} }
template<typename Visitor>
void slot_visitor<Visitor>::visit_literal_table_roots()
{
std::map<code_block *, cell> *uninitialized_blocks = &parent->code->uninitialized_blocks;
std::map<code_block *, cell>::const_iterator iter = uninitialized_blocks->begin();
std::map<code_block *, cell>::const_iterator end = uninitialized_blocks->end();
std::map<code_block *, cell> new_uninitialized_blocks;
for(; iter != end; iter++)
{
new_uninitialized_blocks.insert(std::make_pair(
iter->first,
visit_pointer(iter->second)));
}
parent->code->uninitialized_blocks = new_uninitialized_blocks;
}
template<typename Visitor> template<typename Visitor>
void slot_visitor<Visitor>::visit_roots() void slot_visitor<Visitor>::visit_roots()
{ {
@ -141,6 +160,7 @@ void slot_visitor<Visitor>::visit_roots()
visit_data_roots(); visit_data_roots();
visit_bignum_roots(); visit_bignum_roots();
visit_callback_roots(); visit_callback_roots();
visit_literal_table_roots();
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]);
@ -180,14 +200,14 @@ template<typename Visitor>
void slot_visitor<Visitor>::visit_code_block_objects(code_block *compiled) void slot_visitor<Visitor>::visit_code_block_objects(code_block *compiled)
{ {
visit_handle(&compiled->owner); visit_handle(&compiled->owner);
visit_handle(&compiled->literals); visit_handle(&compiled->parameters);
visit_handle(&compiled->relocation); visit_handle(&compiled->relocation);
} }
template<typename Visitor> template<typename Visitor>
void slot_visitor<Visitor>::visit_embedded_literals(code_block *compiled) void slot_visitor<Visitor>::visit_embedded_literals(code_block *compiled)
{ {
if(!parent->code->needs_fixup_p(compiled)) if(!parent->code->uninitialized_p(compiled))
{ {
literal_references_visitor<Visitor> visitor(this); literal_references_visitor<Visitor> visitor(this);
compiled->each_instruction_operand(visitor); compiled->each_instruction_operand(visitor);

View File

@ -288,7 +288,6 @@ struct factor_vm
void collect_mark_impl(bool trace_contexts_p); void collect_mark_impl(bool trace_contexts_p);
void collect_sweep_impl(); void collect_sweep_impl();
void collect_full(bool trace_contexts_p); void collect_full(bool trace_contexts_p);
void update_fixup_set_for_compaction(mark_bits<code_block> *forwarding_map);
void collect_compact_impl(bool trace_contexts_p); void collect_compact_impl(bool trace_contexts_p);
void collect_compact_code_impl(bool trace_contexts_p); void collect_compact_code_impl(bool trace_contexts_p);
void collect_compact(bool trace_contexts_p); void collect_compact(bool trace_contexts_p);
@ -520,7 +519,7 @@ struct factor_vm
void initialize_code_block(code_block *compiled); void initialize_code_block(code_block *compiled);
void fixup_labels(array *labels, code_block *compiled); void fixup_labels(array *labels, code_block *compiled);
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 parameters_, cell literals_);
//code heap //code heap
inline void check_code_pointer(cell ptr) inline void check_code_pointer(cell ptr)