]> gitweb.factorcode.org Git - factor.git/commitdiff
vm: move c_to_factor, lazy_jit_compile_impl, throw_impl, set_callstack assembly routi...
authorSlava Pestov <slava@slava-pestovs-macbook-pro.local>
Wed, 6 Jan 2010 02:47:36 +0000 (15:47 +1300)
committerSlava Pestov <slava@slava-pestovs-macbook-pro.local>
Wed, 6 Jan 2010 02:47:36 +0000 (15:47 +1300)
33 files changed:
Makefile
basis/bootstrap/image/image.factor
basis/compiler/constants/constants.factor
basis/cpu/architecture/architecture.factor
basis/cpu/ppc/bootstrap.factor
basis/cpu/x86/32/32.factor
basis/cpu/x86/32/bootstrap.factor
basis/cpu/x86/64/64.factor
basis/cpu/x86/64/bootstrap.factor
basis/cpu/x86/assembler/assembler.factor
basis/cpu/x86/bootstrap.factor
basis/cpu/x86/x86.factor
basis/prettyprint/prettyprint.factor
basis/vm/vm.factor
core/bootstrap/primitives.factor
vm/callstack.cpp
vm/code_block_visitor.hpp
vm/cpu-x86.64.S
vm/cpu-x86.S
vm/cpu-x86.hpp
vm/entry_points.cpp [new file with mode: 0644]
vm/entry_points.hpp [new file with mode: 0644]
vm/errors.cpp
vm/factor.cpp
vm/master.hpp
vm/objects.hpp
vm/os-genunix.cpp
vm/os-macosx.mm
vm/os-windows-nt.cpp
vm/primitives.cpp
vm/quotations.cpp
vm/vm.cpp
vm/vm.hpp

index 80621d8f0a96c2649d23efa03d204ba0c82af301..772f3f98754db42759372294788e750c3884b648 100755 (executable)
--- a/Makefile
+++ b/Makefile
@@ -47,6 +47,7 @@ DLL_OBJS = $(PLAF_DLL_OBJS) \
        vm/data_heap_checker.o \
        vm/debug.o \
        vm/dispatch.o \
+       vm/entry_points.o \
        vm/errors.o \
        vm/factor.o \
        vm/free_list.o \
index bf2d14e3aabde68b6c553720f82794b2ad7ab3c3..1565373cab79403d493ed3007d9b87af29388131 100644 (file)
@@ -155,7 +155,7 @@ 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 -- )
+: define-combinator-primitive ( quot non-tail-quot tail-quot word -- )
     [
         [ make-jit ]
         [ make-jit 2nip ]
@@ -202,6 +202,10 @@ USERENV: jit-3dip 39
 USERENV: jit-execute 40
 USERENV: jit-declare-word 41
 
+USERENV: c-to-factor-word 42
+USERENV: lazy-jit-compile-word 43
+USERENV: unwind-native-frames-word 44
+
 USERENV: callback-stub 48
 
 ! PIC stubs
@@ -534,11 +538,14 @@ M: quotation '
     \ dip jit-dip-word set
     \ 2dip jit-2dip-word set
     \ 3dip jit-3dip-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
-    \ mega-cache-miss mega-miss-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
+    \ mega-cache-miss mega-miss-word set
     \ declare jit-declare-word set
+    \ c-to-factor c-to-factor-word set
+    \ lazy-jit-compile lazy-jit-compile-word set
+    \ unwind-native-frames unwind-native-frames-word set
     [ undefined ] undefined-quot set ;
 
 : emit-userenvs ( -- )
index 83b50b61f4dc21d1743ffa317baca4abf14349aa..bc7f037b4a739402e9d088d1a56bb0b2e1f587b0 100644 (file)
@@ -25,6 +25,8 @@ CONSTANT: deck-bits 18
 : word-code-offset ( -- n ) 11 \ word type-number slot-offset ; inline
 : array-start-offset ( -- n ) 2 array type-number slot-offset ; inline
 : compiled-header-size ( -- n ) 4 bootstrap-cells ; inline
+: callstack-length-offset ( -- n ) 1 \ callstack type-number slot-offset ; inline
+: callstack-top-offset ( -- n ) 2 \ callstack type-number slot-offset ; inline
 
 ! Relocation classes
 CONSTANT: rc-absolute-cell 0
index 5127b56acffb369fd7898949c08c0a07a6e8f523..03090dc4b514138cb6561f6955677a899b9d34c7 100644 (file)
@@ -550,7 +550,7 @@ HOOK: %save-param-reg cpu ( stack reg rep -- )
 
 HOOK: %load-param-reg cpu ( stack reg rep -- )
 
-HOOK: %load-context cpu ( temp1 temp2 -- )
+HOOK: %restore-context cpu ( temp1 temp2 -- )
 
 HOOK: %save-context cpu ( temp1 temp2 -- )
 
index a5267b898b76a9b6b4b55c991fb41413123b291a..837acd0ea1bb3ba91d9044b8d491218d7708f061 100644 (file)
@@ -215,12 +215,12 @@ CONSTANT: vm-reg 15
 [ jit-load-return-address jit-inline-cache-miss ]\r
 [ 3 MTLR BLRL ]\r
 [ 3 MTCTR BCTR ]\r
-\ inline-cache-miss define-sub-primitive*\r
+\ inline-cache-miss define-combinator-primitive\r
 \r
 [ jit-inline-cache-miss ]\r
 [ 3 MTLR BLRL ]\r
 [ 3 MTCTR BCTR ]\r
-\ inline-cache-miss-tail define-sub-primitive*\r
+\ inline-cache-miss-tail define-combinator-primitive\r
 \r
 ! ! ! Megamorphic caches\r
 \r
@@ -271,7 +271,7 @@ CONSTANT: vm-reg 15
     5 3 quot-xt-offset LWZ\r
 ]\r
 [ 5 MTLR BLRL ]\r
-[ 5 MTCTR BCTR ] \ (call) define-sub-primitive*\r
+[ 5 MTCTR BCTR ] \ (call) define-combinator-primitive\r
 \r
 [\r
     3 ds-reg 0 LWZ\r
@@ -279,7 +279,7 @@ CONSTANT: vm-reg 15
     4 3 word-xt-offset LWZ\r
 ]\r
 [ 4 MTLR BLRL ]\r
-[ 4 MTCTR BCTR ] \ (execute) define-sub-primitive*\r
+[ 4 MTCTR BCTR ] \ (execute) define-combinator-primitive\r
 \r
 [\r
     3 ds-reg 0 LWZ\r
index 8b44b6580973ad491287ac36f15be47f85424023..e741012bc4360c951020438569acbb7ee1c03650 100644 (file)
@@ -235,7 +235,7 @@ M: x86.32 %alien-indirect ( -- )
     EBP CALL ;
 
 M: x86.32 %alien-callback ( quot -- )
-    EAX EDX %load-context
+    EAX EDX %restore-context
     EAX swap %load-reference
     EDX %mov-vm-ptr
     EAX quot-xt-offset [+] CALL
index 580db119465c480d7ba90d646d40724a008173e5..9c57804e3a8930918c37790699b7e982df5e8608 100644 (file)
@@ -77,7 +77,7 @@ IN: bootstrap.x86
 ]
 [ EAX quot-xt-offset [+] CALL ]
 [ EAX quot-xt-offset [+] JMP ]
-\ (call) define-sub-primitive*
+\ (call) define-combinator-primitive
 
 ! Inline cache miss entry points
 : jit-load-return-address ( -- )
@@ -96,12 +96,12 @@ IN: bootstrap.x86
 [ jit-load-return-address jit-inline-cache-miss ]
 [ EAX CALL ]
 [ EAX JMP ]
-\ inline-cache-miss define-sub-primitive*
+\ inline-cache-miss define-combinator-primitive
 
 [ jit-inline-cache-miss ]
 [ EAX CALL ]
 [ EAX JMP ]
-\ inline-cache-miss-tail define-sub-primitive*
+\ inline-cache-miss-tail define-combinator-primitive
 
 ! Overflowing fixnum arithmetic
 : jit-overflow ( insn func -- )
index 5fc6ae8c169aa64238f68a8bf77109eb27f7f690..071f45d1275c79461df3c6c13c9b2d204b933829 100644 (file)
@@ -223,7 +223,7 @@ M: x86.64 %alien-indirect ( -- )
     RBP CALL ;
 
 M: x86.64 %alien-callback ( quot -- )
-    param-reg-0 param-reg-1 %load-context
+    param-reg-0 param-reg-1 %restore-context
     param-reg-0 swap %load-reference
     param-reg-1 %mov-vm-ptr
     param-reg-0 quot-xt-offset [+] CALL
index a1bdcbd1ff9636f4c3ebeca3ee937171fee404fd..4c059141af875689bd048a47d1ac6b553f1c4780 100644 (file)
@@ -1,9 +1,10 @@
-! Copyright (C) 2007, 2009 Slava Pestov.
+! Copyright (C) 2007, 2010 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 ;
+FROM: vm => context-field-offset vm-field-offset ;
 IN: bootstrap.x86
 
 8 \ cell set
@@ -15,9 +16,12 @@ IN: bootstrap.x86
 : temp1 ( -- reg ) RSI ;
 : temp2 ( -- reg ) RDX ;
 : temp3 ( -- reg ) RBX ;
+: return-reg ( -- reg ) RAX ;
 : safe-reg ( -- reg ) RAX ;
 : stack-reg ( -- reg ) RSP ;
 : frame-reg ( -- reg ) RBP ;
+: vm-reg ( -- reg ) R12 ;
+: ctx-reg ( -- reg ) R13 ;
 : ds-reg ( -- reg ) R14 ;
 : rs-reg ( -- reg ) R15 ;
 : fixnum>slot@ ( -- ) temp0 1 SAR ;
@@ -25,60 +29,114 @@ IN: bootstrap.x86
 
 [
     ! load XT
-    RDI 0 MOV rc-absolute-cell rt-this jit-rel
+    safe-reg 0 MOV rc-absolute-cell rt-this jit-rel
     ! save stack frame size
     stack-frame-size PUSH
     ! push XT
-    RDI PUSH
+    safe-reg PUSH
     ! alignment
     RSP stack-frame-size 3 bootstrap-cells - SUB
 ] jit-prolog jit-define
 
 : jit-load-vm ( -- )
-    RBP 0 MOV 0 rc-absolute-cell jit-vm ;
+    vm-reg 0 MOV 0 rc-absolute-cell jit-vm ;
+
+: jit-load-context ( -- )
+    ! VM pointer must be in vm-reg already
+    ctx-reg vm-reg "ctx" vm-field-offset [+] MOV ;
 
 : jit-save-context ( -- )
-    ! VM pointer must be in RBP already
-    RCX RBP [] MOV
-    ! save ctx->callstack_top
-    RAX RSP -8 [+] LEA
-    RCX [] RAX MOV
-    ! save ctx->datastack
-    RCX 16 [+] ds-reg MOV
-    ! save ctx->retainstack
-    RCX 24 [+] rs-reg MOV ;
+    jit-load-context
+    safe-reg RSP -8 [+] LEA
+    ctx-reg "callstack-top" context-field-offset [+] safe-reg MOV
+    ctx-reg "datastack" context-field-offset [+] ds-reg MOV
+    ctx-reg "retainstack" context-field-offset [+] rs-reg MOV ;
 
 : jit-restore-context ( -- )
-    ! VM pointer must be in EBP already
-    RCX RBP [] MOV
-    ! restore ctx->datastack
-    ds-reg RCX 16 [+] MOV
-    ! restore ctx->retainstack
-    rs-reg RCX 24 [+] MOV ;
+    jit-load-context
+    ds-reg ctx-reg "datastack" context-field-offset [+] MOV
+    rs-reg ctx-reg "retainstack" context-field-offset [+] MOV ;
 
 [
     jit-load-vm
-    ! save ds, rs registers
     jit-save-context
     ! call the primitive
-    arg1 RBP MOV
+    arg1 vm-reg MOV
     RAX 0 MOV rc-absolute-cell rt-primitive jit-rel
     RAX CALL
-    ! restore ds, rs registers
     jit-restore-context
 ] jit-primitive jit-define
 
 [
-    ! load from stack
+    jit-load-vm
+    jit-restore-context
+    ! save ctx->callstack_bottom
+    safe-reg stack-reg stack-frame-size bootstrap-cell - [+] LEA
+    ctx-reg "callstack-bottom" context-field-offset [+] safe-reg MOV
+    ! call the quotation
+    arg1 quot-xt-offset [+] CALL
+    jit-save-context
+] \ c-to-factor define-sub-primitive
+
+[
     arg1 ds-reg [] MOV
-    ! pop stack
     ds-reg bootstrap-cell SUB
-    ! load 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*
+\ (call) define-combinator-primitive
+
+[
+    ! Clear x87 stack, but preserve rounding mode and exception flags
+    RSP 2 SUB
+    RSP [] FNSTCW
+    FNINIT
+    RSP [] FLDCW
+
+    ! Unwind stack frames
+    RSP arg2 MOV
+
+    ! Load ds and rs registers
+    jit-load-vm
+    jit-restore-context
+
+    ! Call quotation
+    arg1 quot-xt-offset [+] JMP
+] \ unwind-native-frames define-sub-primitive
+
+[
+    ! Load callstack object
+    arg4 ds-reg [] MOV
+    ds-reg bootstrap-cell SUB
+    ! Get ctx->callstack_bottom
+    jit-load-vm
+    jit-load-context
+    arg1 ctx-reg "callstack-bottom" context-field-offset [+] MOV
+    ! Get top of callstack object -- 'src' for memcpy
+    arg2 arg4 callstack-top-offset [+] LEA
+    ! Get callstack length, in bytes --- 'len' for memcpy
+    arg3 arg4 callstack-length-offset [+] MOV
+    arg3 tag-bits get SHR
+    ! Compute new stack pointer -- 'dst' for memcpy
+    arg1 arg3 SUB
+    RSP arg1 MOV
+    ! Call memcpy; arguments are now in the correct registers
+    safe-reg 0 MOV "memcpy" f rc-absolute-cell jit-dlsym
+    safe-reg CALL
+    ! Return with new callstack
+    0 RET
+] \ set-callstack define-sub-primitive
+
+[
+    jit-load-vm
+    jit-save-context
+    arg2 vm-reg MOV
+    safe-reg 0 MOV "lazy_jit_compile" f rc-absolute-cell jit-dlsym
+    safe-reg CALL
+]
+[ return-reg quot-xt-offset [+] CALL ]
+[ return-reg quot-xt-offset [+] JMP ]
+\ lazy-jit-compile define-combinator-primitive
 
 ! Inline cache miss entry points
 : jit-load-return-address ( -- )
@@ -90,7 +148,7 @@ IN: bootstrap.x86
     jit-load-vm
     jit-save-context
     arg1 RBX MOV
-    arg2 RBP MOV
+    arg2 vm-reg MOV
     RAX 0 MOV "inline_cache_miss" f rc-absolute-cell jit-dlsym
     RAX CALL
     jit-restore-context ;
@@ -98,12 +156,12 @@ IN: bootstrap.x86
 [ jit-load-return-address jit-inline-cache-miss ]
 [ RAX CALL ]
 [ RAX JMP ]
-\ inline-cache-miss define-sub-primitive*
+\ inline-cache-miss define-combinator-primitive
 
 [ jit-inline-cache-miss ]
 [ RAX CALL ]
 [ RAX JMP ]
-\ inline-cache-miss-tail define-sub-primitive*
+\ inline-cache-miss-tail define-combinator-primitive
 
 ! Overflowing fixnum arithmetic
 : jit-overflow ( insn func -- )
@@ -117,7 +175,7 @@ IN: bootstrap.x86
     ds-reg [] arg3 MOV
     [ JNO ]
     [
-        arg3 RBP MOV
+        arg3 vm-reg MOV
         RAX 0 MOV f rc-absolute-cell jit-dlsym
         RAX CALL
     ]
@@ -142,7 +200,7 @@ IN: bootstrap.x86
         arg1 RCX MOV
         arg1 tag-bits get SAR
         arg2 RBX MOV
-        arg3 RBP MOV
+        arg3 vm-reg MOV
         RAX 0 MOV "overflow_fixnum_multiply" f rc-absolute-cell jit-dlsym
         RAX CALL
     ]
index 57738ce4bad7553057950781670998b669327e6c..fc000ced23df399bf0a3e67a8792fdc84c92c528 100644 (file)
@@ -385,6 +385,11 @@ PRIVATE>
 : FLDS ( operand -- ) { BIN: 000 f HEX: d9 } 1-operand ;
 : FLDL ( operand -- ) { BIN: 000 f HEX: dd } 1-operand ;
 
+: FNSTCW ( operand -- ) { BIN: 111 f HEX: d9 } 1-operand ;
+: FLDCW ( operand -- ) { BIN: 101 f HEX: d9 } 1-operand ;
+
+: FNINIT ( -- ) HEX: db , HEX: e3 , ;
+
 ! SSE multimedia instructions
 
 <PRIVATE
index f0e869fe5b9c7a168a09f645117f11fa13f5fd55..13731692113d7ea998a9ef5a6377b5254e66b9bb 100644 (file)
@@ -169,7 +169,7 @@ big-endian off
 ]
 [ temp0 word-xt-offset [+] CALL ]
 [ temp0 word-xt-offset [+] JMP ]
-\ (execute) define-sub-primitive*
+\ (execute) define-combinator-primitive
 
 [
     temp0 ds-reg [] MOV
index 69a0f39945edc538ae3eeecfb9ee9acb308f622b..a14e2468ad5d42ce6f22bd36a27933348407de1c 100644 (file)
@@ -1410,18 +1410,15 @@ M:: x86 %reload ( dst rep src -- ) dst src rep %copy ;
 
 M: x86 %loop-entry 16 code-alignment [ NOP ] times ;
 
-M:: x86 %load-context ( temp1 temp2 -- )
+M:: x86 %restore-context ( temp1 temp2 -- )
     #! Load Factor stack pointers on entry from C to Factor.
     #! Also save callstack bottom!
     temp1 "ctx" %vm-field-ptr
     temp1 temp1 [] MOV
-    ! callstack_bottom
     temp2 stack-reg stack-frame get total-size>> cell - [+] LEA
-    temp1 1 cells [+] temp2 MOV
-    ! datastack
-    ds-reg temp1 2 cells [+] MOV
-    ! retainstack
-    rs-reg temp1 3 cells [+] MOV ;
+    temp1 "callstack-bottom" context-field-offset [+] temp2 MOV
+    ds-reg temp1 "datastack" context-field-offset [+] MOV
+    rs-reg temp1 "retainstack" context-field-offset [+] MOV ;
 
 M:: x86 %save-context ( temp1 temp2 -- )
     #! Save Factor stack pointers in case the C code calls a
@@ -1429,13 +1426,10 @@ M:: x86 %save-context ( temp1 temp2 -- )
     #! all roots.
     temp1 "ctx" %vm-field-ptr
     temp1 temp1 [] MOV
-    ! callstack_top
     temp2 stack-reg cell neg [+] LEA
-    temp1 [] temp2 MOV
-    ! datastack
-    temp1 2 cells [+] ds-reg MOV
-    ! retainstack
-    temp1 3 cells [+] rs-reg MOV ;
+    temp1 "callstack-top" context-field-offset [+] temp2 MOV
+    temp1 "datastack" context-field-offset [+] ds-reg MOV
+    temp1 "retainstack" context-field-offset [+] rs-reg MOV ;
 
 M: x86 value-struct? drop t ;
 
index 6cff3992019b36f43cac5645b7275a3c4091c9a4..65d25f1812f5d386a121e92b8cb5ab522e1fd2dc 100644 (file)
@@ -73,8 +73,8 @@ SYMBOL: ->
 
 : remove-breakpoints ( quot pos -- quot' )
     over quotation? [
-        1 + cut [ (remove-breakpoints) ] bi@
-        [ -> ] glue 
+        1 + short cut [ (remove-breakpoints) ] bi@
+        [ -> ] glue
     ] [
         drop
     ] if ;
index 278296c4d049b3b98da5429887f5af0951f0c9bb..20428c40f3b5dbea4ea518769cd5bfdaa2d405a5 100644 (file)
@@ -9,7 +9,7 @@ STRUCT: context
 { callstack-top void* }
 { callstack-bottom void* }
 { datastack cell }
-{ callstack cell }
+{ retainstack cell }
 { magic-frame void* }
 { datastack-region void* }
 { retainstack-region void* }
index ac1f4fad69a6744389701c9530940f87d0b85741..a0b278c7a4f3ece423e077144daac38cad7ce2b3 100644 (file)
@@ -312,27 +312,9 @@ tuple
     [ create dup 1quotation ] dip define-declared ;
 
 {
-    { "(execute)" "kernel.private" (( word -- )) }
-    { "(call)" "kernel.private" (( quot -- )) }
-    { "both-fixnums?" "math.private" (( x y -- ? )) }
-    { "fixnum+fast" "math.private" (( x y -- z )) }
-    { "fixnum-fast" "math.private" (( x y -- z )) }
-    { "fixnum*fast" "math.private" (( x y -- z )) }
-    { "fixnum-bitand" "math.private" (( x y -- z )) }
-    { "fixnum-bitor" "math.private" (( x y -- z )) }
-    { "fixnum-bitxor" "math.private" (( x y -- z )) }
-    { "fixnum-bitnot" "math.private" (( x -- y )) }
-    { "fixnum-mod" "math.private" (( x y -- z )) }
-    { "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 -- ? )) }
-    { "fixnum>=" "math.private" (( x y -- ? )) }
+    { "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 -- )) }
     { "drop" "kernel" (( x -- )) }
     { "2drop" "kernel" (( x y -- )) }
     { "3drop" "kernel" (( x y z -- )) }
@@ -350,13 +332,35 @@ tuple
     { "swap" "kernel" (( x y -- y x )) }
     { "eq?" "kernel" (( obj1 obj2 -- ? )) }
     { "tag" "kernel.private" (( object -- n )) }
+    { "(execute)" "kernel.private" (( word -- )) }
+    { "(call)" "kernel.private" (( quot -- )) }
+    { "unwind-native-frames" "kernel.private" (( -- )) }
+    { "set-callstack" "kernel.private" (( cs -- * )) }
+    { "lazy-jit-compile" "kernel.private" (( -- )) }
+    { "c-to-factor" "kernel.private" (( -- )) }
     { "slot" "slots.private" (( obj m -- value )) }
     { "get-local" "locals.backend" (( n -- obj )) }
     { "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 -- )) }
+    { "both-fixnums?" "math.private" (( x y -- ? )) }
+    { "fixnum+fast" "math.private" (( x y -- z )) }
+    { "fixnum-fast" "math.private" (( x y -- z )) }
+    { "fixnum*fast" "math.private" (( x y -- z )) }
+    { "fixnum-bitand" "math.private" (( x y -- z )) }
+    { "fixnum-bitor" "math.private" (( x y -- z )) }
+    { "fixnum-bitxor" "math.private" (( x y -- z )) }
+    { "fixnum-bitnot" "math.private" (( x -- y )) }
+    { "fixnum-mod" "math.private" (( x y -- z )) }
+    { "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 -- ? )) }
+    { "fixnum>=" "math.private" (( x y -- ? )) }
 } [ first3 make-sub-primitive ] each
 
 ! Primitive words
@@ -428,9 +432,8 @@ tuple
     { "datastack" "kernel" (( -- ds )) }
     { "retainstack" "kernel" (( -- rs )) }
     { "callstack" "kernel" (( -- cs )) }
-    { "set-datastack" "kernel" (( ds -- )) }
-    { "set-retainstack" "kernel" (( rs -- )) }
-    { "set-callstack" "kernel" (( cs -- * )) }
+    { "set-datastack" "kernel.private" (( ds -- )) }
+    { "set-retainstack" "kernel.private" (( rs -- )) }
     { "(exit)" "system" (( n -- )) }
     { "data-room" "memory" (( -- data-room )) }
     { "code-room" "memory" (( -- code-room )) }
index 714a4585c3f94c1e61aa60b511c8b4e2e188b28a..b6742534b90a31ee91df7431bd2dab1f6c08f22d 100755 (executable)
@@ -60,20 +60,6 @@ void factor_vm::primitive_callstack()
        ctx->push(tag<callstack>(stack));
 }
 
-void factor_vm::primitive_set_callstack()
-{
-       callstack *stack = untag_check<callstack>(ctx->pop());
-
-       set_callstack(this,
-               ctx->callstack_bottom,
-               stack->top(),
-               untag_fixnum(stack->length),
-               memcpy);
-
-       /* We cannot return here ... */
-       critical_error("Bug in set_callstack()",0);
-}
-
 code_block *factor_vm::frame_code(stack_frame *frame)
 {
        check_frame(frame);
index 0624adb268b5fe0545d43004f6f133f25c91b4ac..dce82843f810a434114428e64d16933ce1d98411 100644 (file)
@@ -72,8 +72,6 @@ void code_block_visitor<Visitor>::visit_object_code_block(object *obj)
                        quotation *q = (quotation *)obj;
                        if(q->code)
                                parent->set_quot_xt(q,visitor(q->code));
-                       else
-                               q->xt = (void *)lazy_jit_compile_impl;
                        break;
                }
        case CALLSTACK_TYPE:
index 37a6507206060fd72912dba4d5cf12e073aa1e0c..a65b0d67e756d8b358a12d062ea9903b6e0ee76b 100644 (file)
@@ -1,180 +1,5 @@
 #include "asm.h"
 
-#define DS_REG %r14
-#define RS_REG %r15
-#define RETURN_REG %rax
-
-#define QUOT_XT_OFFSET 28
-
-#ifdef WINDOWS
-
-       #define ARG0 %rcx
-       #define ARG1 %rdx
-       #define ARG2 %r8
-       #define ARG3 %r9
-
-       #define PUSH_NONVOLATILE \
-               push %r15 ; \
-               push %r14 ; \
-               push %r12 ; \
-               push %r13 ; \
-               push %rdi ; \
-               push %rsi ; \
-               push %rbx ; \
-               push %rbp
-
-       #define POP_NONVOLATILE \
-               pop %rbp ; \
-               pop %rbx ; \
-               pop %rsi ; \
-               pop %rdi ; \
-               pop %r13 ; \
-               pop %r12 ; \
-               pop %r14 ; \
-               pop %r15
-
-#else
-
-       #define ARG0 %rdi
-       #define ARG1 %rsi
-       #define ARG2 %rdx
-       #define ARG3 %rcx
-
-       #define PUSH_NONVOLATILE \
-               push %rbx ; \
-               push %rbp ; \
-               push %r12 ; \
-               push %r13 ; \
-               push %r14 ; \
-               push %r15
-
-       #define POP_NONVOLATILE \
-               pop %r15 ; \
-               pop %r14 ; \
-               pop %r13 ; \
-               pop %r12 ; \
-               pop %rbp ; \
-               pop %rbx
-
-#endif
-
-DEF(void,c_to_factor,(cell quot, void *vm)):
-       PUSH_NONVOLATILE
-
-       /* Save old stack pointer and align */
-       mov %rsp,%rbp
-       and $-16,%rsp
-       push %rbp
-
-       /* Set up stack frame for the call to the boot quotation */
-       push ARG0
-       push ARG1
-
-       /* Create register shadow area (required for Win64 only) */
-       sub $40,%rsp
-
-       /* Load context */
-       mov (ARG1),ARG2
-
-       /* Save ctx->callstack_bottom */
-       lea -8(%rsp),ARG3
-       mov ARG3,8(ARG2)
-
-       /* Load ctx->datastack */
-       mov 16(ARG2),DS_REG
-
-       /* Load ctx->retainstack */
-       mov 24(ARG2),RS_REG
-
-       /* Call quot-xt */
-       call *QUOT_XT_OFFSET(ARG0)
-
-       /* Tear down register shadow area */
-       add $40,%rsp
-
-       /* Tear down stack frame for the call to the boot quotation */
-       pop ARG1
-       pop ARG0
-
-       /* Undo stack alignment */
-       pop %rbp
-       mov %rbp,%rsp
-
-       /* Load context */
-       mov (ARG1),ARG2
-
-       /* Save ctx->datastack */
-       mov DS_REG,16(ARG2)
-
-       /* Save ctx->retainstack */
-       mov RS_REG,24(ARG2)
-
-       POP_NONVOLATILE
-       ret
-
-DEF(void,set_callstack,(void *vm, stack_frame *to, stack_frame *from, cell length)):
-       /* save VM pointer in non-volatile register */
-       mov ARG0,%rbp
-
-       /* compute new stack pointer */ 
-       sub ARG3,ARG1
-       mov ARG1,%rsp
-
-       /* call memcpy */
-       mov ARG1,ARG0
-       mov ARG2,ARG1
-       mov ARG3,ARG2
-       call MANGLE(memcpy)
-
-       /* load context */
-       mov (%rbp),ARG2
-       /* load datastack */
-       mov 16(ARG2),DS_REG
-       /* load retainstack */
-       mov 24(ARG2),RS_REG
-
-       /* return with new stack */
-       ret
-
-DEF(void,throw_impl,(cell quot, void *new_stack, void *vm)):
-       /* clear x87 stack, but preserve rounding mode and exception flags */
-       sub $2,%rsp
-       fnstcw (%rsp)
-       fninit
-       fldcw (%rsp)
-
-       /* shuffle args */
-       mov ARG1,%rsp
-       mov ARG2,ARG1
-
-       /* load context */
-       mov (ARG1),ARG2
-       /* load datastack */
-       mov 16(ARG2),DS_REG
-       /* load retainstack */
-       mov 24(ARG2),RS_REG
-
-       jmp *QUOT_XT_OFFSET(ARG0)
-
-DEF(void,lazy_jit_compile_impl,(cell quot, void *vm)):
-       /* load context */
-       mov (ARG1),ARG2
-       /* save datastack */
-       mov DS_REG,16(ARG2)
-       /* save retainstack */
-       mov RS_REG,24(ARG2)
-       /* save callstack */
-       lea -8(%rsp),%rbp
-       mov %rbp,(ARG2)
-
-       /* compile quotation */
-       sub $8,%rsp
-       call MANGLE(lazy_jit_compile)
-       add $8,%rsp
-
-       /* call quotation */
-       jmp *QUOT_XT_OFFSET(RETURN_REG)
-
 DEF(long long,read_timestamp_counter,(void)):
        mov $0,%rax
        rdtsc
@@ -199,5 +24,7 @@ DEF(void,set_x87_env,(const void*)):
        fnclex
        fldcw 2(%rdi)
        ret
+
+#define RETURN_REG %rax
        
 #include "cpu-x86.S"
index d59d0df7fbd1b6f295e55537ff90116898118f5d..dae775ae3d191990d50641b6677cc85f22b627f8 100644 (file)
@@ -38,5 +38,4 @@ sse_1:
 #ifdef WINDOWS
        .section .drectve
        .ascii " -export:sse_version"
-       .ascii " -export:c_to_factor"
 #endif
index 349548f1ca32d2881bfc7f73b5dd968d4af850ab..c96291b0d72da9be33552f2386bb4dfedd21062c 100644 (file)
@@ -73,16 +73,4 @@ inline static unsigned int fpu_status(unsigned int status)
         return r;
 }
 
-/* Defined in assembly */
-VM_C_API void c_to_factor(cell quot, void *vm);
-VM_C_API void throw_impl(cell quot, void *new_stack, void *vm);
-VM_C_API void lazy_jit_compile_impl(cell quot, void *vm);
-
-VM_C_API void set_callstack(
-       void *vm,
-       stack_frame *to,
-       stack_frame *from,
-       cell length,
-       void *(*memcpy)(void*,const void*, size_t));
-
 }
diff --git a/vm/entry_points.cpp b/vm/entry_points.cpp
new file mode 100644 (file)
index 0000000..87a3c05
--- /dev/null
@@ -0,0 +1,22 @@
+#include "master.hpp"
+
+namespace factor
+{
+
+void factor_vm::c_to_factor(cell quot)
+{
+       /* First time this is called, wrap the c-to-factor sub-primitive inside
+       of a callback stub, which saves and restores non-volatile registers
+       as per platform ABI conventions, so that the Factor compiler can treat
+       all registers as volatile */
+       if(!c_to_factor_func)
+       {
+               tagged<word> c_to_factor_word(special_objects[C_TO_FACTOR_WORD]);
+               code_block *c_to_factor_block = callbacks->add(c_to_factor_word.value(),0);
+               c_to_factor_func = (c_to_factor_func_type)c_to_factor_block->xt();
+       }
+
+       c_to_factor_func(quot);
+}
+
+}
diff --git a/vm/entry_points.hpp b/vm/entry_points.hpp
new file mode 100644 (file)
index 0000000..663eb7d
--- /dev/null
@@ -0,0 +1,6 @@
+namespace factor
+{
+
+typedef void (* c_to_factor_func_type)(cell quot);
+
+}
index 2292c2769369bd5cbc118f9c81967907f0a7412b..2dcb773dd1c06b81ec9528708c9e2afb47191791 100755 (executable)
@@ -31,7 +31,7 @@ void factor_vm::throw_error(cell error, stack_frame *callstack_top)
 {
        /* If the error handler is set, we rewind any C stack frames and
        pass the error to user-space. */
-       if(!current_gc && to_boolean(special_objects[OBJ_BREAK]))
+       if(!current_gc && to_boolean(special_objects[ERROR_HANDLER_QUOT]))
        {
                /* If error was thrown during heap scan, we re-enable the GC */
                gc_off = false;
@@ -56,7 +56,7 @@ void factor_vm::throw_error(cell error, stack_frame *callstack_top)
                else
                        callstack_top = ctx->callstack_top;
 
-               throw_impl(special_objects[OBJ_BREAK],callstack_top,this);
+               unwind_native_frames(special_objects[ERROR_HANDLER_QUOT],callstack_top);
        }
        /* Error was thrown in early startup before error handler is set, just
        crash. */
@@ -130,7 +130,7 @@ void factor_vm::fp_trap_error(unsigned int fpu_status, stack_frame *signal_calls
 
 void factor_vm::primitive_call_clear()
 {
-       throw_impl(ctx->pop(),ctx->callstack_bottom,this);
+       unwind_native_frames(ctx->pop(),ctx->callstack_bottom);
 }
 
 /* For testing purposes */
index d4824fdcd5fc7d7358e6c43074412bda05114126..46eb2efdfd6e5cf110eaa1981fce752741f7b764 100755 (executable)
@@ -87,6 +87,7 @@ void factor_vm::do_stage1_init()
 
        compile_all_words();
        update_code_heap_words();
+       initialize_all_quotations();
        special_objects[OBJ_STAGE2] = true_object;
 
        std::cout << "done\n";
index 80c2f1050d5e71644929c1b2f1e49028491c7e78..52fe70240149a82fae708f474c065b22f4f7498f 100755 (executable)
@@ -74,6 +74,7 @@ namespace factor
 #include "alien.hpp"
 #include "callbacks.hpp"
 #include "dispatch.hpp"
+#include "entry_points.hpp"
 #include "vm.hpp"
 #include "allot.hpp"
 #include "tagged.hpp"
index 368f0f2c19d16a0e783161c43270dcfb4fd4063f..fdc5758a8d2159bb6730307c764f2bc7ff8f6202 100644 (file)
@@ -11,7 +11,7 @@ enum special_object {
        OBJ_WALKER_HOOK,           /* non-local exit hook, used by library only */
        OBJ_CALLCC_1,              /* used to pass the value in callcc1 */
 
-       OBJ_BREAK = 5,             /* quotation called by throw primitive */
+       ERROR_HANDLER_QUOT = 5,    /* quotation called when VM throws an error */
        OBJ_ERROR,                 /* a marker consed onto kernel errors */
 
        OBJ_CELL_SIZE = 7,         /* sizeof(cell) */
@@ -57,6 +57,11 @@ enum special_object {
        JIT_EXECUTE,
        JIT_DECLARE_WORD,
 
+       /* External entry points */
+       C_TO_FACTOR_WORD,
+       LAZY_JIT_COMPILE_WORD,
+       UNWIND_NATIVE_FRAMES_WORD,
+
        /* Incremented on every modify-code-heap call; invalidates call( inline
        caching */
        REDEFINITION_COUNTER = 47,
index ba23125e802c616281ef8f10be40252b530ce328..301b68fb528bb96ce302f5d3b54675a12110c4bb 100644 (file)
@@ -6,7 +6,7 @@ namespace factor
 
 void factor_vm::c_to_factor_toplevel(cell quot)
 {
-       c_to_factor(quot,this);
+       c_to_factor(quot);
 }
 
 void init_signals()
index 101169be064427843573641a9fa8817c0742e515..92694a4599a19770b1db16807189e9221c9d0901 100644 (file)
@@ -11,7 +11,7 @@ void factor_vm::c_to_factor_toplevel(cell quot)
        for(;;)
        {
 NS_DURING
-               c_to_factor(quot,this);
+               c_to_factor(quot);
                NS_VOIDRETURN;
 NS_HANDLER
                ctx->push(allot_alien(false_object,(cell)localException));
index f0ae9e7a6d46c418f4c825d4332be29a4f750c04..cab30b121ee287d38459d852e3d12295ca692ba7 100755 (executable)
@@ -117,16 +117,13 @@ FACTOR_STDCALL LONG exception_handler(PEXCEPTION_POINTERS pe)
        return tls_vm()->exception_handler(pe);
 }
 
-bool handler_added = 0;
-
 void factor_vm::c_to_factor_toplevel(cell quot)
 {
-       if(!handler_added){
-               if(!AddVectoredExceptionHandler(0, (PVECTORED_EXCEPTION_HANDLER)factor::exception_handler))
-                       fatal_error("AddVectoredExceptionHandler failed", 0);
-               handler_added = 1;
-       }
-       c_to_factor(quot,this);
+       if(!AddVectoredExceptionHandler(0, (PVECTORED_EXCEPTION_HANDLER)factor::exception_handler))
+               fatal_error("AddVectoredExceptionHandler failed", 0);
+
+       c_to_factor(quot);
+
        RemoveVectoredExceptionHandler((void *)factor::exception_handler);
 }
 
index 830ae7beb234455c845867a6772212e3a2a760d5..5521b26a3f9ac4b973f6217be14d9c42cef4efb8 100644 (file)
@@ -62,7 +62,6 @@ PRIMITIVE_FORWARD(retainstack)
 PRIMITIVE_FORWARD(callstack)
 PRIMITIVE_FORWARD(set_datastack)
 PRIMITIVE_FORWARD(set_retainstack)
-PRIMITIVE_FORWARD(set_callstack)
 PRIMITIVE_FORWARD(exit)
 PRIMITIVE_FORWARD(data_room)
 PRIMITIVE_FORWARD(code_room)
@@ -196,7 +195,6 @@ const primitive_type primitives[] = {
        primitive_callstack,
        primitive_set_datastack,
        primitive_set_retainstack,
-       primitive_set_callstack,
        primitive_exit,
        primitive_data_room,
        primitive_code_room,
index 5af9d95b02324daf1a5664d3eb11779bd2a8bebf..73c28875fa6e7502a623a5683391b64e4b8e10fa 100755 (executable)
@@ -294,10 +294,11 @@ void factor_vm::jit_compile_quot(cell quot_, bool relocating)
 {
        data_root<quotation> quot(quot_,this);
 
-       if(quot->code) return;
-
-       code_block *compiled = jit_compile_quot(quot.value(),quot.value(),relocating);
-       set_quot_xt(quot.untagged(),compiled);
+       if(quot->code == NULL || quot->code == lazy_jit_compile_block())
+       {
+               code_block *compiled = jit_compile_quot(quot.value(),quot.value(),relocating);
+               set_quot_xt(quot.untagged(),compiled);
+       }
 }
 
 void factor_vm::primitive_jit_compile()
@@ -305,15 +306,21 @@ void factor_vm::primitive_jit_compile()
        jit_compile_quot(ctx->pop(),true);
 }
 
+code_block *factor_vm::lazy_jit_compile_block()
+{
+       return untag<word>(special_objects[LAZY_JIT_COMPILE_WORD])->code;
+}
+
 /* push a new quotation on the stack */
 void factor_vm::primitive_array_to_quotation()
 {
        quotation *quot = allot<quotation>(sizeof(quotation));
+
        quot->array = ctx->peek();
        quot->cached_effect = false_object;
        quot->cache_counter = false_object;
-       quot->xt = (void *)lazy_jit_compile_impl;
-       quot->code = NULL;
+       set_quot_xt(quot,lazy_jit_compile_block());
+
        ctx->replace(tag<quotation>(quot));
 }
 
@@ -353,7 +360,25 @@ void factor_vm::primitive_quot_compiled_p()
 {
        tagged<quotation> quot(ctx->pop());
        quot.untag_check(this);
-       ctx->push(tag_boolean(quot->code != NULL));
+       ctx->push(tag_boolean(quot->code != lazy_jit_compile_block()));
+}
+
+cell factor_vm::find_all_quotations()
+{
+       return instances(QUOTATION_TYPE);
+}
+
+void factor_vm::initialize_all_quotations()
+{
+       data_root<array> quotations(find_all_quotations(),this);
+
+       cell length = array_capacity(quotations.untagged());
+       for(cell i = 0; i < length; i++)
+       {
+               data_root<quotation> quot(array_nth(quotations.untagged(),i),this);
+               if(!quot->code)
+                       set_quot_xt(quot.untagged(),lazy_jit_compile_block());
+       }
 }
 
 }
index d911b80227d009befe6151a84ac341cd695a0bb7..623556416ab3ece478241406fc283646a3e14137 100755 (executable)
--- a/vm/vm.cpp
+++ b/vm/vm.cpp
@@ -5,6 +5,7 @@ namespace factor
 \r
 factor_vm::factor_vm() :\r
        nursery(0,0),\r
+       c_to_factor_func(NULL),\r
        profiling_p(false),\r
        gc_off(false),\r
        current_gc(NULL),\r
index ef2d7e06444b319ce3979bd49e18cdc8b8deb5bf..3a87857488b294f1abd734ac0be925ea51c8fe8e 100755 (executable)
--- a/vm/vm.hpp
+++ b/vm/vm.hpp
@@ -30,6 +30,9 @@ struct factor_vm
        /* Canonical truth value. In Factor, 't' */
        cell true_object;
 
+       /* External entry points */
+       c_to_factor_func_type c_to_factor_func;
+
        /* Is call counting enabled? */
        bool profiling_p;
 
@@ -562,7 +565,6 @@ struct factor_vm
        stack_frame *fix_callstack_top(stack_frame *top, stack_frame *bottom);
        stack_frame *second_from_top_stack_frame();
        void primitive_callstack();
-       void primitive_set_callstack();
        code_block *frame_code(stack_frame *frame);
        code_block_type frame_type(stack_frame *frame);
        cell frame_executing(stack_frame *frame);
@@ -596,6 +598,7 @@ struct factor_vm
 
        //quotations
        void primitive_jit_compile();
+       code_block *lazy_jit_compile_block();
        void primitive_array_to_quotation();
        void primitive_quotation_xt();
        void set_quot_xt(quotation *quot, code_block *code);
@@ -604,6 +607,8 @@ struct factor_vm
        fixnum quot_code_offset_to_scan(cell quot_, cell offset);
        cell lazy_jit_compile(cell quot);
        void primitive_quot_compiled_p();
+       cell find_all_quotations();
+       void initialize_all_quotations();
 
        //dispatch
        cell search_lookup_alist(cell table, cell klass);
@@ -632,9 +637,13 @@ struct factor_vm
        void update_pic_transitions(cell pic_size);
        void *inline_cache_miss(cell return_address);
 
+       //entry points
+       void c_to_factor(cell quot);
+       void unwind_native_frames(cell quot, stack_frame *to);
+
        //factor
        void default_parameters(vm_parameters *p);
-       bool factor_arg(const vm_char* str, const vm_char* arg, cell* value);
+       bool factor_arg(const vm_char *str, const vm_char *arg, cell *value);
        void init_parameters_from_args(vm_parameters *p, int argc, vm_char **argv);
        void do_stage1_init();
        void init_factor(vm_parameters *p);