Split literal table into literal and parameter tables, literal table is discarded after code block initialization
parent
147edb1ce9
commit
68c09f0e93
|
@ -113,25 +113,32 @@ SYMBOL: jit-relocations
|
|||
: jit-rel ( rc rt -- )
|
||||
over compute-offset 3array jit-relocations get push-all ;
|
||||
|
||||
SYMBOL: jit-parameters
|
||||
|
||||
: jit-parameter ( parameter -- )
|
||||
jit-parameters get push ;
|
||||
|
||||
SYMBOL: jit-literals
|
||||
|
||||
: jit-literal ( literal -- )
|
||||
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-relocations set
|
||||
call( -- )
|
||||
jit-parameters get >array
|
||||
jit-literals get >array
|
||||
jit-relocations get >array
|
||||
] B{ } make prefix ;
|
||||
|
||||
: jit-define ( quot name -- )
|
||||
[ make-jit nip ] dip set ;
|
||||
[ make-jit 2nip ] dip set ;
|
||||
|
||||
: 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
|
||||
SYMBOL: image
|
||||
|
|
|
@ -63,7 +63,7 @@ M: ##no-tco generate-insn drop ;
|
|||
|
||||
M: ##call generate-insn
|
||||
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 ;
|
||||
|
||||
|
|
|
@ -3,13 +3,18 @@
|
|||
USING: arrays byte-arrays byte-vectors generic assocs hashtables
|
||||
io.binary kernel kernel.private math namespaces make sequences
|
||||
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 ;
|
||||
IN: compiler.codegen.fixup
|
||||
|
||||
! Owner
|
||||
SYMBOL: compiling-word
|
||||
|
||||
! Parameter table
|
||||
SYMBOL: parameter-table
|
||||
|
||||
: add-parameter ( obj -- ) parameter-table get push ;
|
||||
|
||||
! Literal table
|
||||
SYMBOL: literal-table
|
||||
|
||||
|
@ -50,11 +55,11 @@ SYMBOL: relocation-table
|
|||
: rel-fixup ( class type -- )
|
||||
swap dup offset-for-class add-relocation-entry ;
|
||||
|
||||
: add-dlsym-literals ( symbol dll -- )
|
||||
[ string>symbol add-literal ] [ add-literal ] bi* ;
|
||||
: add-dlsym-parameters ( symbol dll -- )
|
||||
[ string>symbol add-parameter ] [ add-parameter ] bi* ;
|
||||
|
||||
: 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 -- )
|
||||
[ add-literal ] dip rt-xt rel-fixup ;
|
||||
|
@ -66,7 +71,7 @@ SYMBOL: relocation-table
|
|||
[ add-literal ] dip rt-xt-pic-tail rel-fixup ;
|
||||
|
||||
: 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 -- )
|
||||
[ add-literal ] dip rt-immediate rel-fixup ;
|
||||
|
@ -75,10 +80,10 @@ SYMBOL: relocation-table
|
|||
rt-this rel-fixup ;
|
||||
|
||||
: rel-here ( offset class -- )
|
||||
[ add-literal ] dip rt-here rel-fixup ;
|
||||
[ add-parameter ] dip rt-here rel-fixup ;
|
||||
|
||||
: rel-vm ( offset class -- )
|
||||
[ add-literal ] dip rt-vm rel-fixup ;
|
||||
[ add-parameter ] dip rt-vm rel-fixup ;
|
||||
|
||||
: rel-cards-offset ( class -- )
|
||||
rt-cards-offset rel-fixup ;
|
||||
|
@ -91,7 +96,7 @@ SYMBOL: relocation-table
|
|||
label>> offset>> [ "Unresolved label" throw ] unless* ;
|
||||
|
||||
: 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 ;
|
||||
|
||||
: resolve-relative-label ( label-fixup -- label )
|
||||
|
@ -105,6 +110,7 @@ SYMBOL: relocation-table
|
|||
|
||||
: init-fixup ( word -- )
|
||||
compiling-word set
|
||||
V{ } clone parameter-table set
|
||||
V{ } clone literal-table set
|
||||
V{ } clone label-table set
|
||||
BV{ } clone relocation-table set ;
|
||||
|
@ -114,7 +120,8 @@ SYMBOL: relocation-table
|
|||
init-fixup
|
||||
@
|
||||
label-table [ resolve-labels ] change
|
||||
parameter-table get >array
|
||||
literal-table get >array
|
||||
relocation-table get >byte-array
|
||||
label-table get
|
||||
] B{ } make 4array ; inline
|
||||
] B{ } make 5 narray ; inline
|
||||
|
|
|
@ -236,7 +236,7 @@ CONSTANT: rs-reg 14
|
|||
[
|
||||
3 ds-reg 0 LWZ
|
||||
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 MTCTR
|
||||
BCTR
|
||||
|
|
|
@ -231,7 +231,7 @@ big-endian off
|
|||
! pop stack
|
||||
ds-reg bootstrap-cell SUB
|
||||
! 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
|
||||
arg1 quot-xt-offset [+] JMP
|
||||
] \ (call) define-sub-primitive
|
||||
|
|
|
@ -53,7 +53,7 @@ code_block *callback_heap::add(cell owner)
|
|||
|
||||
code_block *stub = (code_block *)free_block;
|
||||
stub->owner = owner;
|
||||
stub->literals = false_object;
|
||||
stub->parameters = false_object;
|
||||
stub->relocation = false_object;
|
||||
|
||||
memcpy(stub->xt(),insns->data<void>(),size);
|
||||
|
|
|
@ -23,6 +23,7 @@ template<typename Visitor> struct code_block_visitor {
|
|||
void visit_object_code_block(object *obj);
|
||||
void visit_embedded_code_pointers(code_block *compiled);
|
||||
void visit_context_code_blocks();
|
||||
void visit_uninitialized_code_blocks();
|
||||
};
|
||||
|
||||
template<typename Visitor>
|
||||
|
@ -102,7 +103,7 @@ struct embedded_code_pointers_visitor {
|
|||
template<typename Visitor>
|
||||
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);
|
||||
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);
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -109,7 +109,7 @@ to update references to other words, without worrying about literals
|
|||
or dlsyms. */
|
||||
void factor_vm::update_word_references(code_block *compiled)
|
||||
{
|
||||
if(code->needs_fixup_p(compiled))
|
||||
if(code->uninitialized_p(compiled))
|
||||
initialize_code_block(compiled);
|
||||
/* update_word_references() is always applied to every block in
|
||||
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)
|
||||
{
|
||||
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();
|
||||
|
||||
switch(op.rel_type())
|
||||
{
|
||||
case RT_PRIMITIVE:
|
||||
op.store_value(compute_primitive_address(array_nth(literals,index)));
|
||||
op.store_value(compute_primitive_address(array_nth(parameters,index)));
|
||||
break;
|
||||
case RT_DLSYM:
|
||||
op.store_value(compute_dlsym_address(literals,index));
|
||||
op.store_value(compute_dlsym_address(parameters,index));
|
||||
break;
|
||||
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;
|
||||
case RT_THIS:
|
||||
op.store_value((cell)compiled->xt());
|
||||
|
@ -233,14 +233,11 @@ void factor_vm::store_external_address(instruction_operand op)
|
|||
case RT_CONTEXT:
|
||||
op.store_value(compute_context_address());
|
||||
break;
|
||||
case RT_UNTAGGED:
|
||||
op.store_value(untag_fixnum(array_nth(literals,index)));
|
||||
break;
|
||||
case RT_MEGAMORPHIC_CACHE_HITS:
|
||||
op.store_value((cell)&dispatch_stats.megamorphic_cache_hits);
|
||||
break;
|
||||
case RT_VM:
|
||||
op.store_value(compute_vm_address(array_nth(literals,index)));
|
||||
op.store_value(compute_vm_address(array_nth(parameters,index)));
|
||||
break;
|
||||
case RT_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 {
|
||||
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)
|
||||
{
|
||||
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())
|
||||
{
|
||||
case RT_IMMEDIATE:
|
||||
op.store_value(array_nth(literals,index));
|
||||
op.store_value(next_literal());
|
||||
break;
|
||||
case RT_XT:
|
||||
op.store_value(parent->compute_xt_address(array_nth(literals,index)));
|
||||
op.store_value(parent->compute_xt_address(next_literal()));
|
||||
break;
|
||||
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;
|
||||
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;
|
||||
default:
|
||||
parent->store_external_address(op);
|
||||
|
@ -289,10 +293,11 @@ struct initial_code_block_visitor {
|
|||
/* Perform all fixups on a code block */
|
||||
void factor_vm::initialize_code_block(code_block *compiled)
|
||||
{
|
||||
code->needs_fixup.erase(compiled);
|
||||
initial_code_block_visitor visitor(this);
|
||||
std::map<code_block *,cell>::iterator iter = code->uninitialized_blocks.find(compiled);
|
||||
initial_code_block_visitor visitor(this,iter->second);
|
||||
compiled->each_instruction_operand(visitor);
|
||||
compiled->flush_icache();
|
||||
code->uninitialized_blocks.erase(iter);
|
||||
}
|
||||
|
||||
/* 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 */
|
||||
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<object> labels(labels_,this);
|
||||
data_root<object> owner(owner_,this);
|
||||
data_root<byte_array> relocation(relocation_,this);
|
||||
data_root<array> parameters(parameters_,this);
|
||||
data_root<array> literals(literals_,this);
|
||||
|
||||
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
|
||||
compiled->relocation = relocation.value();
|
||||
|
||||
if(literals.type() == ARRAY_TYPE && array_capacity(literals.untagged()) == 0)
|
||||
compiled->literals = false_object;
|
||||
if(parameters.type() == ARRAY_TYPE && array_capacity(parameters.untagged()) == 0)
|
||||
compiled->parameters = false_object;
|
||||
else
|
||||
compiled->literals = literals.value();
|
||||
compiled->parameters = parameters.value();
|
||||
|
||||
/* code */
|
||||
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
|
||||
literals */
|
||||
this->code->write_barrier(compiled);
|
||||
this->code->needs_fixup.insert(compiled);
|
||||
this->code->uninitialized_blocks.insert(std::make_pair(compiled,literals.value()));
|
||||
|
||||
return compiled;
|
||||
}
|
||||
|
|
|
@ -6,7 +6,7 @@ struct code_block
|
|||
{
|
||||
cell header;
|
||||
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 */
|
||||
|
||||
bool free_p() const
|
||||
|
|
|
@ -31,9 +31,9 @@ void code_heap::clear_remembered_set()
|
|||
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)
|
||||
|
@ -55,7 +55,7 @@ void code_heap::code_heap_free(code_block *compiled)
|
|||
{
|
||||
points_to_nursery.erase(compiled);
|
||||
points_to_aging.erase(compiled);
|
||||
needs_fixup.erase(compiled);
|
||||
uninitialized_blocks.erase(compiled);
|
||||
allocator->free(compiled);
|
||||
}
|
||||
|
||||
|
@ -118,10 +118,11 @@ void factor_vm::primitive_modify_code_heap()
|
|||
case ARRAY_TYPE:
|
||||
{
|
||||
array *compiled_data = data.as<array>().untagged();
|
||||
cell literals = array_nth(compiled_data,0);
|
||||
cell relocation = array_nth(compiled_data,1);
|
||||
cell labels = array_nth(compiled_data,2);
|
||||
cell code = array_nth(compiled_data,3);
|
||||
cell parameters = array_nth(compiled_data,0);
|
||||
cell literals = array_nth(compiled_data,1);
|
||||
cell relocation = array_nth(compiled_data,2);
|
||||
cell labels = array_nth(compiled_data,3);
|
||||
cell code = array_nth(compiled_data,4);
|
||||
|
||||
code_block *compiled = add_code_block(
|
||||
code_block_optimized,
|
||||
|
@ -129,6 +130,7 @@ void factor_vm::primitive_modify_code_heap()
|
|||
labels,
|
||||
word.value(),
|
||||
relocation,
|
||||
parameters,
|
||||
literals);
|
||||
|
||||
word->code = compiled;
|
||||
|
|
|
@ -8,8 +8,10 @@ struct code_heap {
|
|||
/* Memory allocator */
|
||||
free_list_allocator<code_block> *allocator;
|
||||
|
||||
/* Set of blocks which need to be initialized by initialize_code_block(). */
|
||||
std::set<code_block *> needs_fixup;
|
||||
/* Keys are blocks which need to be initialized by initialize_code_block().
|
||||
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 */
|
||||
std::set<code_block *> points_to_nursery;
|
||||
|
@ -21,7 +23,7 @@ struct code_heap {
|
|||
~code_heap();
|
||||
void write_barrier(code_block *compiled);
|
||||
void clear_remembered_set();
|
||||
bool needs_fixup_p(code_block *compiled);
|
||||
bool uninitialized_p(code_block *compiled);
|
||||
bool marked_p(code_block *compiled);
|
||||
void set_marked_p(code_block *compiled);
|
||||
void clear_mark_bits();
|
||||
|
|
|
@ -2,18 +2,6 @@
|
|||
|
||||
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 {
|
||||
mark_bits<Block> *forwarding_map;
|
||||
|
||||
|
@ -178,11 +166,11 @@ void factor_vm::collect_compact_impl(bool trace_contexts_p)
|
|||
data_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));
|
||||
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 */
|
||||
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;
|
||||
code_forwarding_map->compute_forwarding();
|
||||
|
||||
update_fixup_set_for_compaction(code_forwarding_map);
|
||||
|
||||
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_forwarder.visit_uninitialized_code_blocks();
|
||||
|
||||
if(trace_contexts_p)
|
||||
code_forwarder.visit_context_code_blocks();
|
||||
|
||||
|
|
10
vm/debug.cpp
10
vm/debug.cpp
|
@ -300,10 +300,10 @@ void factor_vm::find_data_references(cell look_for)
|
|||
|
||||
struct code_block_printer {
|
||||
factor_vm *parent;
|
||||
cell reloc_size, literal_size;
|
||||
cell reloc_size, parameter_size;
|
||||
|
||||
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)
|
||||
{
|
||||
|
@ -313,7 +313,7 @@ struct code_block_printer {
|
|||
else
|
||||
{
|
||||
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))
|
||||
status = "marked";
|
||||
|
@ -332,8 +332,8 @@ void factor_vm::dump_code_heap()
|
|||
{
|
||||
code_block_printer printer(this);
|
||||
code->allocator->iterate(printer);
|
||||
std::cout << printer.reloc_size << " bytes of relocation data\n";
|
||||
std::cout << printer.literal_size << " bytes of literal data\n";
|
||||
std::cout << printer.reloc_size << " bytes used by relocation tables\n";
|
||||
std::cout << printer.parameter_size << " bytes used by parameter tables\n";
|
||||
}
|
||||
|
||||
void factor_vm::factorbug()
|
||||
|
|
|
@ -152,7 +152,7 @@ void quotation_jit::emit_mega_cache_lookup(cell methods_, fixnum index, cell cac
|
|||
emit_class_lookup(index,PIC_TUPLE);
|
||||
|
||||
/* 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. */
|
||||
emit(parent->special_objects[JIT_PROLOG]);
|
||||
|
|
|
@ -27,6 +27,11 @@ void full_collector::trace_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)
|
||||
{
|
||||
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_context_code_blocks();
|
||||
collector.trace_uninitialized_code_blocks();
|
||||
}
|
||||
|
||||
while(!mark_stack.empty())
|
||||
|
|
|
@ -49,6 +49,7 @@ struct full_collector : collector<tenured_space,full_policy> {
|
|||
explicit full_collector(factor_vm *parent_);
|
||||
void trace_code_block(code_block *compiled);
|
||||
void trace_context_code_blocks();
|
||||
void trace_uninitialized_code_blocks();
|
||||
void trace_object_code_block(object *obj);
|
||||
};
|
||||
|
||||
|
|
|
@ -190,6 +190,8 @@ struct code_block_fixup_relocation_visitor {
|
|||
case RT_XT_PIC_TAIL:
|
||||
op.store_code_block(code_visitor(op.load_code_block(old_offset)));
|
||||
break;
|
||||
case RT_UNTAGGED:
|
||||
break;
|
||||
default:
|
||||
parent->store_external_address(op);
|
||||
break;
|
||||
|
|
|
@ -70,7 +70,7 @@ void inline_cache_jit::emit_check(cell klass)
|
|||
else
|
||||
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
|
||||
|
@ -101,7 +101,7 @@ void inline_cache_jit::compile_inline_cache(fixnum index,
|
|||
|
||||
/* Yes? Jump to method */
|
||||
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
|
||||
|
|
|
@ -96,16 +96,16 @@ struct relocation_entry {
|
|||
switch(rel_type())
|
||||
{
|
||||
case RT_PRIMITIVE:
|
||||
case RT_XT:
|
||||
case RT_XT_PIC:
|
||||
case RT_XT_PIC_TAIL:
|
||||
case RT_IMMEDIATE:
|
||||
case RT_HERE:
|
||||
case RT_UNTAGGED:
|
||||
case RT_VM:
|
||||
return 1;
|
||||
case RT_DLSYM:
|
||||
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_CONTEXT:
|
||||
case RT_MEGAMORPHIC_CACHE_HITS:
|
||||
|
|
14
vm/jit.cpp
14
vm/jit.cpp
|
@ -15,6 +15,7 @@ jit::jit(code_block_type type_, cell owner_, factor_vm *vm)
|
|||
owner(owner_,vm),
|
||||
code(vm),
|
||||
relocation(vm),
|
||||
parameters(vm),
|
||||
literals(vm),
|
||||
computing_offset_p(false),
|
||||
position(0),
|
||||
|
@ -67,16 +68,23 @@ void jit::emit(cell code_template_)
|
|||
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<object> argument(argument_,parent);
|
||||
literal(argument.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)
|
||||
{
|
||||
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]);
|
||||
}
|
||||
|
||||
|
@ -95,6 +103,7 @@ code_block *jit::to_code_block()
|
|||
{
|
||||
code.trim();
|
||||
relocation.trim();
|
||||
parameters.trim();
|
||||
literals.trim();
|
||||
|
||||
return parent->add_code_block(
|
||||
|
@ -103,6 +112,7 @@ code_block *jit::to_code_block()
|
|||
false_object, /* no labels */
|
||||
owner.value(),
|
||||
relocation.elements.value(),
|
||||
parameters.elements.value(),
|
||||
literals.elements.value());
|
||||
}
|
||||
|
||||
|
|
24
vm/jit.hpp
24
vm/jit.hpp
|
@ -6,6 +6,7 @@ struct jit {
|
|||
data_root<object> owner;
|
||||
growable_byte_array code;
|
||||
growable_byte_array relocation;
|
||||
growable_array parameters;
|
||||
growable_array literals;
|
||||
bool computing_offset_p;
|
||||
fixnum position;
|
||||
|
@ -18,38 +19,41 @@ struct jit {
|
|||
void emit_relocation(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 emit_with(cell code_template_, cell literal_);
|
||||
void emit_with_literal(cell code_template_, 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_)
|
||||
{
|
||||
data_root<word> word(word_,parent);
|
||||
literal(tag_fixnum(xt_tail_pic_offset));
|
||||
literal(word.value());
|
||||
emit(parent->special_objects[JIT_WORD_JUMP]);
|
||||
parameter(tag_fixnum(xt_tail_pic_offset));
|
||||
emit_with_literal(parent->special_objects[JIT_WORD_JUMP],word.value());
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
emit_with(parent->special_objects[JIT_WORD_SPECIAL],word);
|
||||
emit_with_literal(parent->special_objects[JIT_WORD_SPECIAL],word);
|
||||
}
|
||||
|
||||
void emit_subprimitive(cell word_)
|
||||
{
|
||||
data_root<word> word(word_,parent);
|
||||
data_root<array> code_pair(word->subprimitive,parent);
|
||||
literals.append(untag<array>(array_nth(code_pair.untagged(),0)));
|
||||
emit(array_nth(code_pair.untagged(),1));
|
||||
data_root<array> code_triple(word->subprimitive,parent);
|
||||
parameters.append(untag<array>(array_nth(code_triple.untagged(),0)));
|
||||
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);
|
||||
|
|
|
@ -14,7 +14,7 @@ code_block *factor_vm::compile_profiling_stub(cell word_)
|
|||
data_root<word> word(word_,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();
|
||||
}
|
||||
|
|
|
@ -204,8 +204,8 @@ void quotation_jit::iterate_quotation()
|
|||
/* Primitive calls */
|
||||
if(primitive_call_p(i,length))
|
||||
{
|
||||
literal(tag_fixnum(0));
|
||||
literal(obj.value());
|
||||
parameter(tag_fixnum(0));
|
||||
parameter(obj.value());
|
||||
emit(parent->special_objects[JIT_PRIMITIVE]);
|
||||
|
||||
i++;
|
||||
|
|
|
@ -32,6 +32,7 @@ template<typename Visitor> struct slot_visitor {
|
|||
void visit_data_roots();
|
||||
void visit_bignum_roots();
|
||||
void visit_callback_roots();
|
||||
void visit_literal_table_roots();
|
||||
void visit_roots();
|
||||
void visit_contexts();
|
||||
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);
|
||||
}
|
||||
|
||||
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>
|
||||
void slot_visitor<Visitor>::visit_roots()
|
||||
{
|
||||
|
@ -141,6 +160,7 @@ void slot_visitor<Visitor>::visit_roots()
|
|||
visit_data_roots();
|
||||
visit_bignum_roots();
|
||||
visit_callback_roots();
|
||||
visit_literal_table_roots();
|
||||
|
||||
for(cell i = 0; i < special_object_count; 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)
|
||||
{
|
||||
visit_handle(&compiled->owner);
|
||||
visit_handle(&compiled->literals);
|
||||
visit_handle(&compiled->parameters);
|
||||
visit_handle(&compiled->relocation);
|
||||
}
|
||||
|
||||
template<typename Visitor>
|
||||
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);
|
||||
compiled->each_instruction_operand(visitor);
|
||||
|
|
|
@ -288,7 +288,6 @@ struct factor_vm
|
|||
void collect_mark_impl(bool trace_contexts_p);
|
||||
void collect_sweep_impl();
|
||||
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_code_impl(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 fixup_labels(array *labels, code_block *compiled);
|
||||
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
|
||||
inline void check_code_pointer(cell ptr)
|
||||
|
|
Loading…
Reference in New Issue