]> gitweb.factorcode.org Git - factor.git/commitdiff
vm: big overhaul of non-optimizing compiler
authorSlava Pestov <slava@slava-pestovs-macbook-pro.local>
Tue, 15 Dec 2009 12:20:09 +0000 (07:20 -0500)
committerSlava Pestov <slava@slava-pestovs-macbook-pro.local>
Tue, 15 Dec 2009 12:20:09 +0000 (07:20 -0500)
- change some primitives into sub-primitives: fixnum+ fixnum- fixnum* inline-cache-miss inline-cache-miss-tail
- rename some relocation types for clarity
- some other minor re-organizations and cleanups

38 files changed:
basis/bootstrap/image/image.factor
basis/compiler/cfg/build-stack-frame/build-stack-frame.factor
basis/compiler/codegen/codegen.factor
basis/compiler/codegen/fixup/fixup.factor
basis/compiler/constants/constants.factor
basis/cpu/ppc/bootstrap.factor
basis/cpu/x86/32/bootstrap.factor
basis/cpu/x86/64/bootstrap.factor
basis/cpu/x86/64/unix/bootstrap.factor
basis/cpu/x86/64/winnt/bootstrap.factor
basis/cpu/x86/bootstrap.factor
core/bootstrap/primitives.factor
core/compiler/units/units.factor
vm/callstack.cpp
vm/callstack.hpp
vm/code_blocks.cpp
vm/compaction.cpp
vm/cpu-ppc.S
vm/cpu-x86.32.S
vm/cpu-x86.64.S
vm/cpu-x86.S
vm/cpu-x86.hpp
vm/data_heap.cpp
vm/debug.cpp
vm/dispatch.cpp
vm/full_collector.cpp
vm/image.cpp
vm/inline_cache.cpp
vm/instruction_operands.hpp
vm/jit.cpp
vm/jit.hpp
vm/objects.hpp
vm/primitives.cpp
vm/quotations.cpp
vm/quotations.hpp
vm/slot_visitor.hpp
vm/vm.hpp
vm/words.cpp

index 697c158a6dba100037dc6dc0d3c97371fc18e971..9415f191403c76068cf8067275092c404328eaa8 100644 (file)
@@ -1,6 +1,6 @@
 ! Copyright (C) 2004, 2009 Slava Pestov.
 ! See http://factorcode.org/license.txt for BSD license.
-USING: alien arrays byte-arrays generic hashtables
+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 strings sbufs vectors words quotations
@@ -10,7 +10,7 @@ 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
-bootstrap.image.syntax ;
+locals bootstrap.image.syntax generalizations ;
 IN: bootstrap.image
 
 : arch ( os cpu -- arch )
@@ -107,8 +107,11 @@ SYMBOL: sub-primitives
 
 SYMBOL: jit-relocations
 
+SYMBOL: jit-offset
+
 : compute-offset ( rc -- offset )
-    [ building get length ] dip rc-absolute-cell = bootstrap-cell 4 ? - ;
+    [ building get length jit-offset get + ] dip
+    rc-absolute-cell = bootstrap-cell 4 ? - ;
 
 : jit-rel ( rc rt -- )
     over compute-offset 3array jit-relocations get push-all ;
@@ -123,8 +126,21 @@ SYMBOL: jit-literals
 : jit-literal ( literal -- )
     jit-literals get push ;
 
-: make-jit ( quot -- jit-parameters jit-literals jit-data )
+: jit-vm ( offset rc -- )
+    [ jit-parameter ] dip rt-vm jit-rel ;
+
+: jit-dlsym ( name library rc -- )
+    rt-dlsym jit-rel [ string>symbol jit-parameter ] bi@ ;
+
+:: 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
+    [ length test-quot call ] [ % ] bi ; inline
+
+: make-jit ( quot -- jit-parameters jit-literals jit-code )
     [
+        0 jit-offset set
         V{ } clone jit-parameters set
         V{ } clone jit-literals set
         V{ } clone jit-relocations set
@@ -140,6 +156,15 @@ SYMBOL: jit-literals
 : define-sub-primitive ( quot word -- )
     [ make-jit 3array ] dip sub-primitives get set-at ;
 
+: define-sub-primitive* ( quot non-tail-quot tail-quot word -- )
+    [
+        [ make-jit ]
+        [ make-jit 2nip ]
+        [ make-jit 2nip ]
+        tri* 5 narray
+    ] dip
+    sub-primitives get set-at ;
+
 ! The image being constructed; a vector of word-size integers
 SYMBOL: image
 
@@ -163,35 +188,32 @@ USERENV: jit-primitive-word 24
 USERENV: jit-primitive 25
 USERENV: jit-word-jump 26
 USERENV: jit-word-call 27
-USERENV: jit-word-special 28
-USERENV: jit-if-word 29
-USERENV: jit-if 30
-USERENV: jit-epilog 31
-USERENV: jit-return 32
-USERENV: jit-profiling 33
-USERENV: jit-push-immediate 34
-USERENV: jit-dip-word 35
-USERENV: jit-dip 36
-USERENV: jit-2dip-word 37
-USERENV: jit-2dip 38
-USERENV: jit-3dip-word 39
-USERENV: jit-3dip 40
-USERENV: jit-execute-word 41
-USERENV: jit-execute-jump 42
-USERENV: jit-execute-call 43
-USERENV: jit-declare-word 44
-
-USERENV: callback-stub 45
+USERENV: jit-if-word 28
+USERENV: jit-if 29
+USERENV: jit-epilog 30
+USERENV: jit-return 31
+USERENV: jit-profiling 32
+USERENV: jit-push-immediate 33
+USERENV: jit-dip-word 34
+USERENV: jit-dip 35
+USERENV: jit-2dip-word 36
+USERENV: jit-2dip 37
+USERENV: jit-3dip-word 38
+USERENV: jit-3dip 39
+USERENV: jit-execute 40
+USERENV: jit-declare-word 41
+
+USERENV: callback-stub 48
 
 ! PIC stubs
-USERENV: pic-load 47
-USERENV: pic-tag 48
-USERENV: pic-tuple 49
-USERENV: pic-check-tag 50
-USERENV: pic-check-tuple 51
-USERENV: pic-hit 52
-USERENV: pic-miss-word 53
-USERENV: pic-miss-tail-word 54
+USERENV: pic-load 49
+USERENV: pic-tag 50
+USERENV: pic-tuple 51
+USERENV: pic-check-tag 52
+USERENV: pic-check-tuple 53
+USERENV: pic-hit 54
+USERENV: pic-miss-word 55
+USERENV: pic-miss-tail-word 56
 
 ! Megamorphic dispatch
 USERENV: mega-lookup 57
@@ -513,7 +535,6 @@ M: quotation '
     \ dip jit-dip-word set
     \ 2dip jit-2dip-word set
     \ 3dip jit-3dip-word set
-    \ (execute) jit-execute-word set
     \ inline-cache-miss \ pic-miss-word set
     \ inline-cache-miss-tail \ pic-miss-tail-word set
     \ mega-cache-lookup \ mega-lookup-word set
index 1f01bc438b8c07a6e76acd3e318a0a322cc6359a..6f45a51f552a5ca93cb36cb8ebdc64a01353789d 100644 (file)
@@ -22,8 +22,7 @@ UNION: stack-frame-insn
 M: stack-frame-insn compute-stack-frame*
     stack-frame>> request-stack-frame ;
 
-M: ##call compute-stack-frame*
-    word>> sub-primitive>> [ frame-required? on ] unless ;
+M: ##call compute-stack-frame* drop frame-required? on ;
 
 M: ##gc compute-stack-frame*
     frame-required? on
index 8d976193e1c0520f4f2982d56f6f95f1f0a141ce..b1b39c0b07ee1c5f8b18edd9e94fef6d36fd5bd9 100644 (file)
@@ -61,9 +61,7 @@ SYMBOL: labels
 ! Special cases
 M: ##no-tco generate-insn drop ;
 
-M: ##call generate-insn
-    word>> dup sub-primitive>>
-    [ third first % ] [ [ add-call ] [ %call ] bi ] ?if ;
+M: ##call generate-insn word>> [ add-call ] [ %call ] bi ;
 
 M: ##jump generate-insn word>> [ add-call ] [ %jump ] bi ;
 
index edac283ee06802ba3a07050b71f7b1766153dfa9..aafa6edd94d99657da955d76ef6f6c5b0792028f 100644 (file)
@@ -74,7 +74,7 @@ SYMBOL: relocation-table
     [ def>> first add-parameter ] dip rt-primitive rel-fixup ;
 
 : rel-immediate ( literal class -- )
-    [ add-literal ] dip rt-immediate rel-fixup ;
+    [ add-literal ] dip rt-literal rel-fixup ;
 
 : rel-this ( class -- )
     rt-this rel-fixup ;
index 19cdb6eebdb033b76fdf1686f12abb239f844e1d..cfa893546db28bd90374150ba537086e54e4bec4 100644 (file)
@@ -47,8 +47,8 @@ CONSTANT: rt-xt-pic 4
 CONSTANT: rt-xt-pic-tail 5
 CONSTANT: rt-here 6
 CONSTANT: rt-this 7
-CONSTANT: rt-immediate 8
-CONSTANT: rt-stack-chain 9
+CONSTANT: rt-literal 8
+CONSTANT: rt-context 9
 CONSTANT: rt-untagged 10
 CONSTANT: rt-megamorphic-cache-hits 11
 CONSTANT: rt-vm 12
index 995bdab566e72be72c7867a7b76dd9d5e501c8a9..753fff13c43209bae6fbfc138be9bc9187728613 100644 (file)
@@ -1,9 +1,9 @@
-! Copyright (C) 2007, 2008 Slava Pestov.\r
+! Copyright (C) 2007, 2009 Slava Pestov.\r
 ! See http://factorcode.org/license.txt for BSD license.\r
 USING: bootstrap.image.private kernel kernel.private namespaces\r
 system cpu.ppc.assembler compiler.codegen.fixup compiler.units\r
-compiler.constants math math.private layouts words\r
-vocabs slots.private locals.backend ;\r
+compiler.constants math math.private layouts words vocabs\r
+slots.private locals locals.backend generic.single.private fry ;\r
 FROM: cpu.ppc.assembler => B ;\r
 IN: bootstrap.ppc\r
 \r
@@ -21,8 +21,16 @@ CONSTANT: rs-reg 14
 : next-save ( -- n ) stack-frame bootstrap-cell - ;\r
 : xt-save ( -- n ) stack-frame 2 bootstrap-cells - ;\r
 \r
+: jit-conditional* ( test-quot true-quot -- )\r
+    [ '[ bootstrap-cell /i 1 + @ ] ] dip jit-conditional ; inline\r
+\r
+: jit-save-context ( -- )\r
+    0 3 LOAD32 rc-absolute-ppc-2/2 rt-context jit-rel\r
+    4 3 0 LWZ\r
+    1 4 0 STW ;\r
+\r
 [\r
-    0 3 LOAD32 rc-absolute-ppc-2/2 rt-immediate jit-rel\r
+    0 3 LOAD32 rc-absolute-ppc-2/2 rt-literal jit-rel\r
     11 3 profile-count-offset LWZ\r
     11 11 1 tag-fixnum ADDI\r
     11 3 profile-count-offset STW\r
@@ -43,14 +51,12 @@ CONSTANT: rs-reg 14
 ] jit-prolog jit-define\r
 \r
 [\r
-    0 3 LOAD32 rc-absolute-ppc-2/2 rt-immediate jit-rel\r
+    0 3 LOAD32 rc-absolute-ppc-2/2 rt-literal jit-rel\r
     3 ds-reg 4 STWU\r
 ] jit-push-immediate jit-define\r
 \r
 [\r
-    0 3 LOAD32 rc-absolute-ppc-2/2 rt-stack-chain jit-rel\r
-    4 3 0 LWZ\r
-    1 4 0 STW\r
+    jit-save-context\r
     4 0 swap LOAD32 rc-absolute-ppc-2/2 rt-vm jit-rel\r
     0 5 LOAD32 rc-absolute-ppc-2/2 rt-primitive jit-rel\r
     5 MTCTR\r
@@ -64,14 +70,11 @@ CONSTANT: rs-reg 14
     0 B rc-relative-ppc-3 rt-xt-pic-tail jit-rel\r
 ] jit-word-jump jit-define\r
 \r
-[ 0 B rc-relative-ppc-3 rt-xt jit-rel ] jit-word-special jit-define\r
-\r
 [\r
     3 ds-reg 0 LWZ\r
     ds-reg dup 4 SUBI\r
     0 3 \ f type-number CMPI\r
-    2 BEQ\r
-    0 B rc-relative-ppc-3 rt-xt jit-rel\r
+    [ BEQ ] [ 0 B rc-relative-ppc-3 rt-xt jit-rel ] jit-conditional*\r
     0 B rc-relative-ppc-3 rt-xt jit-rel\r
 ] jit-if jit-define\r
 \r
@@ -139,16 +142,6 @@ CONSTANT: rs-reg 14
     jit-3r>\r
 ] jit-3dip jit-define\r
 \r
-: prepare-(execute) ( -- operand )\r
-    3 ds-reg 0 LWZ\r
-    ds-reg dup 4 SUBI\r
-    4 3 word-xt-offset LWZ\r
-    4 ;\r
-\r
-[ prepare-(execute) MTCTR BCTR ] jit-execute-jump jit-define\r
-\r
-[ prepare-(execute) MTLR BLRL ] jit-execute-call jit-define\r
-\r
 [\r
     0 1 lr-save stack-frame + LWZ\r
     1 1 stack-frame ADDI\r
@@ -179,26 +172,29 @@ CONSTANT: rs-reg 14
     3 4 MR\r
     load-tag\r
     0 4 tuple type-number tag-fixnum CMPI\r
-    2 BNE\r
-    4 3 tuple type-number neg bootstrap-cell + LWZ\r
+    [ BNE ]\r
+    [ 4 3 tuple type-number neg bootstrap-cell + LWZ ]\r
+    jit-conditional*\r
 ] pic-tuple jit-define\r
 \r
 [\r
-    0 4 0 CMPI rc-absolute-ppc-2 rt-immediate jit-rel\r
+    0 4 0 CMPI rc-absolute-ppc-2 rt-literal jit-rel\r
 ] pic-check-tag jit-define\r
 \r
 [\r
-    0 5 LOAD32 rc-absolute-ppc-2/2 rt-immediate jit-rel\r
+    0 5 LOAD32 rc-absolute-ppc-2/2 rt-literal jit-rel\r
     4 0 5 CMP\r
 ] pic-check-tuple jit-define\r
 \r
-[ 2 BNE 0 B rc-relative-ppc-3 rt-xt jit-rel ] pic-hit jit-define\r
+[\r
+    [ BNE ] [ 0 B rc-relative-ppc-3 rt-xt jit-rel ] jit-conditional*\r
+] pic-hit jit-define\r
 \r
 ! ! ! Megamorphic caches\r
 \r
 [\r
     ! cache = ...\r
-    0 3 LOAD32 rc-absolute-ppc-2/2 rt-immediate jit-rel\r
+    0 3 LOAD32 rc-absolute-ppc-2/2 rt-literal jit-rel\r
     ! key = hashcode(class)\r
     5 4 1 SRAWI\r
     ! key &= cache.length - 1\r
@@ -210,17 +206,20 @@ CONSTANT: rs-reg 14
     ! if(get(cache) == class)\r
     6 3 0 LWZ\r
     6 0 4 CMP\r
-    10 BNE\r
-    ! megamorphic_cache_hits++\r
-    0 4 LOAD32 rc-absolute-ppc-2/2 rt-megamorphic-cache-hits jit-rel\r
-    5 4 0 LWZ\r
-    5 5 1 ADDI\r
-    5 4 0 STW\r
-    ! ... goto get(cache + bootstrap-cell)\r
-    3 3 4 LWZ\r
-    3 3 word-xt-offset LWZ\r
-    3 MTCTR\r
-    BCTR\r
+    [ BNE ]\r
+    [\r
+        ! megamorphic_cache_hits++\r
+        0 4 LOAD32 rc-absolute-ppc-2/2 rt-megamorphic-cache-hits jit-rel\r
+        5 4 0 LWZ\r
+        5 5 1 ADDI\r
+        5 4 0 STW\r
+        ! ... goto get(cache + bootstrap-cell)\r
+        3 3 4 LWZ\r
+        3 3 word-xt-offset LWZ\r
+        3 MTCTR\r
+        BCTR\r
+    ]\r
+    jit-conditional*\r
     ! fall-through on miss\r
 ] mega-lookup jit-define\r
 \r
@@ -238,9 +237,24 @@ CONSTANT: rs-reg 14
     ds-reg dup 4 SUBI\r
     4 0 swap LOAD32 0 jit-parameter rc-absolute-ppc-2/2 rt-vm jit-rel\r
     5 3 quot-xt-offset LWZ\r
-    5 MTCTR\r
-    BCTR\r
-] \ (call) define-sub-primitive\r
+]\r
+[ 5 MTLR BLRL ]\r
+[ 5 MTCTR BCTR ] \ (call) define-sub-primitive*\r
+\r
+[\r
+    3 ds-reg 0 LWZ\r
+    ds-reg dup 4 SUBI\r
+    4 3 word-xt-offset LWZ\r
+]\r
+[ 4 MTLR BLRL ]\r
+[ 4 MTCTR BCTR ] \ (execute) define-sub-primitive*\r
+\r
+[\r
+    3 ds-reg 0 LWZ\r
+    ds-reg dup 4 SUBI\r
+    4 3 word-xt-offset LWZ\r
+    4 MTCTR BCTR\r
+] jit-execute jit-define\r
 \r
 ! Objects\r
 [\r
@@ -361,7 +375,7 @@ CONSTANT: rs-reg 14
 ! Comparisons\r
 : jit-compare ( insn -- )\r
     t jit-literal\r
-    0 3 LOAD32 rc-absolute-ppc-2/2 rt-immediate jit-rel\r
+    0 3 LOAD32 rc-absolute-ppc-2/2 rt-literal jit-rel\r
     4 ds-reg 0 LWZ\r
     5 ds-reg -4 LWZU\r
     5 0 4 CMP\r
@@ -387,8 +401,7 @@ CONSTANT: rs-reg 14
     3 3 tag-mask get ANDI\r
     \ f type-number 4 LI\r
     0 3 0 CMPI\r
-    2 BNE\r
-    1 tag-fixnum 4 LI\r
+    [ BNE ] [ 1 tag-fixnum 4 LI ] jit-conditional*\r
     4 ds-reg 0 STW\r
 ] \ both-fixnums? define-sub-primitive\r
 \r
@@ -433,8 +446,7 @@ CONSTANT: rs-reg 14
     7 4 6 SRAW\r
     7 7 0 0 31 tag-bits get - RLWINM\r
     0 3 0 CMPI\r
-    2 BGT\r
-    5 7 MR\r
+    [ BGT ] [ 5 7 MR ] jit-conditional*\r
     5 ds-reg 0 STW\r
 ] \ fixnum-shift-fast define-sub-primitive\r
 \r
@@ -482,4 +494,67 @@ CONSTANT: rs-reg 14
     rs-reg 3 rs-reg SUBF\r
 ] \ drop-locals define-sub-primitive\r
 \r
+! Inline cache miss entry points\r
+: jit-load-return-address ( -- ) 6 MFLR ;\r
+\r
+! These are always in tail position with an existing stack\r
+! frame, and the stack. The frame setup takes this into account.\r
+: jit-inline-cache-miss ( -- )\r
+    jit-save-context\r
+    3 6 MR\r
+    4 0 LOAD32 0 rc-absolute-ppc-2/2 jit-vm\r
+    5 0 LOAD32 "inline_cache_miss" f rc-absolute-ppc-2/2 jit-dlsym ;\r
+\r
+[ jit-load-return-address jit-inline-cache-miss ]\r
+[ 5 MTLR BLRL ]\r
+[ 5 MTCTR BCTR ]\r
+\ inline-cache-miss define-sub-primitive*\r
+\r
+[ jit-inline-cache-miss ]\r
+[ 5 MTLR BLRL ]\r
+[ 5 MTCTR BCTR ]\r
+\ inline-cache-miss-tail define-sub-primitive*\r
+\r
+! Overflowing fixnum arithmetic\r
+:: jit-overflow ( insn func -- )\r
+    jit-save-context\r
+    3 ds-reg 0 LWZ\r
+    4 ds-reg -4 LWZ\r
+    ds-reg ds-reg 4 SUBI\r
+    0 0 LI\r
+    0 MTXER\r
+    6 3 4 insn call( d a s -- )\r
+    6 ds-reg 0 STW\r
+    [ BNO ]\r
+    [\r
+       0 5 LOAD32 0 rc-absolute-ppc-2/2 jit-vm\r
+       0 6 LOAD32 func f rc-absolute-ppc-2/2 jit-dlsym\r
+    ]\r
+    jit-conditional ;\r
+\r
+[ [ ADDO. ] "overflow_fixnum_add" jit-overflow ] \ fixnum+ define-sub-primitive\r
+\r
+[ [ SUBFO. ] "overflow_fixnum_subtract" jit-overflow ] \ fixnum- define-sub-primitive\r
+\r
+[\r
+    jit-save-context\r
+    3 ds-reg 0 LWZ\r
+    3 3 tag-bits get SRAWI\r
+    4 ds-reg -4 LWZ\r
+    ds-reg ds-reg 4 SUBI\r
+    0 0 LI\r
+    0 MTXER\r
+    6 3 4 MULLWO.\r
+    6 ds-reg 0 STW\r
+    [ BNO ]\r
+    [\r
+        4 4 tag-bits get SRAWI\r
+        0 5 LOAD32 0 rc-absolute-ppc-2/2 jit-vm\r
+        0 6 LOAD32 "overflow_fixnum_multiply" f rc-absolute-ppc-2/2 jit-dlsym\r
+        6 MTLR\r
+        BLRL\r
+    ]\r
+    jit-conditional\r
+] \ fixnum* define-sub-primitive\r
+\r
 [ "bootstrap.ppc" forget-vocab ] with-compilation-unit\r
index f777040e86fa8599f7b811755016439d1118ee6c..97a3ae2c1f3c5c9567fb9d7743099da3b98af19c 100644 (file)
@@ -2,12 +2,13 @@
 ! See http://factorcode.org/license.txt for BSD license.
 USING: bootstrap.image.private kernel namespaces system
 cpu.x86.assembler cpu.x86.assembler.operands layouts
-vocabs parser compiler.constants sequences ;
+vocabs parser compiler.constants sequences math math.private
+generic.single.private ;
 IN: bootstrap.x86
 
 4 \ cell set
 
-: stack-frame-size ( -- n ) 4 bootstrap-cells ;
+: stack-frame-size ( -- n ) 8 bootstrap-cells ;
 : shift-arg ( -- reg ) ECX ;
 : div-arg ( -- reg ) EAX ;
 : mod-arg ( -- reg ) EDX ;
@@ -25,15 +26,89 @@ IN: bootstrap.x86
 : rex-length ( -- n ) 0 ;
 
 [
-    ! load stack_chain
-    temp0 0 [] MOV rc-absolute-cell rt-stack-chain jit-rel
+    ! save stack frame size
+    stack-frame-size PUSH
+    ! push XT
+    0 PUSH rc-absolute-cell rt-this jit-rel
+    ! alignment
+    ESP stack-frame-size 3 bootstrap-cells - SUB
+] jit-prolog jit-define
+
+: jit-save-context ( -- )
+    EAX 0 [] MOV rc-absolute-cell rt-context jit-rel
     ! save stack pointer
-    temp0 [] stack-reg MOV
+    ECX ESP -4 [+] LEA
+    EAX [] ECX MOV ;
+
+[
+    jit-save-context
     ! pass vm ptr to primitive
-    arg1 0 MOV rc-absolute-cell rt-vm jit-rel
+    EAX 0 MOV rc-absolute-cell rt-vm jit-rel
     ! call the primitive
-    0 JMP rc-relative rt-primitive jit-rel
+    0 CALL rc-relative rt-primitive jit-rel
 ] jit-primitive jit-define
 
+! Inline cache miss entry points
+: jit-load-return-address ( -- )
+    EBX ESP stack-frame-size bootstrap-cell - [+] MOV ;
+
+! These are always in tail position with an existing stack
+! frame, and the stack. The frame setup takes this into account.
+: jit-inline-cache-miss ( -- )
+    jit-save-context
+    ESP 4 [+] 0 MOV 0 rc-absolute-cell jit-vm
+    ESP [] EBX MOV
+    0 CALL "inline_cache_miss" f rc-relative jit-dlsym ;
+
+[ jit-load-return-address jit-inline-cache-miss ]
+[ EAX CALL ]
+[ EAX JMP ]
+\ inline-cache-miss define-sub-primitive*
+
+[ jit-inline-cache-miss ]
+[ EAX CALL ]
+[ EAX JMP ]
+\ inline-cache-miss-tail define-sub-primitive*
+
+! Overflowing fixnum arithmetic
+: jit-overflow ( insn func -- )
+    jit-save-context
+    EAX ds-reg -4 [+] MOV
+    EDX ds-reg [] MOV
+    ds-reg 4 SUB
+    ECX EAX MOV
+    [ [ ECX EDX ] dip call( dst src -- ) ] dip
+    ds-reg [] ECX MOV
+    [ JNO ]
+    [
+        ECX 0 MOV 0 rc-absolute-cell jit-vm
+        [ 0 CALL ] dip f rc-relative jit-dlsym
+    ]
+    jit-conditional ;
+
+[ [ ADD ] "overflow_fixnum_add" jit-overflow ] \ fixnum+ define-sub-primitive
+
+[ [ SUB ] "overflow_fixnum_subtract" jit-overflow ] \ fixnum- define-sub-primitive
+
+[
+    jit-save-context
+    ECX ds-reg -4 [+] MOV
+    EBX ds-reg [] MOV
+    EBX tag-bits get SAR
+    ds-reg 4 SUB
+    EAX ECX MOV
+    EBX IMUL
+    ds-reg [] EAX MOV
+    [ JNO ]
+    [
+        EAX ECX MOV
+        EAX tag-bits get SAR
+        EDX EBX MOV
+        ECX 0 MOV 0 rc-absolute-cell jit-vm
+        0 CALL "overflow_fixnum_multiply" f rc-relative jit-dlsym
+    ]
+    jit-conditional
+] \ fixnum* define-sub-primitive
+
 << "vocab:cpu/x86/bootstrap.factor" parse-file suffix! >>
 call
index 0fc029fdfee4438875f9f998cad4ef91b1dc33c7..b77b08abe997e94de6ad2bcd2b31368d17925511 100644 (file)
@@ -1,8 +1,9 @@
 ! Copyright (C) 2007, 2009 Slava Pestov.
 ! See http://factorcode.org/license.txt for BSD license.
 USING: bootstrap.image.private kernel namespaces system
-layouts vocabs parser compiler.constants math
-cpu.x86.assembler cpu.x86.assembler.operands sequences ;
+layouts vocabs parser compiler.constants math math.private
+cpu.x86.assembler cpu.x86.assembler.operands sequences
+generic.single.private ;
 IN: bootstrap.x86
 
 8 \ cell set
@@ -22,18 +23,94 @@ IN: bootstrap.x86
 : rex-length ( -- n ) 1 ;
 
 [
-    ! load stack_chain
-    temp0 0 MOV rc-absolute-cell rt-stack-chain jit-rel
+    ! load XT
+    RDI 0 MOV rc-absolute-cell rt-this jit-rel
+    ! save stack frame size
+    stack-frame-size PUSH
+    ! push XT
+    RDI PUSH
+    ! alignment
+    RSP stack-frame-size 3 bootstrap-cells - SUB
+] jit-prolog jit-define
+
+: jit-save-context ( -- )
+    temp0 0 MOV rc-absolute-cell rt-context jit-rel
     temp0 temp0 [] MOV
     ! save stack pointer
-    temp0 [] stack-reg MOV
+    temp1 stack-reg bootstrap-cell neg [+] LEA
+    temp0 [] temp1 MOV ;
+
+[
+    jit-save-context
     ! load vm ptr
     arg1 0 MOV rc-absolute-cell rt-vm jit-rel
     ! load XT
     temp1 0 MOV rc-absolute-cell rt-primitive jit-rel
     ! go
-    temp1 JMP
+    temp1 CALL
 ] jit-primitive jit-define
 
+! Inline cache miss entry points
+: jit-load-return-address ( -- )
+    RBX RSP stack-frame-size bootstrap-cell - [+] MOV ;
+
+! These are always in tail position with an existing stack
+! frame, and the stack. The frame setup takes this into account.
+: jit-inline-cache-miss ( -- )
+    jit-save-context
+    arg1 RBX MOV
+    arg2 0 MOV 0 rc-absolute-cell jit-vm
+    0 CALL "inline_cache_miss" f rc-relative jit-dlsym ;
+
+[ jit-load-return-address jit-inline-cache-miss ]
+[ RAX CALL ]
+[ RAX JMP ]
+\ inline-cache-miss define-sub-primitive*
+
+[ jit-inline-cache-miss ]
+[ RAX CALL ]
+[ RAX JMP ]
+\ inline-cache-miss-tail define-sub-primitive*
+
+! Overflowing fixnum arithmetic
+: jit-overflow ( insn func -- )
+    jit-save-context
+    arg1 ds-reg bootstrap-cell neg [+] MOV
+    arg2 ds-reg [] MOV
+    ds-reg bootstrap-cell SUB
+    arg3 arg1 MOV
+    [ [ arg3 arg2 ] dip call ] dip
+    ds-reg [] arg3 MOV
+    [ JNO ]
+    [
+        arg3 0 MOV 0 rc-absolute-cell jit-vm
+        [ 0 CALL ] dip f rc-relative jit-dlsym
+    ]
+    jit-conditional ; inline
+
+[ [ ADD ] "overflow_fixnum_add" jit-overflow ] \ fixnum+ define-sub-primitive
+
+[ [ SUB ] "overflow_fixnum_subtract" jit-overflow ] \ fixnum- define-sub-primitive
+
+[
+    jit-save-context
+    RCX ds-reg bootstrap-cell neg [+] MOV
+    RBX ds-reg [] MOV
+    RBX tag-bits get SAR
+    ds-reg bootstrap-cell SUB
+    RAX RCX MOV
+    RBX IMUL
+    ds-reg [] RAX MOV
+    [ JNO ]
+    [
+        arg1 RCX MOV
+        arg1 tag-bits get SAR
+        arg2 RBX MOV
+        arg3 0 MOV 0 rc-absolute-cell jit-vm
+        0 CALL "overflow_fixnum_multiply" f rc-relative jit-dlsym
+    ]
+    jit-conditional
+] \ fixnum* define-sub-primitive
+
 << "vocab:cpu/x86/bootstrap.factor" parse-file suffix! >>
 call
index 238fad984a86420115d186df8433a648f64c05e4..350c037e3ab069affd49aff525de31c9f62ce032 100644 (file)
@@ -8,6 +8,7 @@ IN: bootstrap.x86
 : stack-frame-size ( -- n ) 4 bootstrap-cells ;
 : arg1 ( -- reg ) RDI ;
 : arg2 ( -- reg ) RSI ;
+: arg3 ( -- reg ) RDX ;
 
 << "vocab:cpu/x86/64/bootstrap.factor" parse-file suffix! >>
 call
index 6cf2f2a10f6ef405d71ac885b64840c4bdafae6e..d25cc980843f08b5069be619bd5995e0c5751cd3 100644 (file)
@@ -8,6 +8,7 @@ IN: bootstrap.x86
 : stack-frame-size ( -- n ) 8 bootstrap-cells ;
 : arg1 ( -- reg ) RCX ;
 : arg2 ( -- reg ) RDX ;
+: arg3 ( -- reg ) R8 ;
 
 << "vocab:cpu/x86/64/bootstrap.factor" parse-file suffix! >>
 call
index ab02ce7e74618886298c837c224838bd4ca4718e..db048dd31460280f876792532d2ebe2eab50627b 100644 (file)
@@ -10,7 +10,7 @@ big-endian off
 
 [
     ! Load word
-    temp0 0 MOV rc-absolute-cell rt-immediate jit-rel
+    temp0 0 MOV rc-absolute-cell rt-literal jit-rel
     ! Bump profiling counter
     temp0 profile-count-offset [+] 1 tag-fixnum ADD
     ! Load word->code
@@ -21,20 +21,9 @@ big-endian off
     temp0 JMP
 ] jit-profiling jit-define
 
-[
-    ! load XT
-    temp0 0 MOV rc-absolute-cell rt-this jit-rel
-    ! save stack frame size
-    stack-frame-size PUSH
-    ! push XT
-    temp0 PUSH
-    ! alignment
-    stack-reg stack-frame-size 3 bootstrap-cells - SUB
-] jit-prolog jit-define
-
 [
     ! load literal
-    temp0 0 MOV rc-absolute-cell rt-immediate jit-rel
+    temp0 0 MOV rc-absolute-cell rt-literal jit-rel
     ! increment datastack pointer
     ds-reg bootstrap-cell ADD
     ! store literal on datastack
@@ -50,10 +39,6 @@ big-endian off
     0 CALL rc-relative rt-xt-pic jit-rel
 ] jit-word-call jit-define
 
-[
-    0 JMP rc-relative rt-xt jit-rel
-] jit-word-special jit-define
-
 [
     ! load boolean
     temp0 ds-reg [] MOV
@@ -133,20 +118,35 @@ big-endian off
     jit-3r>
 ] jit-3dip jit-define
 
-: prepare-(execute) ( -- operand )
+[
     ! load from stack
-    temp0 ds-reg [] MOV
+    arg1 ds-reg [] MOV
     ! pop stack
     ds-reg bootstrap-cell SUB
-    ! execute word
-    temp0 word-xt-offset [+] ;
+    ! pass vm pointer
+    arg2 0 MOV 0 rc-absolute-cell jit-vm
+]
+[ arg1 quot-xt-offset [+] CALL ]
+[ arg1 quot-xt-offset [+] JMP ]
+\ (call) define-sub-primitive*
 
-[ prepare-(execute) JMP ] jit-execute-jump jit-define
+[
+    ! load from stack
+    arg1 ds-reg [] MOV
+    ! pop stack
+    ds-reg bootstrap-cell SUB
+]
+[ arg1 word-xt-offset [+] CALL ]
+[ arg1 word-xt-offset [+] JMP ]
+\ (execute) define-sub-primitive*
 
-[ prepare-(execute) CALL ] jit-execute-call jit-define
+[
+    arg1 ds-reg [] MOV
+    ds-reg bootstrap-cell SUB
+    arg1 word-xt-offset [+] JMP
+] jit-execute jit-define
 
 [
-    ! unwind stack frame
     stack-reg stack-frame-size bootstrap-cell - ADD
 ] jit-epilog jit-define
 
@@ -176,16 +176,17 @@ big-endian off
     temp0 temp1 MOV
     load-tag
     temp1 tuple type-number tag-fixnum CMP
-    [ temp1 temp0 tuple type-number neg bootstrap-cell + [+] MOV ] { } make
-    [ length JNE ] [ % ] bi
+    [ JNE ]
+    [ temp1 temp0 tuple type-number neg bootstrap-cell + [+] MOV ]
+    jit-conditional
 ] pic-tuple jit-define
 
 [
-    temp1 HEX: ffffffff CMP rc-absolute rt-immediate jit-rel
+    temp1 HEX: ffffffff CMP rc-absolute rt-literal jit-rel
 ] pic-check-tag jit-define
 
 [
-    temp2 HEX: ffffffff MOV rc-absolute-cell rt-immediate jit-rel
+    temp2 HEX: ffffffff MOV rc-absolute-cell rt-literal jit-rel
     temp1 temp2 CMP
 ] pic-check-tuple jit-define
 
@@ -195,7 +196,7 @@ big-endian off
 
 [
     ! cache = ...
-    temp0 0 MOV rc-absolute-cell rt-immediate jit-rel
+    temp0 0 MOV rc-absolute-cell rt-literal jit-rel
     ! key = hashcode(class)
     temp2 temp1 MOV
     bootstrap-cell 4 = [ temp2 1 SHR ] when
@@ -224,18 +225,6 @@ big-endian off
 
 ! ! ! Sub-primitives
 
-! Quotations and words
-[
-    ! load from stack
-    arg1 ds-reg [] MOV
-    ! pop stack
-    ds-reg bootstrap-cell SUB
-    ! pass vm pointer
-    arg2 0 MOV 0 jit-parameter rc-absolute-cell rt-vm jit-rel
-    ! call quotation
-    arg1 quot-xt-offset [+] JMP
-] \ (call) define-sub-primitive
-
 ! Objects
 [
     ! load from stack
@@ -373,7 +362,7 @@ big-endian off
 : jit-compare ( insn -- )
     ! load t
     t jit-literal
-    temp3 0 MOV rc-absolute-cell rt-immediate jit-rel
+    temp3 0 MOV rc-absolute-cell rt-literal jit-rel
     ! load f
     temp1 \ f type-number MOV
     ! load first value
index 3dcd5969c9fa67532b88e4886945e57086909d4d..78c219ae3cc0c59a9b06f335330e59c37b95d929 100644 (file)
@@ -326,6 +326,9 @@ tuple
     { "fixnum-shift-fast" "math.private" (( x y -- z )) }
     { "fixnum/i-fast" "math.private" (( x y -- z )) }
     { "fixnum/mod-fast" "math.private" (( x y -- z w )) }
+    { "fixnum+" "math.private" (( x y -- z )) }
+    { "fixnum-" "math.private" (( x y -- z )) }
+    { "fixnum*" "math.private" (( x y -- z )) }
     { "fixnum<" "math.private" (( x y -- ? )) }
     { "fixnum<=" "math.private" (( x y -- z )) }
     { "fixnum>" "math.private" (( x y -- ? )) }
@@ -352,6 +355,8 @@ tuple
     { "load-local" "locals.backend" (( obj -- )) }
     { "drop-locals" "locals.backend" (( n -- )) }
     { "mega-cache-lookup" "generic.single.private" (( methods index cache -- )) }
+    { "inline-cache-miss" "generic.single.private" (( generic methods index cache -- )) }
+    { "inline-cache-miss-tail" "generic.single.private" (( generic methods index cache -- )) }
 } [ first3 make-sub-primitive ] each
 
 ! Primitive words
@@ -374,9 +379,6 @@ tuple
     { "double>bits" "math" (( x -- n )) }
     { "bits>float" "math" (( n -- x )) }
     { "bits>double" "math" (( n -- x )) }
-    { "fixnum+" "math.private" (( x y -- z )) }
-    { "fixnum-" "math.private" (( x y -- z )) }
-    { "fixnum*" "math.private" (( x y -- z )) }
     { "fixnum/i" "math.private" (( x y -- z )) }
     { "fixnum/mod" "math.private" (( x y -- z w )) }
     { "fixnum-shift" "math.private" (( x y -- z )) }
@@ -508,8 +510,6 @@ tuple
     { "jit-compile" "quotations" (( quot -- )) }
     { "load-locals" "locals.backend" (( ... n -- )) }
     { "check-datastack" "kernel.private" (( array in# out# -- ? )) }
-    { "inline-cache-miss" "generic.single.private" (( generic methods index cache -- )) }
-    { "inline-cache-miss-tail" "generic.single.private" (( generic methods index cache -- )) }
     { "mega-cache-miss" "generic.single.private" (( methods index cache -- method )) }
     { "lookup-method" "generic.single.private" (( object methods -- method )) }
     { "reset-dispatch-stats" "tools.dispatch.private" (( -- )) }
index bc372d8d90c9df66b873e7b4a5d7e3217dfa6dec..996a6e9bd46b828f8b1dcef0719bde219285209d 100644 (file)
@@ -100,7 +100,7 @@ GENERIC: definitions-changed ( assoc obj -- )
 ! Incremented each time stack effects potentially changed, used
 ! by compiler.tree.propagation.call-effect for call( and execute(
 ! inline caching
-: effect-counter ( -- n ) 46 getenv ; inline
+: effect-counter ( -- n ) 47 getenv ; inline
 
 GENERIC: bump-effect-counter* ( defspec -- ? )
 
@@ -132,7 +132,7 @@ M: object bump-effect-counter* drop f ;
     or ;
 
 : bump-effect-counter ( -- )
-    bump-effect-counter? [ 46 getenv 0 or 1 + 46 setenv ] when ;
+    bump-effect-counter? [ 47 getenv 0 or 1 + 47 setenv ] when ;
 
 : notify-observers ( -- )
     updated-definitions dup assoc-empty?
index 28197db64df8b1f6e29866454555656da5f417bb..cbd18b3c1a586af889e9b28472f6743715455a85 100755 (executable)
@@ -28,29 +28,32 @@ stack_frame *factor_vm::fix_callstack_top(stack_frame *top, stack_frame *bottom)
        return frame + 1;
 }
 
-/* We ignore the topmost frame, the one calling 'callstack',
+/* We ignore the two topmost frames, the 'callstack' primitive
+frame itself, and the frame calling the 'callstack' primitive,
 so that set-callstack doesn't get stuck in an infinite loop.
 
 This means that if 'callstack' is called in tail position, we
 will have popped a necessary frame... however this word is only
 called by continuation implementation, and user code shouldn't
 be calling it at all, so we leave it as it is for now. */
-stack_frame *factor_vm::capture_start()
+stack_frame *factor_vm::second_from_top_stack_frame()
 {
        stack_frame *frame = ctx->callstack_bottom - 1;
-       while(frame >= ctx->callstack_top && frame_successor(frame) >= ctx->callstack_top)
+       while(frame >= ctx->callstack_top
+               && frame_successor(frame) >= ctx->callstack_top
+               && frame_successor(frame_successor(frame)) >= ctx->callstack_top)
+       {
                frame = frame_successor(frame);
+       }
        return frame + 1;
 }
 
 void factor_vm::primitive_callstack()
 {
-       stack_frame *top = capture_start();
+       stack_frame *top = second_from_top_stack_frame();
        stack_frame *bottom = ctx->callstack_bottom;
 
-       fixnum size = (cell)bottom - (cell)top;
-       if(size < 0)
-               size = 0;
+       fixnum size = std::max((fixnum)0,(fixnum)bottom - (fixnum)top);
 
        callstack *stack = allot_callstack(size);
        memcpy(stack->top(),top,size);
index 76bf3ecea49754997eeb99789691575abdc077f1..dcbf78632ee7a24fcaca14b9f5dc4005f20b3b00 100755 (executable)
@@ -6,7 +6,7 @@ inline static cell callstack_size(cell size)
        return sizeof(callstack) + size;
 }
 
-VM_ASM_API void save_callstack_bottom(stack_frame *callstack_bottom, factor_vm *vm);
+VM_ASM_API void save_callstack_bottom(stack_frame *callstack_bottom, factor_vm *parent);
 
 /* This is a little tricky. The iterator may allocate memory, so we
 keep the callstack in a GC root and use relative offsets */
@@ -25,12 +25,9 @@ template<typename Iterator> void factor_vm::iterate_callstack_object(callstack *
 
 template<typename Iterator> void factor_vm::iterate_callstack(context *ctx, Iterator &iterator)
 {
-       cell top = (cell)ctx->callstack_top;
-       cell bottom = (cell)ctx->callstack_bottom;
+       stack_frame *frame = ctx->callstack_bottom - 1;
 
-       stack_frame *frame = (stack_frame *)bottom - 1;
-
-       while((cell)frame >= top)
+       while(frame >= ctx->callstack_top)
        {
                iterator(frame);
                frame = frame_successor(frame);
index 7f73766714bb26f60c728a99ae801f67f0952205..ae96def0a9f88da1fabdf956f269fb92adf072ec 100755 (executable)
@@ -264,7 +264,7 @@ struct initial_code_block_visitor {
        {
                switch(op.rel_type())
                {
-               case RT_IMMEDIATE:
+               case RT_LITERAL:
                        op.store_value(next_literal());
                        break;
                case RT_XT:
index 41ae20232d1efefa27ccec9a1be32daf52c5b92c..3cdf005e035aa67b02805b8000fd9dfd69910110 100644 (file)
@@ -108,7 +108,7 @@ struct code_block_compaction_relocation_visitor {
 
                switch(op.rel_type())
                {
-               case RT_IMMEDIATE:
+               case RT_LITERAL:
                        op.store_value(slot_forwarder.visit_pointer(op.load_value(old_offset)));
                        break;
                case RT_XT:
index 40f2521e501241882460b16a5200abdf4fdc2d64..876b633a02caabe1ab8551414ef7a9f9717d35e6 100644 (file)
@@ -4,49 +4,6 @@ in the public domain. */
 
 #define DS_REG r13
 
-DEF(void,primitive_fixnum_add,(void *vm)):
-       mr r5,r3  /* save vm ptr for overflow */
-       lwz r3,0(DS_REG)
-       lwz r4,-4(DS_REG)
-       subi DS_REG,DS_REG,4
-       li r0,0
-       mtxer r0
-       addo. r6,r3,r4
-       bso add_overflow
-       stw r6,0(DS_REG)
-       blr
-add_overflow:
-       b MANGLE(overflow_fixnum_add)
-
-DEF(void,primitive_fixnum_subtract,(void *vm)):
-       mr r5,r3  /* save vm ptr for overflow */
-       lwz r3,-4(DS_REG)
-       lwz r4,0(DS_REG)
-       subi DS_REG,DS_REG,4
-       li r0,0
-       mtxer r0
-       subfo. r6,r4,r3
-       bso sub_overflow
-       stw r6,0(DS_REG)
-       blr
-sub_overflow:
-       b MANGLE(overflow_fixnum_subtract)
-
-DEF(void,primitive_fixnum_multiply,(void *vm)):
-       mr r5,r3  /* save vm ptr for overflow */
-       lwz r3,0(DS_REG)
-       lwz r4,-4(DS_REG)
-       subi DS_REG,DS_REG,4
-       srawi r3,r3,4
-       mullwo. r6,r3,r4
-       bso multiply_overflow
-       stw r6,0(DS_REG)
-       blr
-multiply_overflow:
-       srawi r4,r4,4
-       b MANGLE(overflow_fixnum_multiply)
-       
-/* Note that the XT is passed to the quotation in r11 */
 #define CALL_OR_JUMP_QUOT \
        lwz r11,12(r3)     /* load quotation-xt slot */ XX \
 
@@ -150,35 +107,35 @@ DEF(void,c_to_factor,(cell quot, void *vm)):
        SAVE_FP(f30,52)
        SAVE_FP(f31,54)
 
-        SAVE_V(v20,56)
-        SAVE_V(v21,60)
-        SAVE_V(v22,64)
-        SAVE_V(v23,68)
-        SAVE_V(v24,72)
-        SAVE_V(v25,76)
-        SAVE_V(v26,80)
-        SAVE_V(v27,84)
-        SAVE_V(v28,88)
-        SAVE_V(v29,92)
-        SAVE_V(v30,96)
-        SAVE_V(v31,100)
+       SAVE_V(v20,56)
+       SAVE_V(v21,60)
+       SAVE_V(v22,64)
+       SAVE_V(v23,68)
+       SAVE_V(v24,72)
+       SAVE_V(v25,76)
+       SAVE_V(v26,80)
+       SAVE_V(v27,84)
+       SAVE_V(v28,88)
+       SAVE_V(v29,92)
+       SAVE_V(v30,96)
+       SAVE_V(v31,100)
 
        /* r4 vm ptr preserved */
-        mfvscr v0
-        li r2,SAVE_AT(104)
-        stvxl v0,r2,r1
-        addi r2,r2,0xc
-        lwzx r5,r2,r1
-        lis r6,0x1
-        andc r5,r5,r6
-        stwx r5,r2,r1
-        subi r2,r2,0xc
-        lvxl v0,r2,r1
-        mtvscr v0
-
-        /* save args in non-volatile regs */
-        mr r15,r3
-        mr r16,r4
+       mfvscr v0
+       li r2,SAVE_AT(104)
+       stvxl v0,r2,r1
+       addi r2,r2,0xc
+       lwzx r5,r2,r1
+       lis r6,0x1
+       andc r5,r5,r6
+       stwx r5,r2,r1
+       subi r2,r2,0xc
+       lvxl v0,r2,r1
+       mtvscr v0
+
+       /* save args in non-volatile regs */
+       mr r15,r3
+       mr r16,r4
 
        /* pass call stack pointer as an argument */
        mr r3,r1
@@ -189,23 +146,23 @@ DEF(void,c_to_factor,(cell quot, void *vm)):
        mr r4,r16
        CALL_QUOT
 
-        RESTORE_V(v0,104)
-        mtvscr v0
-
-        RESTORE_V(v31,100)
-        RESTORE_V(v30,96)
-        RESTORE_V(v29,92)
-        RESTORE_V(v28,88)
-        RESTORE_V(v27,84)
-        RESTORE_V(v26,80)
-        RESTORE_V(v25,76)
-        RESTORE_V(v24,72)
-        RESTORE_V(v23,68)
-        RESTORE_V(v22,64)
-        RESTORE_V(v21,60)
-        RESTORE_V(v20,56)
-
-        /* Restore FPRs */
+       RESTORE_V(v0,104)
+       mtvscr v0
+
+       RESTORE_V(v31,100)
+       RESTORE_V(v30,96)
+       RESTORE_V(v29,92)
+       RESTORE_V(v28,88)
+       RESTORE_V(v27,84)
+       RESTORE_V(v26,80)
+       RESTORE_V(v25,76)
+       RESTORE_V(v24,72)
+       RESTORE_V(v23,68)
+       RESTORE_V(v22,64)
+       RESTORE_V(v21,60)
+       RESTORE_V(v20,56)
+
+       /* Restore FPRs */
        RESTORE_FP(f31,54)
        RESTORE_FP(f30,52)
        RESTORE_FP(f29,50)
@@ -299,17 +256,6 @@ DEF(void,flush_icache,(void *start, int len)):
        isync
        blr
 
-DEF(void,primitive_inline_cache_miss,(void *vm)):
-       mflr r6
-DEF(void,primitive_inline_cache_miss_tail,(void *vm)):
-       PROLOGUE
-       mr r4,r3          /* vm ptr in 2nd arg */
-       mr r3,r6
-       bl MANGLE(inline_cache_miss)
-       EPILOGUE
-       mtctr r3
-       bctr
-
 DEF(void,get_ppc_fpu_env,(void*)):
        mffs f0
        stfd f0,0(r3)
@@ -341,4 +287,3 @@ DEF(void,set_ppc_vmx_env,(const void*)):
        lvxl v0,0,r4
        mtvscr v0
        blr
-
index c0532f0ece1cae33aa6b1786f47c799f721b86a9..b9e60b06a951c82d1329b0bd2a999aeb0883bdb5 100644 (file)
 #define NV0 %ebx
 #define NV1 %ebp
 
-#define ARITH_TEMP_1 %ebp
-#define ARITH_TEMP_2 %ebx
-#define DIV_RESULT %eax
-
 #define CELL_SIZE 4
 #define STACK_PADDING 12
 
@@ -44,20 +40,32 @@ DEF(void,set_callstack,(F_STACK_FRAME *to, F_STACK_FRAME *from, CELL length, voi
        add $12,%esp                       /* pop args from the stack */
        ret                                /* return _with new stack_ */
 
+DEF(F_FASTCALL void,throw_impl,(CELL quot, F_STACK_FRAME *rewind_to, void *vm)):
+       mov ARG2,NV0  /* remember vm ptr in case quot_xt = lazy_jit_compile */          
+       /* clear x87 stack, but preserve rounding mode and exception flags */
+       sub $2,STACK_REG
+       fnstcw (STACK_REG)
+       fninit
+       fldcw (STACK_REG)
+       /* rewind_to */
+       mov ARG1,STACK_REG
+       mov NV0,ARG1
+       jmp *QUOT_XT_OFFSET(ARG0)
+
+DEF(F_FASTCALL void,lazy_jit_compile,(CELL quot, void *vm)):
+       mov ARG1,ARG2
+       mov STACK_REG,ARG1           /* Save stack pointer */
+       sub $STACK_PADDING,STACK_REG
+       call MANGLE(lazy_jit_compile_impl)
+       mov RETURN_REG,ARG0          /* No-op on 32-bit */
+       add $STACK_PADDING,STACK_REG
+    jmp *QUOT_XT_OFFSET(ARG0)    /* Call the quotation */
+
+
 DEF(long long,read_timestamp_counter,(void)):
        rdtsc
        ret
 
-DEF(void,primitive_inline_cache_miss,(void *vm)):
-       mov (%esp),%ebx
-DEF(void,primitive_inline_cache_miss_tail,(void *vm)):
-       sub $4,%esp
-       push ARG0   /* push vm ptr */
-       push %ebx
-       call MANGLE(inline_cache_miss)
-       add $12,%esp
-       jmp *%eax
-
 DEF(void,get_sse_env,(void*)):
        movl 4(%esp), %eax
        stmxcsr (%eax)
@@ -80,28 +88,6 @@ DEF(void,set_x87_env,(const void*)):
        fldcw 2(%eax)
        ret
 
-DEF(F_FASTCALL void,throw_impl,(CELL quot, F_STACK_FRAME *rewind_to, void *vm)):
-       mov ARG2,NV0  /* remember vm ptr in case quot_xt = lazy_jit_compile */          
-       /* clear x87 stack, but preserve rounding mode and exception flags */
-       sub $2,STACK_REG
-       fnstcw (STACK_REG)
-       fninit
-       fldcw (STACK_REG)
-       /* rewind_to */
-       mov ARG1,STACK_REG
-       mov NV0,ARG1
-       jmp *QUOT_XT_OFFSET(ARG0)
-
-DEF(F_FASTCALL void,lazy_jit_compile,(CELL quot, void *vm)):
-       mov ARG1,ARG2
-       mov STACK_REG,ARG1           /* Save stack pointer */
-       sub $STACK_PADDING,STACK_REG
-       call MANGLE(lazy_jit_compile_impl)
-       mov RETURN_REG,ARG0          /* No-op on 32-bit */
-       add $STACK_PADDING,STACK_REG
-    jmp *QUOT_XT_OFFSET(ARG0)    /* Call the quotation */
-
-       
 #include "cpu-x86.S"
 
 #ifdef WINDOWS
index 8ccd703bfeb015e87ee4ad291f12336ce620abb1..1a943e6d1ee1b3fc6d57e76cdbfd43b1b9bbf5c9 100644 (file)
 #define NV0 %rbp
 #define NV1 %r12
 
-#define ARITH_TEMP_1 %r8
-#define ARITH_TEMP_2 %r9
-#define DIV_RESULT %rax
-
 #ifdef WINDOWS
 
        #define ARG0 %rcx
@@ -69,6 +65,26 @@ DEF(void,set_callstack,(F_STACK_FRAME *to, F_STACK_FRAME *from, CELL length, voi
        call *ARG3                         /* call memcpy */
        ret                                /* return _with new stack_ */
 
+DEF(F_FASTCALL void,throw_impl,(CELL quot, F_STACK_FRAME *rewind_to, void *vm)):
+       /* clear x87 stack, but preserve rounding mode and exception flags */
+       sub $2,STACK_REG
+       fnstcw (STACK_REG)
+       fninit
+       fldcw (STACK_REG)
+       /* rewind_to */
+       mov ARG1,STACK_REG
+       mov ARG2,ARG1  /* make vm ptr 2nd arg in case quot_xt = lazy_jit_compile */
+       jmp *QUOT_XT_OFFSET(ARG0)
+
+DEF(F_FASTCALL void,lazy_jit_compile,(CELL quot, void *vm)):
+       mov ARG1,ARG2                /* vm is 3rd arg */
+       mov STACK_REG,ARG1           /* Save stack pointer */
+       sub $STACK_PADDING,STACK_REG
+       call MANGLE(lazy_jit_compile_impl)
+       mov RETURN_REG,ARG0          /* No-op on 32-bit */
+       add $STACK_PADDING,STACK_REG
+        jmp *QUOT_XT_OFFSET(ARG0)    /* Call the quotation */
+
 DEF(long long,read_timestamp_counter,(void)):
        mov $0,%rax
        rdtsc
@@ -76,16 +92,6 @@ DEF(long long,read_timestamp_counter,(void)):
        or %rdx,%rax
        ret
 
-DEF(void,primitive_inline_cache_miss,(void *vm)):
-       mov (%rsp),%rbx
-DEF(void,primitive_inline_cache_miss_tail,(void *vm)):
-       sub $STACK_PADDING,%rsp
-       mov ARG0,ARG1
-       mov %rbx,ARG0
-       call MANGLE(inline_cache_miss)
-       add $STACK_PADDING,%rsp
-       jmp *%rax
-
 DEF(void,get_sse_env,(void*)):
        stmxcsr (%rdi)
        ret
@@ -103,26 +109,5 @@ DEF(void,set_x87_env,(const void*)):
        fnclex
        fldcw 2(%rdi)
        ret
-
-DEF(F_FASTCALL void,throw_impl,(CELL quot, F_STACK_FRAME *rewind_to, void *vm)):
-       /* clear x87 stack, but preserve rounding mode and exception flags */
-       sub $2,STACK_REG
-       fnstcw (STACK_REG)
-       fninit
-       fldcw (STACK_REG)
-       /* rewind_to */
-       mov ARG1,STACK_REG
-       mov ARG2,ARG1  /* make vm ptr 2nd arg in case quot_xt = lazy_jit_compile */
-       jmp *QUOT_XT_OFFSET(ARG0)
-
-DEF(F_FASTCALL void,lazy_jit_compile,(CELL quot, void *vm)):
-       mov ARG1,ARG2                /* vm is 3rd arg */
-       mov STACK_REG,ARG1           /* Save stack pointer */
-       sub $STACK_PADDING,STACK_REG
-       call MANGLE(lazy_jit_compile_impl)
-       mov RETURN_REG,ARG0          /* No-op on 32-bit */
-       add $STACK_PADDING,STACK_REG
-        jmp *QUOT_XT_OFFSET(ARG0)    /* Call the quotation */
-
        
 #include "cpu-x86.S"
index 411a0cdaa69bed2ff50a56483e5f90fc4a3f1228..87e45c75db3da5dde978e73127d079439212db22 100644 (file)
@@ -1,44 +1,3 @@
-DEF(void,primitive_fixnum_add,(void *myvm)):
-       mov ARG0, ARG2  /* save vm ptr for overflow */
-       mov (DS_REG),ARG0
-       mov -CELL_SIZE(DS_REG),ARG1
-       sub $CELL_SIZE,DS_REG
-       mov ARG1,ARITH_TEMP_1
-       add ARG0,ARITH_TEMP_1
-       jo MANGLE(overflow_fixnum_add)
-       mov ARITH_TEMP_1,(DS_REG)
-       ret
-
-DEF(void,primitive_fixnum_subtract,(void *myvm)):
-       mov ARG0, ARG2  /* save vm ptr for overflow */
-       mov (DS_REG),ARG1
-       mov -CELL_SIZE(DS_REG),ARG0
-       sub $CELL_SIZE,DS_REG
-       mov ARG0,ARITH_TEMP_1
-       sub ARG1,ARITH_TEMP_1
-       jo MANGLE(overflow_fixnum_subtract)
-       mov ARITH_TEMP_1,(DS_REG)
-       ret
-
-DEF(void,primitive_fixnum_multiply,(void *myvm)):
-       push ARG0  /* save vm ptr for overflow */
-       mov (DS_REG),ARITH_TEMP_1
-       mov ARITH_TEMP_1,DIV_RESULT
-       mov -CELL_SIZE(DS_REG),ARITH_TEMP_2
-       sar $4,ARITH_TEMP_2
-       sub $CELL_SIZE,DS_REG
-       imul ARITH_TEMP_2
-       jo multiply_overflow
-       mov DIV_RESULT,(DS_REG)
-       pop ARG2
-       ret
-multiply_overflow:
-       sar $4,ARITH_TEMP_1
-       mov ARITH_TEMP_1,ARG0
-       mov ARITH_TEMP_2,ARG1
-       pop ARG2
-       jmp MANGLE(overflow_fixnum_multiply)
-
 DEF(F_FASTCALL void,c_to_factor,(CELL quot, void *vm)):
        PUSH_NONVOLATILE
        mov ARG0,NV0
index 85585aeda627935446b60d82c105145973a60da4..4eed59dd78d035020e581b03990ec678b84acb6d 100644 (file)
@@ -47,7 +47,12 @@ inline static void set_call_target(cell return_address, void *target)
 
 inline static bool tail_call_site_p(cell return_address)
 {
-       return call_site_opcode(return_address) == jmp_opcode;
+       switch(call_site_opcode(return_address))
+       {
+       case jmp_opcode: return true;
+       case call_opcode: return false;
+       default: abort(); return false;
+       }
 }
 
 inline static unsigned int fpu_status(unsigned int status)
@@ -74,8 +79,8 @@ VM_ASM_API void throw_impl(cell quot, stack_frame *rewind_to, void *vm);
 VM_ASM_API void lazy_jit_compile(cell quot, void *vm);
 
 VM_C_API void set_callstack(stack_frame *to,
-                             stack_frame *from,
-                             cell length,
-                             void *(*memcpy)(void*,const void*, size_t));
+       stack_frame *from,
+       cell length,
+       void *(*memcpy)(void*,const void*, size_t));
 
 }
index aa7e3eb51a15fe38b5c88518cd703e272e2fc5a2..8e732830e09dfd1e01fc5a059438d873157d2ec7 100755 (executable)
@@ -268,9 +268,4 @@ void factor_vm::primitive_all_instances()
        dpush(instances(TYPE_COUNT));
 }
 
-cell factor_vm::find_all_words()
-{
-       return instances(WORD_TYPE);
-}
-
 }
index c02569df255ab91bf811707d34923e74a5accaa3..a19e8fe34edbcc3e826f1e6ada94e539adc866f5 100755 (executable)
@@ -10,7 +10,7 @@ std::ostream &operator<<(std::ostream &out, const string *str)
        return out;
 }
 
-void factor_vm::print_word(wordword, cell nesting)
+void factor_vm::print_word(word *word, cell nesting)
 {
        if(tagged<object>(word->vocabulary).type_p(STRING_TYPE))
                std::cout << untag<string>(word->vocabulary) << ":";
@@ -30,7 +30,7 @@ void factor_vm::print_factor_string(string *str)
        std::cout << '"' << str << '"';
 }
 
-void factor_vm::print_array(arrayarray, cell nesting)
+void factor_vm::print_array(array *array, cell nesting)
 {
        cell length = array_capacity(array);
        cell i;
@@ -160,8 +160,11 @@ struct stack_frame_printer {
        explicit stack_frame_printer(factor_vm *parent_) : parent(parent_) {}
        void operator()(stack_frame *frame)
        {
+               std::cout << "frame: " << std::hex << (cell)frame << std::dec << std::endl;
+               std::cout << "executing: ";
                parent->print_obj(parent->frame_executing(frame));
                std::cout << std::endl;
+               std::cout << "scan: ";
                parent->print_obj(parent->frame_scan(frame));
                std::cout << std::endl;
                std::cout << "word/quot addr: ";
index 5b6e90437b8875f116bab180f8b617033e8b4ee2..9ee9957819411ad7ebd230fbb70fb2a1411c1cb7 100755 (executable)
@@ -166,7 +166,7 @@ void quotation_jit::emit_mega_cache_lookup(cell methods_, fixnum index, cell cac
        /* Now the new method has been stored into the cache, and its on
           the stack. */
        emit(parent->special_objects[JIT_EPILOG]);
-       emit(parent->special_objects[JIT_EXECUTE_JUMP]);
+       emit(parent->special_objects[JIT_EXECUTE]);
 }
 
 }
index da7da4a95125f048f5a1d045e5b8784fb3134c14..7ee4f4141319c0d2f00d9db086a24255fbab1b8e 100644 (file)
@@ -75,7 +75,7 @@ void factor_vm::update_code_roots_for_compaction()
                /* Offset of return address within 16-byte allocation line */
                cell offset = root->value - (cell)block;
 
-               if(root->valid && state->marked_p((code_block *)root->value))
+               if(root->valid && state->marked_p(block))
                {
                        block = state->forward_block(block);
                        root->value = (cell)block + offset;
index 4131365adc1f073a9f352245d187a72b9bac33ab..1afd3d0b1b398d3695fb168d1eb7c6197fcc86a0 100755 (executable)
@@ -182,7 +182,7 @@ struct code_block_fixup_relocation_visitor {
 
                switch(op.rel_type())
                {
-               case RT_IMMEDIATE:
+               case RT_LITERAL:
                        op.store_value(data_visitor.visit_pointer(op.load_value(old_offset)));
                        break;
                case RT_XT:
index c8be92b0a98f89e7f142b6c68c20c794b3425878..6923a650e77b7993c6bcbf3732147534b1120980 100755 (executable)
@@ -104,16 +104,24 @@ void inline_cache_jit::compile_inline_cache(fixnum index,
                emit_with_literal(parent->special_objects[PIC_HIT],method);
        }
 
-       /* Generate machine code to handle a cache miss, which ultimately results in
-          this function being called again.
+       /* If none of the above conditionals tested true, then execution "falls
+          through" to here. */
 
-          The inline-cache-miss primitive call receives enough information to
-          reconstruct the PIC. */
+       /* A stack frame is set up, since the inline-cache-miss sub-primitive
+       makes a subroutine call to the VM. */
+       emit(parent->special_objects[JIT_PROLOG]);
+
+       /* The inline-cache-miss sub-primitive call receives enough information to
+          reconstruct the PIC with the new entry. */
        push(generic_word.value());
        push(methods.value());
        push(tag_fixnum(index));
        push(cache_entries.value());
-       word_special(parent->special_objects[tail_call_p ? PIC_MISS_TAIL_WORD : PIC_MISS_WORD]);
+
+       emit_subprimitive(
+               parent->special_objects[tail_call_p ? PIC_MISS_TAIL_WORD : PIC_MISS_WORD],
+               true, /* tail_call_p */
+               true); /* stack_frame_p */
 }
 
 code_block *factor_vm::compile_inline_cache(fixnum index,
@@ -180,8 +188,15 @@ to take care of the details. */
 void *factor_vm::inline_cache_miss(cell return_address_)
 {
        code_root return_address(return_address_,this);
-
        check_code_pointer(return_address.value);
+       bool tail_call_site = tail_call_site_p(return_address.value);
+
+#ifdef PIC_DEBUG
+       std::cout << "Inline cache miss at "
+               << (tail_call_site ? "tail" : "non-tail")
+               << " call site 0x" << std::hex << return_address.value << std::dec
+               << std::endl;
+#endif
 
        data_root<array> cache_entries(dpop(),this);
        fixnum index = untag_fixnum(dpop());
@@ -203,14 +218,15 @@ void *factor_vm::inline_cache_miss(cell return_address_)
                cell method = lookup_method(object.value(),methods.value());
 
                data_root<array> new_cache_entries(add_inline_cache_entry(
-                                                          cache_entries.value(),
-                                                          klass,
-                                                          method),this);
+                       cache_entries.value(),
+                       klass,
+                       method),this);
+
                xt = compile_inline_cache(index,
-                                         generic_word.value(),
-                                         methods.value(),
-                                         new_cache_entries.value(),
-                                         tail_call_site_p(return_address.value))->xt();
+                       generic_word.value(),
+                       methods.value(),
+                       new_cache_entries.value(),
+                       tail_call_site)->xt();
        }
 
        /* Install the new stub. */
@@ -224,9 +240,9 @@ void *factor_vm::inline_cache_miss(cell return_address_)
 
 #ifdef PIC_DEBUG
                std::cout << "Updated "
-                       << (tail_call_site_p(return_address.value) ? "tail" : "non-tail")
+                       << (tail_call_site ? "tail" : "non-tail")
                        << " call site 0x" << std::hex << return_address.value << std::dec
-                       << " with " << std::hex << (cell)xt << std::dec << "\n";
+                       << " with 0x" << std::hex << (cell)xt << std::dec << std::endl;
 #endif
        }
 
index c403428206cb530163891cf4b39fafb889e501b4..1aa70732719aeb5703308b24b900a22ed09532a3 100644 (file)
@@ -18,8 +18,8 @@ enum relocation_type {
        RT_HERE,
        /* current code block */
        RT_THIS,
-       /* immediate literal */
-       RT_IMMEDIATE,
+       /* data heap literal */
+       RT_LITERAL,
        /* address of ctx var */
        RT_CONTEXT,
        /* untagged fixnum literal */
@@ -103,7 +103,7 @@ struct relocation_entry {
                case RT_XT:
                case RT_XT_PIC:
                case RT_XT_PIC_TAIL:
-               case RT_IMMEDIATE:
+               case RT_LITERAL:
                case RT_HERE:
                case RT_UNTAGGED:
                case RT_THIS:
index f80607801a4f6d0858a30bdae7550cd77017b8eb..8d2f5abb9a1739c3408e36e98a1d000b1ee15419 100644 (file)
@@ -82,6 +82,27 @@ void jit::emit_with_parameter(cell code_template_, cell argument_) {
        emit(code_template.value());
 }
 
+bool jit::emit_subprimitive(cell word_, bool tail_call_p, bool stack_frame_p)
+{
+       data_root<word> word(word_,parent);
+       data_root<array> code_template(word->subprimitive,parent);
+       parameters.append(untag<array>(array_nth(code_template.untagged(),0)));
+       literals.append(untag<array>(array_nth(code_template.untagged(),1)));
+       emit(array_nth(code_template.untagged(),2));
+       if(array_capacity(code_template.untagged()) == 5)
+       {
+               if(tail_call_p)
+               {
+                       if(stack_frame_p) emit(parent->special_objects[JIT_EPILOG]);
+                       emit(array_nth(code_template.untagged(),4));
+                       return true;
+               }
+               else
+                       emit(array_nth(code_template.untagged(),3));
+       }
+       return false;
+}
+       
 void jit::emit_class_lookup(fixnum index, cell type)
 {
        emit_with_literal(parent->special_objects[PIC_LOAD],tag_fixnum(-index * sizeof(cell)));
index 8bc21296e77bdd3eeb2e12e61ae7dc305b2b1965..277aecb66d355a3ffac9a362f51a0ef3da9bbe6c 100644 (file)
@@ -43,19 +43,7 @@ struct jit {
                emit_with_literal(parent->special_objects[JIT_WORD_CALL],word);
        }
 
-       void word_special(cell 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_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));
-       }
+       bool emit_subprimitive(cell word_, bool tail_call_p, bool stack_frame_p);
 
        void emit_class_lookup(fixnum index, cell type);
 
index 55b5f9063db54d5a61fa92b820f3e128561c8e51..368f0f2c19d16a0e783161c43270dcfb4fd4063f 100644 (file)
@@ -42,7 +42,6 @@ enum special_object {
        JIT_PRIMITIVE,
        JIT_WORD_JUMP,
        JIT_WORD_CALL,
-       JIT_WORD_SPECIAL,
        JIT_IF_WORD,
        JIT_IF,
        JIT_EPILOG,
@@ -55,20 +54,18 @@ enum special_object {
        JIT_2DIP,
        JIT_3DIP_WORD,
        JIT_3DIP,
-       JIT_EXECUTE_WORD,
-       JIT_EXECUTE_JUMP,
-       JIT_EXECUTE_CALL,
+       JIT_EXECUTE,
        JIT_DECLARE_WORD,
 
-       /* Callback stub generation in callbacks.c */
-       CALLBACK_STUB = 45,
-       
        /* Incremented on every modify-code-heap call; invalidates call( inline
        caching */
-       REDEFINITION_COUNTER = 46,
+       REDEFINITION_COUNTER = 47,
 
+       /* Callback stub generation in callbacks.c */
+       CALLBACK_STUB = 48,
+       
        /* Polymorphic inline cache generation in inline_cache.c */
-       PIC_LOAD = 47,
+       PIC_LOAD = 49,
        PIC_TAG,
        PIC_TUPLE,
        PIC_CHECK_TAG,
index dc1ca8246db24328ee872acca8f175105b63c081..830ae7beb234455c845867a6772212e3a2a760d5 100644 (file)
@@ -143,9 +143,6 @@ const primitive_type primitives[] = {
        primitive_double_bits,
        primitive_bits_float,
        primitive_bits_double,
-       primitive_fixnum_add,
-       primitive_fixnum_subtract,
-       primitive_fixnum_multiply,
        primitive_fixnum_divint,
        primitive_fixnum_divmod,
        primitive_fixnum_shift,
@@ -279,8 +276,6 @@ const primitive_type primitives[] = {
        primitive_jit_compile,
        primitive_load_locals,
        primitive_check_datastack,
-       primitive_inline_cache_miss,
-       primitive_inline_cache_miss_tail,
        primitive_mega_cache_miss,
        primitive_lookup_method,
        primitive_reset_dispatch_stats,
index fa179b5dd8c75c9a2ef66529a93fe14ee90941a8..d10efb0ad5f5be27a4c65f53a5089134ceaa7fe0 100755 (executable)
@@ -82,18 +82,23 @@ bool quotation_jit::declare_p(cell i, cell length)
                && array_nth(elements.untagged(),i + 1) == parent->special_objects[JIT_DECLARE_WORD];
 }
 
+bool quotation_jit::word_stack_frame_p(cell obj)
+{
+       return to_boolean(untag<word>(obj)->subprimitive)
+               || obj == parent->special_objects[JIT_PRIMITIVE_WORD];
+}
+
 bool quotation_jit::stack_frame_p()
 {
        fixnum length = array_capacity(elements.untagged());
-       fixnum i;
 
-       for(i = 0; i < length - 1; i++)
+       for(fixnum i = 0; i < length; i++)
        {
                cell obj = array_nth(elements.untagged(),i);
                switch(tagged<object>(obj).type())
                {
                case WORD_TYPE:
-                       if(!to_boolean(untag<word>(obj)->subprimitive))
+                       if(i != length - 1 || word_stack_frame_p(obj))
                                return true;
                        break;
                case QUOTATION_TYPE:
@@ -153,49 +158,22 @@ void quotation_jit::iterate_quotation()
                switch(obj.type())
                {
                case WORD_TYPE:
-                       /* Intrinsics */
+                       /* Sub-primitives */
                        if(to_boolean(obj.as<word>()->subprimitive))
-                               emit_subprimitive(obj.value());
-                       /* The (execute) primitive is special-cased */
-                       else if(obj.value() == parent->special_objects[JIT_EXECUTE_WORD])
                        {
-                               if(i == length - 1)
-                               {
-                                       if(stack_frame) emit(parent->special_objects[JIT_EPILOG]);
-                                       tail_call = true;
-                                       emit(parent->special_objects[JIT_EXECUTE_JUMP]);
-                               }
-                               else
-                                       emit(parent->special_objects[JIT_EXECUTE_CALL]);
+                               tail_call = emit_subprimitive(obj.value(), /* word */
+                                       i == length - 1, /* tail_call_p */
+                                       stack_frame); /* stack_frame_p */
                        }
                        /* Everything else */
-                       else
+                       else if(i == length - 1)
                        {
-                               if(i == length - 1)
-                               {
-                                       if(stack_frame) emit(parent->special_objects[JIT_EPILOG]);
-                                       tail_call = true;
-                                       /* Inline cache misses are special-cased.
-                                          The calling convention for tail
-                                          calls stores the address of the next
-                                          instruction in a register. However,
-                                          PIC miss stubs themselves tail-call
-                                          the inline cache miss primitive, and
-                                          we don't want to clobber the saved
-                                          address. */
-                                       if(obj.value() == parent->special_objects[PIC_MISS_WORD]
-                                          || obj.value() == parent->special_objects[PIC_MISS_TAIL_WORD])
-                                       {
-                                               word_special(obj.value());
-                                       }
-                                       else
-                                       {
-                                               word_jump(obj.value());
-                                       }
-                               }
-                               else
-                                       word_call(obj.value());
+                               if(stack_frame) emit(parent->special_objects[JIT_EPILOG]);
+                               tail_call = true;
+                               word_jump(obj.value());
                        }
+                       else
+                               word_call(obj.value());
                        break;
                case WRAPPER_TYPE:
                        push(obj.as<wrapper>()->object);
@@ -209,8 +187,6 @@ void quotation_jit::iterate_quotation()
                                emit(parent->special_objects[JIT_PRIMITIVE]);
 
                                i++;
-
-                               tail_call = true;
                        }
                        else
                                push(obj.value());
@@ -257,12 +233,13 @@ void quotation_jit::iterate_quotation()
                        /* Method dispatch */
                        if(mega_lookup_p(i,length))
                        {
+                               if(stack_frame) emit(parent->special_objects[JIT_EPILOG]);
+                               tail_call = true;
                                emit_mega_cache_lookup(
                                        array_nth(elements.untagged(),i),
                                        untag_fixnum(array_nth(elements.untagged(),i + 1)),
                                        array_nth(elements.untagged(),i + 2));
                                i += 3;
-                               tail_call = true;
                        }
                        /* Non-optimizing compiler ignores declarations */
                        else if(declare_p(i,length))
@@ -280,8 +257,7 @@ void quotation_jit::iterate_quotation()
        {
                set_position(length);
 
-               if(stack_frame)
-                       emit(parent->special_objects[JIT_EPILOG]);
+               if(stack_frame) emit(parent->special_objects[JIT_EPILOG]);
                emit(parent->special_objects[JIT_RETURN]);
        }
 }
@@ -342,37 +318,6 @@ void factor_vm::primitive_quotation_xt()
        drepl(allot_cell((cell)quot->xt));
 }
 
-/* Compile a word definition with the non-optimizing compiler. Allocates memory */
-void factor_vm::jit_compile_word(cell word_, cell def_, bool relocating)
-{
-       data_root<word> word(word_,this);
-       data_root<quotation> def(def_,this);
-
-       code_block *compiled = jit_compile_quot(word.value(),def.value(),relocating);
-       word->code = compiled;
-
-       if(to_boolean(word->pic_def)) jit_compile_quot(word->pic_def,relocating);
-       if(to_boolean(word->pic_tail_def)) jit_compile_quot(word->pic_tail_def,relocating);
-}
-
-void factor_vm::compile_all_words()
-{
-       data_root<array> words(find_all_words(),this);
-
-       cell i;
-       cell length = array_capacity(words.untagged());
-       for(i = 0; i < length; i++)
-       {
-               data_root<word> word(array_nth(words.untagged(),i),this);
-
-               if(!word->code || !word->code->optimized_p())
-                       jit_compile_word(word.value(),word->def,false);
-
-               update_word_xt(word.untagged());
-
-       }
-}
-
 /* Allocates memory */
 fixnum factor_vm::quot_code_offset_to_scan(cell quot_, cell offset)
 {
index 0735b5a7b859ed3561254bd1d6bc877328cc0785..50e7667b4ec957955b2bb2050035611808971e69 100755 (executable)
@@ -22,6 +22,7 @@ struct quotation_jit : public jit {
        bool fast_3dip_p(cell i, cell length);
        bool mega_lookup_p(cell i, cell length);
        bool declare_p(cell i, cell length);
+       bool word_stack_frame_p(cell obj);
        bool stack_frame_p();
        void iterate_quotation();
 };
index a7684d106664e95aedc435d03f32cb8be78f2769..0ab9cc171d703f36e0e4dee65f09c892f87bc822 100644 (file)
@@ -191,7 +191,7 @@ struct literal_references_visitor {
 
        void operator()(instruction_operand op)
        {
-               if(op.rel_type() == RT_IMMEDIATE)
+               if(op.rel_type() == RT_LITERAL)
                        op.store_value(visitor->visit_pointer(op.load_value()));
        }
 };
index 2d78bae709846629d77b9a20e9f6bc2d459bacfe..31f013eae4de3a4d548b1a9a9d9438329d5d3a07 100755 (executable)
--- a/vm/vm.hpp
+++ b/vm/vm.hpp
@@ -232,7 +232,6 @@ struct factor_vm
        void end_scan();
        cell instances(cell type);
        void primitive_all_instances();
-       cell find_all_words();
 
        template<typename Generation, typename Iterator>
        inline void each_object(Generation *gen, Iterator &iterator)
@@ -398,6 +397,9 @@ struct factor_vm
        void update_word_xt(word *w_);
        void primitive_optimized_p();
        void primitive_wrapper();
+       void jit_compile_word(cell word_, cell def_, bool relocating);
+       cell find_all_words();
+       void compile_all_words();
 
        //math
        void primitive_bignum_to_fixnum();
@@ -562,7 +564,7 @@ struct factor_vm
        void check_frame(stack_frame *frame);
        callstack *allot_callstack(cell size);
        stack_frame *fix_callstack_top(stack_frame *top, stack_frame *bottom);
-       stack_frame *capture_start();
+       stack_frame *second_from_top_stack_frame();
        void primitive_callstack();
        void primitive_set_callstack();
        code_block *frame_code(stack_frame *frame);
@@ -605,8 +607,6 @@ struct factor_vm
        void set_quot_xt(quotation *quot, code_block *code);
        code_block *jit_compile_quot(cell owner_, cell quot_, bool relocating);
        void jit_compile_quot(cell quot_, bool relocating);
-       void jit_compile_word(cell word_, cell def_, bool relocating);
-       void compile_all_words();
        fixnum quot_code_offset_to_scan(cell quot_, cell offset);
        cell lazy_jit_compile_impl(cell quot_, stack_frame *stack);
        void primitive_quot_compiled_p();
index e3e5c070af087158ab478b83759442b310f807fb..347076a52952827a067a8c159a50b4c2ac4286a3 100644 (file)
@@ -3,6 +3,41 @@
 namespace factor
 {
 
+/* Compile a word definition with the non-optimizing compiler. Allocates memory */
+void factor_vm::jit_compile_word(cell word_, cell def_, bool relocating)
+{
+       data_root<word> word(word_,this);
+       data_root<quotation> def(def_,this);
+
+       code_block *compiled = jit_compile_quot(word.value(),def.value(),relocating);
+       word->code = compiled;
+
+       if(to_boolean(word->pic_def)) jit_compile_quot(word->pic_def,relocating);
+       if(to_boolean(word->pic_tail_def)) jit_compile_quot(word->pic_tail_def,relocating);
+}
+
+cell factor_vm::find_all_words()
+{
+       return instances(WORD_TYPE);
+}
+
+void factor_vm::compile_all_words()
+{
+       data_root<array> words(find_all_words(),this);
+
+       cell length = array_capacity(words.untagged());
+       for(cell i = 0; i < length; i++)
+       {
+               data_root<word> word(array_nth(words.untagged(),i),this);
+
+               if(!word->code || !word->code->optimized_p())
+                       jit_compile_word(word.value(),word->def,false);
+
+               update_word_xt(word.untagged());
+
+       }
+}
+
 word *factor_vm::allot_word(cell name_, cell vocab_, cell hashcode_)
 {
        data_root<object> vocab(vocab_,this);