From 05f7419f2f39c1e90ffbc4e5e816900b54f5dbe5 Mon Sep 17 00:00:00 2001 From: Slava Pestov Date: Wed, 14 Sep 2011 00:44:35 -0700 Subject: [PATCH] Rework non-optimizing compiler backend to use compiler.codegen.relocation --- basis/bootstrap/image/image.factor | 82 +++++++------------ .../codegen/relocation/relocation.factor | 20 ++++- basis/cpu/x86/32/bootstrap.factor | 25 +++--- basis/cpu/x86/32/windows/bootstrap.factor | 7 +- basis/cpu/x86/64/bootstrap.factor | 21 ++--- basis/cpu/x86/bootstrap.factor | 47 ++++++----- vm/callbacks.cpp | 17 +--- vm/jit.cpp | 22 ++--- vm/jit.hpp | 2 +- 9 files changed, 113 insertions(+), 130 deletions(-) diff --git a/basis/bootstrap/image/image.factor b/basis/bootstrap/image/image.factor index ff41e39338..650bbd8103 100755 --- a/basis/bootstrap/image/image.factor +++ b/basis/bootstrap/image/image.factor @@ -1,17 +1,17 @@ -! Copyright (C) 2004, 2010 Slava Pestov. +! Copyright (C) 2004, 2011 Slava Pestov. ! See http://factorcode.org/license.txt for BSD license. USING: alien alien.strings arrays byte-arrays generic hashtables hashtables.private io io.binary io.files io.encodings.binary io.pathnames kernel kernel.private math namespaces make parser -prettyprint sequences sequences.generalizations strings sbufs -vectors words quotations assocs system layouts splitting -grouping growable classes classes.private classes.builtin -classes.tuple classes.tuple.private vocabs vocabs.loader -source-files definitions debugger quotations.private combinators +prettyprint sequences combinators.smart strings sbufs vectors +words quotations assocs system layouts splitting grouping +growable classes classes.private classes.builtin classes.tuple +classes.tuple.private vocabs vocabs.loader source-files +definitions debugger quotations.private combinators combinators.short-circuit math.order math.private accessors slots.private generic.single.private compiler.units -compiler.constants fry locals bootstrap.image.syntax -generalizations parser.notes ; +compiler.constants compiler.codegen.relocation fry locals +bootstrap.image.syntax parser.notes ; IN: bootstrap.image : arch ( os cpu -- arch ) @@ -32,7 +32,6 @@ IN: bootstrap.image : images ( -- seq ) { "windows-x86.32" "unix-x86.32" - "linux-ppc.32" "linux-ppc.64" "windows-x86.64" "unix-x86.64" } ; @@ -105,65 +104,40 @@ CONSTANT: -1-offset 9 SYMBOL: sub-primitives -SYMBOL: jit-relocations - -SYMBOL: jit-offset - -: compute-offset ( -- offset ) - building get length jit-offset get + ; - -: jit-rel ( rc rt -- ) - 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 ; - -: jit-vm ( offset rc -- ) - [ jit-parameter ] dip rt-vm jit-rel ; - -: jit-dlsym ( name rc -- ) - rt-dlsym jit-rel string>symbol jit-parameter f jit-parameter ; - -: jit-dlsym-toc ( name rc -- ) - rt-dlsym-toc jit-rel string>symbol jit-parameter f jit-parameter ; - :: jit-conditional ( test-quot false-quot -- ) [ 0 test-quot call ] B{ } make length :> len - building get length jit-offset get + len + - [ jit-offset set false-quot call ] B{ } make + building get length extra-offset get + len + + [ extra-offset set false-quot call ] B{ } make [ length test-quot call ] [ % ] bi ; inline -: make-jit ( quot -- jit-parameters jit-literals jit-code ) +: make-jit ( quot -- parameters literals code ) + #! code is a { relocation insns } pair [ - 0 jit-offset set - V{ } clone jit-parameters set - V{ } clone jit-literals set - V{ } clone jit-relocations set + 0 extra-offset set + init-relocation call( -- ) - jit-parameters get >array - jit-literals get >array - jit-relocations get >array - ] B{ } make prefix ; + parameter-table get >array + literal-table get >array + relocation-table get >byte-array + ] B{ } make 2array ; + +: make-jit-no-params ( quot -- code ) + make-jit 2nip ; : jit-define ( quot name -- ) - [ make-jit 2nip ] dip set ; + [ make-jit-no-params ] dip set ; : define-sub-primitive ( quot word -- ) [ make-jit 3array ] dip sub-primitives get set-at ; : define-combinator-primitive ( quot non-tail-quot tail-quot word -- ) [ - [ make-jit ] - [ make-jit 2nip ] - [ make-jit 2nip ] - tri* 5 narray + [ + [ make-jit ] + [ make-jit-no-params ] + [ make-jit-no-params ] + tri* + ] output>array ] dip sub-primitives get set-at ; diff --git a/basis/compiler/codegen/relocation/relocation.factor b/basis/compiler/codegen/relocation/relocation.factor index 2baaaa57f6..e5132a7509 100644 --- a/basis/compiler/codegen/relocation/relocation.factor +++ b/basis/compiler/codegen/relocation/relocation.factor @@ -11,7 +11,10 @@ IN: compiler.codegen.relocation ! Code is compiled into the 'make' vector. -: compiled-offset ( -- n ) building get length ; +SYMBOL: extra-offset ! Only used by non-optimizing compiler + +: compiled-offset ( -- n ) + building get length extra-offset get + ; : alignment ( align -- n ) [ compiled-offset dup ] dip align swap - ; @@ -36,6 +39,9 @@ SYMBOL: literal-table SYMBOL: relocation-table : push-uint ( value vector -- ) + ! If we ever revive PowerPC support again, this needs to be + ! changed to reverse the byte order when bootstrapping from + ! x86 to PowerPC or vice versa [ length ] [ B{ 0 0 0 0 } swap push-all ] [ underlying>> ] tri swap set-alien-unsigned-4 ; @@ -69,6 +75,9 @@ MEMO: cached-string>symbol ( symbol -- obj ) string>symbol ; : rel-literal ( literal class -- ) [ add-literal ] dip rt-literal add-relocation ; +: rel-untagged ( literal class -- ) + [ add-literal ] dip rt-untagged add-relocation ; + : rel-this ( class -- ) rt-this add-relocation ; @@ -84,7 +93,14 @@ MEMO: cached-string>symbol ( symbol -- obj ) string>symbol ; : rel-decks-offset ( class -- ) rt-decks-offset add-relocation ; +: rel-megamorphic-cache-hits ( class -- ) + rt-megamorphic-cache-hits add-relocation ; + +: rel-exception-handler ( class -- ) + rt-exception-handler add-relocation ; + : init-relocation ( -- ) V{ } clone parameter-table set V{ } clone literal-table set - BV{ } clone relocation-table set ; + BV{ } clone relocation-table set + 0 extra-offset set ; diff --git a/basis/cpu/x86/32/bootstrap.factor b/basis/cpu/x86/32/bootstrap.factor index 95481712ca..4474e402fe 100755 --- a/basis/cpu/x86/32/bootstrap.factor +++ b/basis/cpu/x86/32/bootstrap.factor @@ -1,9 +1,10 @@ -! Copyright (C) 2007, 2010 Slava Pestov. +! Copyright (C) 2007, 2011 Slava Pestov. ! See http://factorcode.org/license.txt for BSD license. USING: bootstrap.image.private kernel kernel.private namespaces system cpu.x86.assembler cpu.x86.assembler.operands layouts -vocabs parser compiler.constants sequences math math.private -generic.single.private threads.private ; +vocabs parser compiler.constants compiler.codegen.relocation +sequences math math.private generic.single.private +threads.private ; IN: bootstrap.x86 4 \ cell set @@ -30,24 +31,24 @@ IN: bootstrap.x86 : rex-length ( -- n ) 0 ; : jit-call ( name -- ) - 0 CALL rc-relative jit-dlsym ; + 0 CALL f rc-relative rel-dlsym ; [ ! save stack frame size stack-frame-size PUSH ! push entry point - 0 PUSH rc-absolute-cell rt-this jit-rel + 0 PUSH rc-absolute-cell rel-this ! alignment ESP stack-frame-size 3 bootstrap-cells - SUB ] jit-prolog jit-define [ - pic-tail-reg 0 MOV rc-absolute-cell rt-here jit-rel - 0 JMP rc-relative rt-entry-point-pic-tail jit-rel + pic-tail-reg 0 MOV 0 rc-absolute-cell rel-here + 0 JMP f rc-relative rel-word-pic-tail ] jit-word-jump jit-define : jit-load-vm ( -- ) - vm-reg 0 MOV 0 rc-absolute-cell jit-vm ; + vm-reg 0 MOV 0 rc-absolute-cell rel-vm ; : jit-load-context ( -- ) ! VM pointer must be in vm-reg already @@ -65,13 +66,13 @@ IN: bootstrap.x86 rs-reg ctx-reg context-retainstack-offset [+] MOV ; [ - ! ctx-reg is preserved across the call because it is non-volatile - ! in the C ABI + ! ctx-reg is preserved across the call because it is + ! non-volatile in the C ABI jit-load-vm jit-save-context ! call the primitive ESP [] vm-reg MOV - 0 CALL rc-relative rt-dlsym jit-rel + 0 CALL f f rc-relative rel-dlsym jit-restore-context ] jit-primitive jit-define @@ -177,7 +178,7 @@ IN: bootstrap.x86 \ lazy-jit-compile define-combinator-primitive [ - temp1 HEX: ffffffff CMP rc-absolute-cell rt-literal jit-rel + temp1 HEX: ffffffff CMP f rc-absolute-cell rel-literal ] pic-check-tuple jit-define ! Inline cache miss entry points diff --git a/basis/cpu/x86/32/windows/bootstrap.factor b/basis/cpu/x86/32/windows/bootstrap.factor index a081b48f62..801818e59b 100644 --- a/basis/cpu/x86/32/windows/bootstrap.factor +++ b/basis/cpu/x86/32/windows/bootstrap.factor @@ -1,8 +1,9 @@ ! Copyright (C) 2010 Slava Pestov. ! See http://factorcode.org/license.txt for BSD license. USING: bootstrap.image.private compiler.constants -cpu.x86.assembler cpu.x86.assembler.operands kernel layouts -locals parser sequences ; +compiler.codegen.relocation cpu.x86.assembler +cpu.x86.assembler.operands kernel layouts locals parser +sequences ; IN: bootstrap.x86 : tib-segment ( -- ) FS ; @@ -16,7 +17,7 @@ IN: bootstrap.x86 ! Align stack ESP 3 bootstrap-cells ADD ! Exception handler address filled in by callback.cpp - tib-temp 0 MOV rc-absolute-cell rt-exception-handler jit-rel + tib-temp 0 MOV rc-absolute-cell rel-exception-handler tib-temp PUSH ! No next handler 0 PUSH diff --git a/basis/cpu/x86/64/bootstrap.factor b/basis/cpu/x86/64/bootstrap.factor index f3de6b900e..7e6e937f9c 100755 --- a/basis/cpu/x86/64/bootstrap.factor +++ b/basis/cpu/x86/64/bootstrap.factor @@ -1,9 +1,10 @@ -! Copyright (C) 2007, 2010 Slava Pestov. +! Copyright (C) 2007, 2011 Slava Pestov. ! See http://factorcode.org/license.txt for BSD license. USING: bootstrap.image.private kernel kernel.private namespaces -system layouts vocabs parser compiler.constants math -math.private cpu.x86.assembler cpu.x86.assembler.operands -sequences generic.single.private threads.private ; +system layouts vocabs parser compiler.constants +compiler.codegen.relocation math math.private cpu.x86.assembler +cpu.x86.assembler.operands sequences generic.single.private +threads.private ; IN: bootstrap.x86 8 \ cell set @@ -29,12 +30,12 @@ IN: bootstrap.x86 : rex-length ( -- n ) 1 ; : jit-call ( name -- ) - RAX 0 MOV rc-absolute-cell jit-dlsym + RAX 0 MOV f rc-absolute-cell rel-dlsym RAX CALL ; [ ! load entry point - RAX 0 MOV rc-absolute-cell rt-this jit-rel + RAX 0 MOV rc-absolute-cell rel-this ! save stack frame size stack-frame-size PUSH ! push entry point @@ -45,7 +46,7 @@ IN: bootstrap.x86 [ pic-tail-reg 5 [RIP+] LEA - 0 JMP rc-relative rt-entry-point-pic-tail jit-rel + 0 JMP f rc-relative rel-word-pic-tail ] jit-word-jump jit-define : jit-load-context ( -- ) @@ -68,7 +69,7 @@ IN: bootstrap.x86 jit-save-context ! call the primitive arg1 vm-reg MOV - RAX 0 MOV rc-absolute-cell rt-dlsym jit-rel + RAX 0 MOV f f rc-absolute-cell rel-dlsym RAX CALL jit-restore-context ] jit-primitive jit-define @@ -104,7 +105,7 @@ IN: bootstrap.x86 ! Load VM pointer into vm-reg, since we're entering from ! C code - vm-reg 0 MOV 0 rc-absolute-cell jit-vm + vm-reg 0 MOV 0 rc-absolute-cell rel-vm ! Load ds and rs registers jit-load-context @@ -166,7 +167,7 @@ IN: bootstrap.x86 \ lazy-jit-compile define-combinator-primitive [ - temp2 HEX: ffffffff MOV rc-absolute-cell rt-literal jit-rel + temp2 HEX: ffffffff MOV f rc-absolute-cell rel-literal temp1 temp2 CMP ] pic-check-tuple jit-define diff --git a/basis/cpu/x86/bootstrap.factor b/basis/cpu/x86/bootstrap.factor index 08f89e1b91..c5e9405b3c 100644 --- a/basis/cpu/x86/bootstrap.factor +++ b/basis/cpu/x86/bootstrap.factor @@ -1,10 +1,10 @@ -! Copyright (C) 2007, 2010 Slava Pestov. +! Copyright (C) 2007, 2011 Slava Pestov. ! See http://factorcode.org/license.txt for BSD license. USING: bootstrap.image.private compiler.constants -compiler.units cpu.x86.assembler cpu.x86.assembler.operands -kernel kernel.private layouts locals.backend make math -math.private namespaces sequences slots.private strings.private -vocabs ; +compiler.codegen.relocation compiler.units cpu.x86.assembler +cpu.x86.assembler.operands kernel kernel.private layouts +locals.backend make math math.private namespaces sequences +slots.private strings.private vocabs ; IN: bootstrap.x86 big-endian off @@ -25,7 +25,7 @@ big-endian off jit-save-tib ! Load VM into vm-reg - vm-reg 0 MOV rc-absolute-cell rt-vm jit-rel + vm-reg 0 MOV 0 rc-absolute-cell rel-vm ! Save old context nv-reg vm-reg vm-context-offset [+] MOV @@ -47,12 +47,12 @@ big-endian off ds-reg nv-reg context-datastack-offset [+] MOV ! Call into Factor code - link-reg 0 MOV rc-absolute-cell rt-entry-point jit-rel + link-reg 0 MOV f rc-absolute-cell rel-word link-reg CALL ! Load VM into vm-reg; only needed on x86-32, but doesn't ! hurt on x86-64 - vm-reg 0 MOV rc-absolute-cell rt-vm jit-rel + vm-reg 0 MOV 0 rc-absolute-cell rel-vm ! Load C callstack pointer nv-reg vm-reg vm-context-offset [+] MOV @@ -73,12 +73,12 @@ big-endian off ! need a parameter here. ! See the comment for M\ x86.32 stack-cleanup in cpu.x86.32 - HEX: ffff RET rc-absolute-2 rt-untagged jit-rel + HEX: ffff RET f rc-absolute-2 rel-untagged ] callback-stub jit-define [ ! Load word - temp0 0 MOV rc-absolute-cell rt-literal jit-rel + temp0 0 MOV f rc-absolute-cell rel-literal ! Bump profiling counter temp0 profile-count-offset [+] 1 tag-fixnum ADD ! Load word->code @@ -91,7 +91,7 @@ big-endian off [ ! load literal - temp0 0 MOV rc-absolute-cell rt-literal jit-rel + temp0 0 MOV f rc-absolute-cell rel-literal ! increment datastack pointer ds-reg bootstrap-cell ADD ! store literal on datastack @@ -99,7 +99,7 @@ big-endian off ] jit-push jit-define [ - 0 CALL rc-relative rt-entry-point-pic jit-rel + 0 CALL f rc-relative rel-word-pic ] jit-word-call jit-define [ @@ -110,9 +110,9 @@ big-endian off ! compare boolean with f temp0 \ f type-number CMP ! jump to true branch if not equal - 0 JNE rc-relative rt-entry-point jit-rel + 0 JNE f rc-relative rel-word ! jump to false branch if equal - 0 JMP rc-relative rt-entry-point jit-rel + 0 JMP f rc-relative rel-word ] jit-if jit-define : jit->r ( -- ) @@ -165,19 +165,19 @@ big-endian off [ jit->r - 0 CALL rc-relative rt-entry-point jit-rel + 0 CALL f rc-relative rel-word jit-r> ] jit-dip jit-define [ jit-2>r - 0 CALL rc-relative rt-entry-point jit-rel + 0 CALL f rc-relative rel-word jit-2r> ] jit-2dip jit-define [ jit-3>r - 0 CALL rc-relative rt-entry-point jit-rel + 0 CALL f rc-relative rel-word jit-3r> ] jit-3dip jit-define @@ -209,7 +209,7 @@ big-endian off ! Load a value from a stack position [ - temp1 ds-reg HEX: 7f [+] MOV rc-absolute-1 rt-untagged jit-rel + temp1 ds-reg HEX: 7f [+] MOV f rc-absolute-1 rel-untagged ] pic-load jit-define [ temp1 tag-mask get AND ] pic-tag jit-define @@ -224,10 +224,10 @@ big-endian off ] pic-tuple jit-define [ - temp1 HEX: 7f CMP rc-absolute-1 rt-untagged jit-rel + temp1 HEX: 7f CMP f rc-absolute-1 rel-untagged ] pic-check-tag jit-define -[ 0 JE rc-relative rt-entry-point jit-rel ] pic-hit jit-define +[ 0 JE f rc-relative rel-word ] pic-hit jit-define ! ! ! Megamorphic caches @@ -241,7 +241,7 @@ big-endian off [ temp1 temp0 tuple-class-offset [+] MOV ] jit-conditional ! cache = ... - temp0 0 MOV rc-absolute-cell rt-literal jit-rel + temp0 0 MOV f rc-absolute-cell rel-literal ! key = hashcode(class) temp2 temp1 MOV bootstrap-cell 4 = [ temp2 1 SHR ] when @@ -256,7 +256,7 @@ big-endian off [ JNE ] [ ! megamorphic_cache_hits++ - temp1 0 MOV rc-absolute-cell rt-megamorphic-cache-hits jit-rel + temp1 0 MOV rc-absolute-cell rel-megamorphic-cache-hits temp1 [] 1 ADD ! goto get(cache + bootstrap-cell) temp0 temp0 bootstrap-cell [+] MOV @@ -418,8 +418,7 @@ big-endian off ! Comparisons : jit-compare ( insn -- ) ! load t - t jit-literal - temp3 0 MOV rc-absolute-cell rt-literal jit-rel + temp3 0 MOV t rc-absolute-cell rel-literal ! load f temp1 \ f type-number MOV ! load first value diff --git a/vm/callbacks.cpp b/vm/callbacks.cpp index e54957434b..fafcbef54f 100755 --- a/vm/callbacks.cpp +++ b/vm/callbacks.cpp @@ -40,19 +40,10 @@ bool callback_heap::return_takes_param_p() instruction_operand callback_heap::callback_operand(code_block *stub, cell index) { tagged code_template(parent->special_objects[CALLBACK_STUB]); + tagged relocation_template(array_nth(code_template.untagged(),0)); - cell rel_class = untag_fixnum(array_nth(code_template.untagged(),3 * index + 1)); - cell rel_type = untag_fixnum(array_nth(code_template.untagged(),3 * index + 2)); - cell offset = untag_fixnum(array_nth(code_template.untagged(),3 * index + 3)); - - relocation_entry rel( - (relocation_type)rel_type, - (relocation_class)rel_class, - offset); - - instruction_operand op(rel,stub,0); - - return op; + relocation_entry entry(relocation_template->data()[index]); + return instruction_operand(entry,stub,0); } void callback_heap::store_callback_operand(code_block *stub, cell index) @@ -74,7 +65,7 @@ void callback_heap::update(code_block *stub) code_block *callback_heap::add(cell owner, cell return_rewind) { tagged code_template(parent->special_objects[CALLBACK_STUB]); - tagged insns(array_nth(code_template.untagged(),0)); + tagged insns(array_nth(code_template.untagged(),1)); cell size = array_capacity(insns.untagged()); cell bump = align(size + sizeof(code_block),data_alignment); diff --git a/vm/jit.cpp b/vm/jit.cpp index b98c6f54ff..615601ecf6 100644 --- a/vm/jit.cpp +++ b/vm/jit.cpp @@ -23,17 +23,17 @@ jit::jit(code_block_type type_, cell owner_, factor_vm *vm) parent(vm) {} -void jit::emit_relocation(cell code_template_) +void jit::emit_relocation(cell relocation_template_) { - data_root code_template(code_template_,parent); - cell capacity = array_capacity(code_template.untagged()); - for(cell i = 1; i < capacity; i += 3) + data_root relocation_template(relocation_template_,parent); + cell capacity = array_capacity(relocation_template.untagged()) + / sizeof(relocation_entry); + relocation_entry *relocations = relocation_template->data(); + for(cell i = 0; i < capacity; i++) { - relocation_class rel_class = (relocation_class)untag_fixnum(array_nth(code_template.untagged(),i)); - relocation_type rel_type = (relocation_type)untag_fixnum(array_nth(code_template.untagged(),i + 1)); - cell offset = array_nth(code_template.untagged(),i + 2); - - relocation_entry new_entry(rel_type,rel_class,code.count + untag_fixnum(offset)); + relocation_entry entry = relocations[i]; + relocation_entry new_entry(entry.rel_type(), entry.rel_class(), + entry.rel_offset() + code.count); relocation.append_bytes(&new_entry,sizeof(relocation_entry)); } } @@ -43,9 +43,9 @@ void jit::emit(cell code_template_) { data_root code_template(code_template_,parent); - emit_relocation(code_template.value()); + emit_relocation(array_nth(code_template.untagged(),0)); - data_root insns(array_nth(code_template.untagged(),0),parent); + data_root insns(array_nth(code_template.untagged(),1),parent); if(computing_offset_p) { diff --git a/vm/jit.hpp b/vm/jit.hpp index 963115d6ab..4649579a47 100644 --- a/vm/jit.hpp +++ b/vm/jit.hpp @@ -16,7 +16,7 @@ struct jit { explicit jit(code_block_type type, cell owner, factor_vm *parent); void compute_position(cell offset); - void emit_relocation(cell code_template); + void emit_relocation(cell relocation_template); void emit(cell code_template); void parameter(cell parameter) { parameters.add(parameter); }