diff --git a/basis/bootstrap/image/image.factor b/basis/bootstrap/image/image.factor index eb08809ec1..697c158a6d 100644 --- a/basis/bootstrap/image/image.factor +++ b/basis/bootstrap/image/image.factor @@ -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 diff --git a/basis/compiler/codegen/codegen.factor b/basis/compiler/codegen/codegen.factor index 21a58586bb..dde0d6ef9f 100644 --- a/basis/compiler/codegen/codegen.factor +++ b/basis/compiler/codegen/codegen.factor @@ -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 ; diff --git a/basis/compiler/codegen/fixup/fixup.factor b/basis/compiler/codegen/fixup/fixup.factor index 03da5e904c..af2b1ef1a3 100644 --- a/basis/compiler/codegen/fixup/fixup.factor +++ b/basis/compiler/codegen/fixup/fixup.factor @@ -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 diff --git a/basis/cpu/ppc/bootstrap.factor b/basis/cpu/ppc/bootstrap.factor index 7e7de6d4bc..995bdab566 100644 --- a/basis/cpu/ppc/bootstrap.factor +++ b/basis/cpu/ppc/bootstrap.factor @@ -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 diff --git a/basis/cpu/x86/bootstrap.factor b/basis/cpu/x86/bootstrap.factor index c993a1fdec..ab02ce7e74 100644 --- a/basis/cpu/x86/bootstrap.factor +++ b/basis/cpu/x86/bootstrap.factor @@ -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 diff --git a/vm/callbacks.cpp b/vm/callbacks.cpp index e0ebbd1402..7ab44c2dc7 100644 --- a/vm/callbacks.cpp +++ b/vm/callbacks.cpp @@ -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(),size); diff --git a/vm/code_block_visitor.hpp b/vm/code_block_visitor.hpp index 17ade71d2d..8819dc8134 100644 --- a/vm/code_block_visitor.hpp +++ b/vm/code_block_visitor.hpp @@ -23,6 +23,7 @@ template 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 @@ -102,7 +103,7 @@ struct embedded_code_pointers_visitor { template void code_block_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(this->visitor); compiled->each_instruction_operand(visitor); @@ -116,4 +117,22 @@ void code_block_visitor::visit_context_code_blocks() parent->iterate_active_frames(call_frame_visitor); } +template +void code_block_visitor::visit_uninitialized_code_blocks() +{ + std::map *uninitialized_blocks = &parent->code->uninitialized_blocks; + std::map::const_iterator iter = uninitialized_blocks->begin(); + std::map::const_iterator end = uninitialized_blocks->end(); + + std::map 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; +} + } diff --git a/vm/code_blocks.cpp b/vm/code_blocks.cpp index 0aa8898e89..d50cbf5160 100755 --- a/vm/code_blocks.cpp +++ b/vm/code_blocks.cpp @@ -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(compiled->literals) : NULL); + array *parameters = (to_boolean(compiled->parameters) ? untag(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(literals),literal_index++); + } void operator()(instruction_operand op) { - code_block *compiled = op.parent_code_block(); - array *literals = (to_boolean(compiled->literals) ? untag(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::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 code(code_,this); data_root labels(labels_,this); data_root owner(owner_,this); data_root relocation(relocation_,this); + data_root parameters(parameters_,this); data_root 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; } diff --git a/vm/code_blocks.hpp b/vm/code_blocks.hpp index 199b0afff0..8aa8b5693f 100644 --- a/vm/code_blocks.hpp +++ b/vm/code_blocks.hpp @@ -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 diff --git a/vm/code_heap.cpp b/vm/code_heap.cpp index 5086e3359c..e87ba5fbbf 100755 --- a/vm/code_heap.cpp +++ b/vm/code_heap.cpp @@ -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().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; diff --git a/vm/code_heap.hpp b/vm/code_heap.hpp index 94f315ee61..69453677cf 100755 --- a/vm/code_heap.hpp +++ b/vm/code_heap.hpp @@ -8,8 +8,10 @@ struct code_heap { /* Memory allocator */ free_list_allocator *allocator; - /* Set of blocks which need to be initialized by initialize_code_block(). */ - std::set 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 uninitialized_blocks; /* Code blocks which may reference objects in the nursery */ std::set 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(); diff --git a/vm/compaction.cpp b/vm/compaction.cpp index ecc3eb8bba..3b6beb3de9 100644 --- a/vm/compaction.cpp +++ b/vm/compaction.cpp @@ -2,18 +2,6 @@ namespace factor { -void factor_vm::update_fixup_set_for_compaction(mark_bits *forwarding_map) -{ - std::set::const_iterator iter = code->needs_fixup.begin(); - std::set::const_iterator end = code->needs_fixup.end(); - - std::set new_needs_fixup; - for(; iter != end; iter++) - new_needs_fixup.insert(forwarding_map->forward_block(*iter)); - - code->needs_fixup = new_needs_fixup; -} - template struct forwarder { mark_bits *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 > slot_forwarder(this,forwarder(data_forwarding_map)); code_block_visitor > code_forwarder(this,forwarder(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_forwarding_map = &code->allocator->state; code_forwarding_map->compute_forwarding(); - update_fixup_set_for_compaction(code_forwarding_map); - slot_visitor slot_forwarder(this,dummy_slot_forwarder()); code_block_visitor > code_forwarder(this,forwarder(code_forwarding_map)); + code_forwarder.visit_uninitialized_code_blocks(); + if(trace_contexts_p) code_forwarder.visit_context_code_blocks(); diff --git a/vm/debug.cpp b/vm/debug.cpp index 2f191a0bf8..c02569df25 100755 --- a/vm/debug.cpp +++ b/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() diff --git a/vm/dispatch.cpp b/vm/dispatch.cpp index 3eba483fe6..5b6e90437b 100755 --- a/vm/dispatch.cpp +++ b/vm/dispatch.cpp @@ -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]); diff --git a/vm/full_collector.cpp b/vm/full_collector.cpp index 13546460d1..14c7f09332 100644 --- a/vm/full_collector.cpp +++ b/vm/full_collector.cpp @@ -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()) diff --git a/vm/full_collector.hpp b/vm/full_collector.hpp index a126ad4d96..ba859e28c9 100644 --- a/vm/full_collector.hpp +++ b/vm/full_collector.hpp @@ -49,6 +49,7 @@ struct full_collector : collector { 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); }; diff --git a/vm/image.cpp b/vm/image.cpp index 5ffc09eb45..7ec3d615ce 100755 --- a/vm/image.cpp +++ b/vm/image.cpp @@ -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; diff --git a/vm/inline_cache.cpp b/vm/inline_cache.cpp index 1383a0b453..76b6c17225 100755 --- a/vm/inline_cache.cpp +++ b/vm/inline_cache.cpp @@ -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 diff --git a/vm/instruction_operands.hpp b/vm/instruction_operands.hpp index 788a64ac60..a7d6e4813e 100644 --- a/vm/instruction_operands.hpp +++ b/vm/instruction_operands.hpp @@ -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: diff --git a/vm/jit.cpp b/vm/jit.cpp index 1bdbbc6171..f80607801a 100644 --- a/vm/jit.cpp +++ b/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 code_template(code_template_,parent); data_root argument(argument_,parent); literal(argument.value()); emit(code_template.value()); } +void jit::emit_with_parameter(cell code_template_, cell argument_) { + data_root code_template(code_template_,parent); + data_root 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()); } diff --git a/vm/jit.hpp b/vm/jit.hpp index b5a2457d57..27800b3081 100644 --- a/vm/jit.hpp +++ b/vm/jit.hpp @@ -6,6 +6,7 @@ struct jit { data_root 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_,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_,parent); - data_root code_pair(word->subprimitive,parent); - literals.append(untag(array_nth(code_pair.untagged(),0))); - emit(array_nth(code_pair.untagged(),1)); + data_root code_triple(word->subprimitive,parent); + parameters.append(untag(array_nth(code_triple.untagged(),0))); + literals.append(untag(array_nth(code_triple.untagged(),1))); + emit(array_nth(code_triple.untagged(),2)); } void emit_class_lookup(fixnum index, cell type); diff --git a/vm/profiler.cpp b/vm/profiler.cpp index 19348be4ef..d4f2d757e0 100755 --- a/vm/profiler.cpp +++ b/vm/profiler.cpp @@ -14,7 +14,7 @@ code_block *factor_vm::compile_profiling_stub(cell word_) data_root 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(); } diff --git a/vm/quotations.cpp b/vm/quotations.cpp index 449c3d98f5..fa179b5dd8 100755 --- a/vm/quotations.cpp +++ b/vm/quotations.cpp @@ -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++; diff --git a/vm/slot_visitor.hpp b/vm/slot_visitor.hpp index dab9e22a1f..a7684d1066 100644 --- a/vm/slot_visitor.hpp +++ b/vm/slot_visitor.hpp @@ -32,6 +32,7 @@ template 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::visit_callback_roots() parent->callbacks->each_callback(callback_visitor); } +template +void slot_visitor::visit_literal_table_roots() +{ + std::map *uninitialized_blocks = &parent->code->uninitialized_blocks; + std::map::const_iterator iter = uninitialized_blocks->begin(); + std::map::const_iterator end = uninitialized_blocks->end(); + + std::map 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 void slot_visitor::visit_roots() { @@ -141,6 +160,7 @@ void slot_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 void slot_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 void slot_visitor::visit_embedded_literals(code_block *compiled) { - if(!parent->code->needs_fixup_p(compiled)) + if(!parent->code->uninitialized_p(compiled)) { literal_references_visitor visitor(this); compiled->each_instruction_operand(visitor); diff --git a/vm/vm.hpp b/vm/vm.hpp index 9ddb60e823..e863597077 100755 --- a/vm/vm.hpp +++ b/vm/vm.hpp @@ -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 *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)