threads: delete old contexts immediately instead of handing them off to a 'context recycler' thread
parent
60d1a9640d
commit
fb2ecab614
|
@ -72,6 +72,12 @@ IN: bootstrap.x86
|
||||||
jit-restore-context
|
jit-restore-context
|
||||||
] jit-primitive jit-define
|
] jit-primitive jit-define
|
||||||
|
|
||||||
|
: jit-jump-quot ( -- )
|
||||||
|
EAX quot-entry-point-offset [+] JMP ;
|
||||||
|
|
||||||
|
: jit-call-quot ( -- )
|
||||||
|
EAX quot-entry-point-offset [+] CALL ;
|
||||||
|
|
||||||
[
|
[
|
||||||
jit-load-vm
|
jit-load-vm
|
||||||
ESP [] vm-reg MOV
|
ESP [] vm-reg MOV
|
||||||
|
@ -92,8 +98,7 @@ IN: bootstrap.x86
|
||||||
ESP ctx-reg context-callstack-bottom-offset [+] MOV
|
ESP ctx-reg context-callstack-bottom-offset [+] MOV
|
||||||
ESP 4 ADD
|
ESP 4 ADD
|
||||||
|
|
||||||
! call the quotation
|
jit-call-quot
|
||||||
EAX quot-entry-point-offset [+] CALL
|
|
||||||
|
|
||||||
jit-load-vm
|
jit-load-vm
|
||||||
jit-save-context
|
jit-save-context
|
||||||
|
@ -109,8 +114,8 @@ IN: bootstrap.x86
|
||||||
EAX ds-reg [] MOV
|
EAX ds-reg [] MOV
|
||||||
ds-reg bootstrap-cell SUB
|
ds-reg bootstrap-cell SUB
|
||||||
]
|
]
|
||||||
[ EAX quot-entry-point-offset [+] CALL ]
|
[ jit-call-quot ]
|
||||||
[ EAX quot-entry-point-offset [+] JMP ]
|
[ jit-jump-quot ]
|
||||||
\ (call) define-combinator-primitive
|
\ (call) define-combinator-primitive
|
||||||
|
|
||||||
[
|
[
|
||||||
|
@ -133,8 +138,7 @@ IN: bootstrap.x86
|
||||||
jit-load-context
|
jit-load-context
|
||||||
jit-restore-context
|
jit-restore-context
|
||||||
|
|
||||||
! Call quotation
|
jit-jump-quot
|
||||||
EAX quot-entry-point-offset [+] JMP
|
|
||||||
] \ unwind-native-frames define-sub-primitive
|
] \ unwind-native-frames define-sub-primitive
|
||||||
|
|
||||||
[
|
[
|
||||||
|
@ -175,8 +179,8 @@ IN: bootstrap.x86
|
||||||
! Call VM
|
! Call VM
|
||||||
"lazy_jit_compile" jit-call
|
"lazy_jit_compile" jit-call
|
||||||
]
|
]
|
||||||
[ EAX quot-entry-point-offset [+] CALL ]
|
[ jit-call-quot ]
|
||||||
[ EAX quot-entry-point-offset [+] JMP ]
|
[ jit-jump-quot ]
|
||||||
\ lazy-jit-compile define-combinator-primitive
|
\ lazy-jit-compile define-combinator-primitive
|
||||||
|
|
||||||
! Inline cache miss entry points
|
! Inline cache miss entry points
|
||||||
|
@ -247,8 +251,8 @@ IN: bootstrap.x86
|
||||||
jit-conditional
|
jit-conditional
|
||||||
] \ fixnum* define-sub-primitive
|
] \ fixnum* define-sub-primitive
|
||||||
|
|
||||||
! Threads
|
! Contexts
|
||||||
: jit-set-context ( reg -- )
|
: jit-switch-context ( reg -- )
|
||||||
! Save ds, rs registers
|
! Save ds, rs registers
|
||||||
jit-load-vm
|
jit-load-vm
|
||||||
jit-save-context
|
jit-save-context
|
||||||
|
@ -263,7 +267,26 @@ IN: bootstrap.x86
|
||||||
! Load new ds, rs registers
|
! Load new ds, rs registers
|
||||||
jit-restore-context ;
|
jit-restore-context ;
|
||||||
|
|
||||||
[
|
: jit-set-context ( -- )
|
||||||
|
! Load context and parameter from datastack
|
||||||
|
EAX ds-reg [] MOV
|
||||||
|
EAX EAX alien-offset [+] MOV
|
||||||
|
EBX ds-reg -4 [+] MOV
|
||||||
|
ds-reg 8 SUB
|
||||||
|
|
||||||
|
! Make the new context active
|
||||||
|
EAX jit-switch-context
|
||||||
|
|
||||||
|
! Twiddle stack for return
|
||||||
|
ESP 4 ADD
|
||||||
|
|
||||||
|
! Store parameter to datastack
|
||||||
|
ds-reg 4 ADD
|
||||||
|
ds-reg [] EBX MOV ;
|
||||||
|
|
||||||
|
[ jit-set-context ] \ (set-context) define-sub-primitive
|
||||||
|
|
||||||
|
: jit-start-context ( -- )
|
||||||
! Create the new context in return-reg
|
! Create the new context in return-reg
|
||||||
jit-load-vm
|
jit-load-vm
|
||||||
ESP [] vm-reg MOV
|
ESP [] vm-reg MOV
|
||||||
|
@ -274,7 +297,7 @@ IN: bootstrap.x86
|
||||||
ds-reg 8 SUB
|
ds-reg 8 SUB
|
||||||
|
|
||||||
! Make the new context active
|
! Make the new context active
|
||||||
EAX jit-set-context
|
EAX jit-switch-context
|
||||||
|
|
||||||
! Push parameter
|
! Push parameter
|
||||||
EAX EBX -4 [+] MOV
|
EAX EBX -4 [+] MOV
|
||||||
|
@ -283,26 +306,26 @@ IN: bootstrap.x86
|
||||||
|
|
||||||
! Jump to initial quotation
|
! Jump to initial quotation
|
||||||
EAX EBX [] MOV
|
EAX EBX [] MOV
|
||||||
EAX quot-entry-point-offset [+] JMP
|
jit-jump-quot ;
|
||||||
] \ (start-context) define-sub-primitive
|
|
||||||
|
[ jit-start-context ] \ (start-context) define-sub-primitive
|
||||||
|
|
||||||
|
: jit-delete-current-context ( -- )
|
||||||
|
jit-load-vm
|
||||||
|
jit-load-context
|
||||||
|
ESP [] vm-reg MOV
|
||||||
|
ESP 4 [+] ctx-reg MOV
|
||||||
|
"delete_context" jit-call ;
|
||||||
|
|
||||||
[
|
[
|
||||||
! Load context and parameter from datastack
|
jit-delete-current-context
|
||||||
EAX ds-reg [] MOV
|
jit-set-context
|
||||||
EAX EAX alien-offset [+] MOV
|
] \ (set-context-and-delete) define-sub-primitive
|
||||||
EBX ds-reg -4 [+] MOV
|
|
||||||
ds-reg 8 SUB
|
|
||||||
|
|
||||||
! Make the new context active
|
[
|
||||||
EAX jit-set-context
|
jit-delete-current-context
|
||||||
|
jit-start-context
|
||||||
! Twiddle stack for return
|
] \ (start-context-and-delete) define-sub-primitive
|
||||||
ESP 4 ADD
|
|
||||||
|
|
||||||
! Store parameter to datastack
|
|
||||||
ds-reg 4 ADD
|
|
||||||
ds-reg [] EBX MOV
|
|
||||||
] \ (set-context) define-sub-primitive
|
|
||||||
|
|
||||||
<< "vocab:cpu/x86/bootstrap.factor" parse-file suffix! >>
|
<< "vocab:cpu/x86/bootstrap.factor" parse-file suffix! >>
|
||||||
call
|
call
|
||||||
|
|
|
@ -70,6 +70,10 @@ IN: bootstrap.x86
|
||||||
jit-restore-context
|
jit-restore-context
|
||||||
] jit-primitive jit-define
|
] jit-primitive jit-define
|
||||||
|
|
||||||
|
: jit-jump-quot ( -- ) arg1 quot-entry-point-offset [+] JMP ;
|
||||||
|
|
||||||
|
: jit-call-quot ( -- ) arg1 quot-entry-point-offset [+] CALL ;
|
||||||
|
|
||||||
[
|
[
|
||||||
nv-reg arg1 MOV
|
nv-reg arg1 MOV
|
||||||
|
|
||||||
|
@ -87,7 +91,7 @@ IN: bootstrap.x86
|
||||||
|
|
||||||
! call the quotation
|
! call the quotation
|
||||||
arg1 nv-reg MOV
|
arg1 nv-reg MOV
|
||||||
arg1 quot-entry-point-offset [+] CALL
|
jit-call-quot
|
||||||
|
|
||||||
jit-save-context
|
jit-save-context
|
||||||
|
|
||||||
|
@ -102,8 +106,8 @@ IN: bootstrap.x86
|
||||||
arg1 ds-reg [] MOV
|
arg1 ds-reg [] MOV
|
||||||
ds-reg bootstrap-cell SUB
|
ds-reg bootstrap-cell SUB
|
||||||
]
|
]
|
||||||
[ arg1 quot-entry-point-offset [+] CALL ]
|
[ jit-call-quot ]
|
||||||
[ arg1 quot-entry-point-offset [+] JMP ]
|
[ jit-jump-quot ]
|
||||||
\ (call) define-combinator-primitive
|
\ (call) define-combinator-primitive
|
||||||
|
|
||||||
[
|
[
|
||||||
|
@ -124,7 +128,7 @@ IN: bootstrap.x86
|
||||||
jit-restore-context
|
jit-restore-context
|
||||||
|
|
||||||
! Call quotation
|
! Call quotation
|
||||||
arg1 quot-entry-point-offset [+] JMP
|
jit-jump-quot
|
||||||
] \ unwind-native-frames define-sub-primitive
|
] \ unwind-native-frames define-sub-primitive
|
||||||
|
|
||||||
[
|
[
|
||||||
|
@ -157,9 +161,10 @@ IN: bootstrap.x86
|
||||||
jit-save-context
|
jit-save-context
|
||||||
arg2 vm-reg MOV
|
arg2 vm-reg MOV
|
||||||
"lazy_jit_compile" jit-call
|
"lazy_jit_compile" jit-call
|
||||||
|
arg1 return-reg MOV
|
||||||
]
|
]
|
||||||
[ return-reg quot-entry-point-offset [+] CALL ]
|
[ return-reg quot-entry-point-offset [+] CALL ]
|
||||||
[ return-reg quot-entry-point-offset [+] JMP ]
|
[ jit-jump-quot ]
|
||||||
\ lazy-jit-compile define-combinator-primitive
|
\ lazy-jit-compile define-combinator-primitive
|
||||||
|
|
||||||
! Inline cache miss entry points
|
! Inline cache miss entry points
|
||||||
|
@ -222,8 +227,8 @@ IN: bootstrap.x86
|
||||||
jit-conditional
|
jit-conditional
|
||||||
] \ fixnum* define-sub-primitive
|
] \ fixnum* define-sub-primitive
|
||||||
|
|
||||||
! Threads
|
! Contexts
|
||||||
: jit-set-context ( reg -- )
|
: jit-switch-context ( reg -- )
|
||||||
! Save ds, rs registers
|
! Save ds, rs registers
|
||||||
jit-save-context
|
jit-save-context
|
||||||
|
|
||||||
|
@ -237,44 +242,59 @@ IN: bootstrap.x86
|
||||||
! Load new ds, rs registers
|
! Load new ds, rs registers
|
||||||
jit-restore-context ;
|
jit-restore-context ;
|
||||||
|
|
||||||
[
|
: jit-pop-context-and-param ( -- )
|
||||||
|
arg1 ds-reg [] MOV
|
||||||
|
arg1 arg1 alien-offset [+] MOV
|
||||||
|
arg2 ds-reg -8 [+] MOV
|
||||||
|
ds-reg 16 SUB ;
|
||||||
|
|
||||||
|
: jit-push-param ( -- )
|
||||||
|
ds-reg 8 ADD
|
||||||
|
ds-reg [] arg2 MOV ;
|
||||||
|
|
||||||
|
: jit-set-context ( -- )
|
||||||
|
jit-pop-context-and-param
|
||||||
|
arg1 jit-switch-context
|
||||||
|
RSP 8 ADD
|
||||||
|
jit-push-param ;
|
||||||
|
|
||||||
|
[ jit-set-context ] \ (set-context) define-sub-primitive
|
||||||
|
|
||||||
|
: jit-pop-quot-and-param ( -- )
|
||||||
|
arg1 ds-reg [] MOV
|
||||||
|
arg2 ds-reg -8 [+] MOV
|
||||||
|
ds-reg 16 SUB ;
|
||||||
|
|
||||||
|
: jit-start-context ( -- )
|
||||||
! Create the new context in return-reg
|
! Create the new context in return-reg
|
||||||
arg1 vm-reg MOV
|
arg1 vm-reg MOV
|
||||||
"new_context" jit-call
|
"new_context" jit-call
|
||||||
|
|
||||||
! Load quotation and parameter from datastack
|
jit-pop-quot-and-param
|
||||||
arg1 ds-reg [] MOV
|
|
||||||
arg2 ds-reg -8 [+] MOV
|
|
||||||
ds-reg 16 SUB
|
|
||||||
|
|
||||||
! Make the new context active
|
return-reg jit-switch-context
|
||||||
return-reg jit-set-context
|
|
||||||
|
|
||||||
! Push parameter
|
jit-push-param
|
||||||
ds-reg 8 ADD
|
|
||||||
ds-reg [] arg2 MOV
|
|
||||||
|
|
||||||
! Jump to initial quotation
|
jit-jump-quot ;
|
||||||
arg1 quot-entry-point-offset [+] JMP
|
|
||||||
] \ (start-context) define-sub-primitive
|
[ jit-start-context ] \ (start-context) define-sub-primitive
|
||||||
|
|
||||||
|
: jit-delete-current-context ( -- )
|
||||||
|
jit-load-context
|
||||||
|
arg1 vm-reg MOV
|
||||||
|
arg2 ctx-reg MOV
|
||||||
|
"delete_context" jit-call ;
|
||||||
|
|
||||||
[
|
[
|
||||||
! Load context and parameter from datastack
|
jit-delete-current-context
|
||||||
temp0 ds-reg [] MOV
|
jit-set-context
|
||||||
temp0 temp0 alien-offset [+] MOV
|
] \ (set-context-and-delete) define-sub-primitive
|
||||||
temp1 ds-reg -8 [+] MOV
|
|
||||||
ds-reg 16 SUB
|
|
||||||
|
|
||||||
! Make the new context active
|
[
|
||||||
temp0 jit-set-context
|
jit-delete-current-context
|
||||||
|
jit-start-context
|
||||||
! Twiddle stack for return
|
] \ (start-context-and-delete) define-sub-primitive
|
||||||
RSP 8 ADD
|
|
||||||
|
|
||||||
! Store parameter to datastack
|
|
||||||
ds-reg 8 ADD
|
|
||||||
ds-reg [] temp1 MOV
|
|
||||||
] \ (set-context) define-sub-primitive
|
|
||||||
|
|
||||||
<< "vocab:cpu/x86/bootstrap.factor" parse-file suffix! >>
|
<< "vocab:cpu/x86/bootstrap.factor" parse-file suffix! >>
|
||||||
call
|
call
|
||||||
|
|
|
@ -151,13 +151,6 @@ M: bad-call summary
|
||||||
: required-stack-effect ( word -- effect )
|
: required-stack-effect ( word -- effect )
|
||||||
dup stack-effect [ ] [ missing-effect ] ?if ;
|
dup stack-effect [ ] [ missing-effect ] ?if ;
|
||||||
|
|
||||||
: infer-word ( word -- )
|
|
||||||
{
|
|
||||||
{ [ dup macro? ] [ do-not-compile ] }
|
|
||||||
{ [ dup "no-compile" word-prop ] [ do-not-compile ] }
|
|
||||||
[ dup required-stack-effect apply-word/effect ]
|
|
||||||
} cond ;
|
|
||||||
|
|
||||||
: with-infer ( quot -- effect visitor )
|
: with-infer ( quot -- effect visitor )
|
||||||
[
|
[
|
||||||
init-inference
|
init-inference
|
||||||
|
|
|
@ -14,7 +14,7 @@ compiler.units system.private combinators
|
||||||
combinators.short-circuit locals locals.backend locals.types
|
combinators.short-circuit locals locals.backend locals.types
|
||||||
combinators.private stack-checker.values generic.single
|
combinators.private stack-checker.values generic.single
|
||||||
generic.single.private alien.libraries tools.dispatch.private
|
generic.single.private alien.libraries tools.dispatch.private
|
||||||
tools.profiler.private
|
tools.profiler.private macros
|
||||||
stack-checker.alien
|
stack-checker.alien
|
||||||
stack-checker.state
|
stack-checker.state
|
||||||
stack-checker.errors
|
stack-checker.errors
|
||||||
|
@ -27,11 +27,41 @@ stack-checker.recursive-state
|
||||||
stack-checker.row-polymorphism ;
|
stack-checker.row-polymorphism ;
|
||||||
IN: stack-checker.known-words
|
IN: stack-checker.known-words
|
||||||
|
|
||||||
: infer-primitive ( word -- )
|
: infer-special ( word -- )
|
||||||
dup
|
[ current-word set ] [ "special" word-prop call( -- ) ] bi ;
|
||||||
[ "input-classes" word-prop ]
|
|
||||||
[ "default-output-classes" word-prop ] bi <effect>
|
: infer-shuffle ( shuffle -- )
|
||||||
apply-word/effect ;
|
[ in>> length consume-d ] keep ! inputs shuffle
|
||||||
|
[ drop ] [ shuffle dup copy-values dup output-d ] 2bi ! inputs outputs copies
|
||||||
|
[ nip f f ] [ swap zip ] 2bi ! in-d out-d in-r out-r mapping
|
||||||
|
#shuffle, ;
|
||||||
|
|
||||||
|
: infer-shuffle-word ( word -- )
|
||||||
|
"shuffle" word-prop infer-shuffle ;
|
||||||
|
|
||||||
|
: infer-local-reader ( word -- )
|
||||||
|
(( -- value )) apply-word/effect ;
|
||||||
|
|
||||||
|
: infer-local-writer ( word -- )
|
||||||
|
(( value -- )) apply-word/effect ;
|
||||||
|
|
||||||
|
: infer-local-word ( word -- )
|
||||||
|
"local-word-def" word-prop infer-quot-here ;
|
||||||
|
|
||||||
|
: non-inline-word ( word -- )
|
||||||
|
dup depends-on-effect
|
||||||
|
{
|
||||||
|
{ [ dup "shuffle" word-prop ] [ infer-shuffle-word ] }
|
||||||
|
{ [ dup "special" word-prop ] [ infer-special ] }
|
||||||
|
{ [ dup "transform-quot" word-prop ] [ apply-transform ] }
|
||||||
|
{ [ dup macro? ] [ apply-macro ] }
|
||||||
|
{ [ dup local? ] [ infer-local-reader ] }
|
||||||
|
{ [ dup local-reader? ] [ infer-local-reader ] }
|
||||||
|
{ [ dup local-writer? ] [ infer-local-writer ] }
|
||||||
|
{ [ dup local-word? ] [ infer-local-word ] }
|
||||||
|
{ [ dup "no-compile" word-prop ] [ do-not-compile ] }
|
||||||
|
[ dup required-stack-effect apply-word/effect ]
|
||||||
|
} cond ;
|
||||||
|
|
||||||
{
|
{
|
||||||
{ drop (( x -- )) }
|
{ drop (( x -- )) }
|
||||||
|
@ -51,15 +81,6 @@ IN: stack-checker.known-words
|
||||||
{ swap (( x y -- y x )) }
|
{ swap (( x y -- y x )) }
|
||||||
} [ "shuffle" set-word-prop ] assoc-each
|
} [ "shuffle" set-word-prop ] assoc-each
|
||||||
|
|
||||||
: infer-shuffle ( shuffle -- )
|
|
||||||
[ in>> length consume-d ] keep ! inputs shuffle
|
|
||||||
[ drop ] [ shuffle dup copy-values dup output-d ] 2bi ! inputs outputs copies
|
|
||||||
[ nip f f ] [ swap zip ] 2bi ! in-d out-d in-r out-r mapping
|
|
||||||
#shuffle, ;
|
|
||||||
|
|
||||||
: infer-shuffle-word ( word -- )
|
|
||||||
"shuffle" word-prop infer-shuffle ;
|
|
||||||
|
|
||||||
: check-declaration ( declaration -- declaration )
|
: check-declaration ( declaration -- declaration )
|
||||||
dup { [ array? ] [ [ class? ] all? ] } 1&&
|
dup { [ array? ] [ [ class? ] all? ] } 1&&
|
||||||
[ bad-declaration-error ] unless ;
|
[ bad-declaration-error ] unless ;
|
||||||
|
@ -180,11 +201,6 @@ M: bad-executable summary
|
||||||
|
|
||||||
\ call-effect-unsafe [ infer-call-effect-unsafe ] "special" set-word-prop
|
\ call-effect-unsafe [ infer-call-effect-unsafe ] "special" set-word-prop
|
||||||
|
|
||||||
: infer-exit ( -- )
|
|
||||||
\ exit (( n -- * )) apply-word/effect ;
|
|
||||||
|
|
||||||
\ exit [ infer-exit ] "special" set-word-prop
|
|
||||||
|
|
||||||
: infer-load-locals ( -- )
|
: infer-load-locals ( -- )
|
||||||
pop-literal nip
|
pop-literal nip
|
||||||
consume-d dup copy-values dup output-r
|
consume-d dup copy-values dup output-r
|
||||||
|
@ -249,22 +265,10 @@ M: bad-executable summary
|
||||||
c-to-factor
|
c-to-factor
|
||||||
} [ dup '[ _ do-not-compile ] "special" set-word-prop ] each
|
} [ dup '[ _ do-not-compile ] "special" set-word-prop ] each
|
||||||
|
|
||||||
: infer-special ( word -- )
|
|
||||||
[ current-word set ] [ "special" word-prop call( -- ) ] bi ;
|
|
||||||
|
|
||||||
: infer-local-reader ( word -- )
|
|
||||||
(( -- value )) apply-word/effect ;
|
|
||||||
|
|
||||||
: infer-local-writer ( word -- )
|
|
||||||
(( value -- )) apply-word/effect ;
|
|
||||||
|
|
||||||
: infer-local-word ( word -- )
|
|
||||||
"local-word-def" word-prop infer-quot-here ;
|
|
||||||
|
|
||||||
{
|
{
|
||||||
declare call (call) dip 2dip 3dip curry compose
|
declare call (call) dip 2dip 3dip curry compose
|
||||||
execute (execute) call-effect-unsafe execute-effect-unsafe if
|
execute (execute) call-effect-unsafe execute-effect-unsafe if
|
||||||
dispatch <tuple-boa> exit load-local load-locals get-local
|
dispatch <tuple-boa> load-local load-locals get-local
|
||||||
drop-locals do-primitive alien-invoke alien-indirect
|
drop-locals do-primitive alien-invoke alien-indirect
|
||||||
alien-callback
|
alien-callback
|
||||||
} [ t "no-compile" set-word-prop ] each
|
} [ t "no-compile" set-word-prop ] each
|
||||||
|
@ -276,26 +280,10 @@ M: bad-executable summary
|
||||||
! More words not to compile
|
! More words not to compile
|
||||||
\ clear t "no-compile" set-word-prop
|
\ clear t "no-compile" set-word-prop
|
||||||
|
|
||||||
: non-inline-word ( word -- )
|
|
||||||
dup depends-on-effect
|
|
||||||
{
|
|
||||||
{ [ dup "shuffle" word-prop ] [ infer-shuffle-word ] }
|
|
||||||
{ [ dup "special" word-prop ] [ infer-special ] }
|
|
||||||
{ [ dup "primitive" word-prop ] [ infer-primitive ] }
|
|
||||||
{ [ dup "transform-quot" word-prop ] [ apply-transform ] }
|
|
||||||
{ [ dup "macro" word-prop ] [ apply-macro ] }
|
|
||||||
{ [ dup local? ] [ infer-local-reader ] }
|
|
||||||
{ [ dup local-reader? ] [ infer-local-reader ] }
|
|
||||||
{ [ dup local-writer? ] [ infer-local-writer ] }
|
|
||||||
{ [ dup local-word? ] [ infer-local-word ] }
|
|
||||||
[ infer-word ]
|
|
||||||
} cond ;
|
|
||||||
|
|
||||||
: define-primitive ( word inputs outputs -- )
|
: define-primitive ( word inputs outputs -- )
|
||||||
[ 2drop t "primitive" set-word-prop ]
|
[ "input-classes" set-word-prop ]
|
||||||
[ drop "input-classes" set-word-prop ]
|
[ "default-output-classes" set-word-prop ]
|
||||||
[ nip "default-output-classes" set-word-prop ]
|
bi-curry* bi ;
|
||||||
3tri ;
|
|
||||||
|
|
||||||
! Stack effects for all primitives
|
! Stack effects for all primitives
|
||||||
\ (byte-array) { integer } { byte-array } define-primitive \ (byte-array) make-flushable
|
\ (byte-array) { integer } { byte-array } define-primitive \ (byte-array) make-flushable
|
||||||
|
@ -311,8 +299,10 @@ M: bad-executable summary
|
||||||
\ (save-image) { byte-array byte-array } { } define-primitive
|
\ (save-image) { byte-array byte-array } { } define-primitive
|
||||||
\ (save-image-and-exit) { byte-array byte-array } { } define-primitive
|
\ (save-image-and-exit) { byte-array byte-array } { } define-primitive
|
||||||
\ (set-context) { object alien } { object } define-primitive
|
\ (set-context) { object alien } { object } define-primitive
|
||||||
|
\ (set-context-and-delete) { object alien } { } define-primitive
|
||||||
\ (sleep) { integer } { } define-primitive
|
\ (sleep) { integer } { } define-primitive
|
||||||
\ (start-context) { object quotation } { object } define-primitive
|
\ (start-context) { object quotation } { object } define-primitive
|
||||||
|
\ (start-context-and-delete) { object quotation } { } define-primitive
|
||||||
\ (word) { object object object } { word } define-primitive \ (word) make-flushable
|
\ (word) { object object object } { word } define-primitive \ (word) make-flushable
|
||||||
\ <array> { integer object } { array } define-primitive \ <array> make-flushable
|
\ <array> { integer object } { array } define-primitive \ <array> make-flushable
|
||||||
\ <byte-array> { integer } { byte-array } define-primitive \ <byte-array> make-flushable
|
\ <byte-array> { integer } { byte-array } define-primitive \ <byte-array> make-flushable
|
||||||
|
@ -376,7 +366,6 @@ M: bad-executable summary
|
||||||
\ data-room { } { byte-array } define-primitive \ data-room make-flushable
|
\ data-room { } { byte-array } define-primitive \ data-room make-flushable
|
||||||
\ datastack { } { array } define-primitive \ datastack make-flushable
|
\ datastack { } { array } define-primitive \ datastack make-flushable
|
||||||
\ datastack-for { c-ptr } { array } define-primitive \ datastack-for make-flushable
|
\ datastack-for { c-ptr } { array } define-primitive \ datastack-for make-flushable
|
||||||
\ delete-context { c-ptr } { } define-primitive
|
|
||||||
\ die { } { } define-primitive
|
\ die { } { } define-primitive
|
||||||
\ disable-gc-events { } { object } define-primitive
|
\ disable-gc-events { } { object } define-primitive
|
||||||
\ dispatch-stats { } { byte-array } define-primitive
|
\ dispatch-stats { } { byte-array } define-primitive
|
||||||
|
|
|
@ -9,13 +9,21 @@ IN: threads
|
||||||
|
|
||||||
<PRIVATE
|
<PRIVATE
|
||||||
|
|
||||||
! (set-context) and (start-context) are sub-primitives, but
|
! Wrap sub-primitives; we don't want them inlined into callers
|
||||||
! we don't want them inlined into callers since their behavior
|
! since their behavior depends on what frames are on the callstack
|
||||||
! depends on what frames are on the callstack
|
: set-context ( obj context -- obj' )
|
||||||
: set-context ( obj context -- obj' ) (set-context) ;
|
(set-context) ;
|
||||||
|
|
||||||
: start-context ( obj quot: ( obj -- * ) -- obj' ) (start-context) ;
|
: start-context ( obj quot: ( obj -- * ) -- obj' )
|
||||||
|
(start-context) ;
|
||||||
|
|
||||||
|
: set-context-and-delete ( obj context -- * )
|
||||||
|
(set-context-and-delete) ;
|
||||||
|
|
||||||
|
: start-context-and-delete ( obj quot: ( obj -- * ) -- * )
|
||||||
|
(start-context-and-delete) ;
|
||||||
|
|
||||||
|
! Context introspection
|
||||||
: namestack-for ( context -- namestack )
|
: namestack-for ( context -- namestack )
|
||||||
[ 0 ] dip context-object-for ;
|
[ 0 ] dip context-object-for ;
|
||||||
|
|
||||||
|
@ -159,60 +167,43 @@ DEFER: stop
|
||||||
while
|
while
|
||||||
drop ;
|
drop ;
|
||||||
|
|
||||||
: start ( namestack -- obj )
|
CONSTANT: [start]
|
||||||
[
|
[
|
||||||
set-namestack
|
set-namestack
|
||||||
init-catchstack
|
init-catchstack
|
||||||
self quot>> call
|
self quot>> call
|
||||||
stop
|
stop
|
||||||
] start-context ;
|
]
|
||||||
|
|
||||||
DEFER: next
|
: no-runnable-threads ( -- ) die ;
|
||||||
|
|
||||||
: no-runnable-threads ( -- obj )
|
|
||||||
! We should never be in a state where the only threads
|
|
||||||
! are sleeping; the I/O wait thread is always runnable.
|
|
||||||
! However, if it dies, we handle this case
|
|
||||||
! semi-gracefully.
|
|
||||||
!
|
|
||||||
! And if sleep-time outputs f, there are no sleeping
|
|
||||||
! threads either... so WTF.
|
|
||||||
sleep-time {
|
|
||||||
{ [ dup not ] [ drop die ] }
|
|
||||||
{ [ dup 0 = ] [ drop ] }
|
|
||||||
[ (sleep) ]
|
|
||||||
} cond next ;
|
|
||||||
|
|
||||||
: (next) ( obj thread -- obj' )
|
: (next) ( obj thread -- obj' )
|
||||||
f >>state
|
|
||||||
dup set-self
|
|
||||||
dup runnable>>
|
dup runnable>>
|
||||||
[ context>> box> set-context ] [ t >>runnable drop start ] if ;
|
[ context>> box> set-context ]
|
||||||
|
[ t >>runnable drop [start] start-context ] if ;
|
||||||
|
|
||||||
: next ( -- obj )
|
: (stop) ( obj thread -- * )
|
||||||
|
dup runnable>>
|
||||||
|
[ context>> box> set-context-and-delete ]
|
||||||
|
[ t >>runnable drop [start] start-context-and-delete ] if ;
|
||||||
|
|
||||||
|
: next ( -- obj thread )
|
||||||
expire-sleep-loop
|
expire-sleep-loop
|
||||||
run-queue dup deque-empty?
|
run-queue pop-back
|
||||||
[ drop no-runnable-threads ]
|
dup array? [ first2 ] [ [ f ] dip ] if
|
||||||
[ pop-back dup array? [ first2 ] [ [ f ] dip ] if (next) ] if ;
|
f >>state
|
||||||
|
dup set-self ;
|
||||||
: recycler-thread ( -- thread ) 68 special-object ;
|
|
||||||
|
|
||||||
: recycler-queue ( -- vector ) 69 special-object ;
|
|
||||||
|
|
||||||
: delete-context-later ( context -- )
|
|
||||||
recycler-queue push recycler-thread interrupt ;
|
|
||||||
|
|
||||||
PRIVATE>
|
PRIVATE>
|
||||||
|
|
||||||
: stop ( -- * )
|
: stop ( -- * )
|
||||||
self [ exit-handler>> call( -- ) ] [ unregister-thread ] bi
|
self [ exit-handler>> call( -- ) ] [ unregister-thread ] bi
|
||||||
context delete-context-later next
|
next (stop) ;
|
||||||
die 1 exit ;
|
|
||||||
|
|
||||||
: suspend ( state -- obj )
|
: suspend ( state -- obj )
|
||||||
[ self ] dip >>state
|
[ self ] dip >>state
|
||||||
[ context ] dip context>> >box
|
[ context ] dip context>> >box
|
||||||
next ;
|
next (next) ;
|
||||||
|
|
||||||
: yield ( -- ) self resume f suspend drop ;
|
: yield ( -- ) self resume f suspend drop ;
|
||||||
|
|
||||||
|
@ -260,22 +251,9 @@ GENERIC: error-in-thread ( error thread -- )
|
||||||
[ set-self ]
|
[ set-self ]
|
||||||
tri ;
|
tri ;
|
||||||
|
|
||||||
! The recycler thread deletes contexts belonging to stopped
|
|
||||||
! threads
|
|
||||||
|
|
||||||
: recycler-loop ( -- )
|
|
||||||
recycler-queue [ [ delete-context ] each ] [ delete-all ] bi
|
|
||||||
f sleep-until
|
|
||||||
recycler-loop ;
|
|
||||||
|
|
||||||
: init-recycler ( -- )
|
|
||||||
[ recycler-loop ] "Context recycler" spawn 68 set-special-object
|
|
||||||
V{ } clone 69 set-special-object ;
|
|
||||||
|
|
||||||
: init-threads ( -- )
|
: init-threads ( -- )
|
||||||
init-thread-state
|
init-thread-state
|
||||||
init-initial-thread
|
init-initial-thread ;
|
||||||
init-recycler ;
|
|
||||||
|
|
||||||
PRIVATE>
|
PRIVATE>
|
||||||
|
|
||||||
|
|
|
@ -175,7 +175,6 @@ IN: tools.deploy.shaker
|
||||||
"predicate"
|
"predicate"
|
||||||
"predicate-definition"
|
"predicate-definition"
|
||||||
"predicating"
|
"predicating"
|
||||||
"primitive"
|
|
||||||
"reader"
|
"reader"
|
||||||
"reading"
|
"reading"
|
||||||
"recursive"
|
"recursive"
|
||||||
|
|
|
@ -370,7 +370,9 @@ tuple
|
||||||
{ "fixnum>" "math.private" (( x y -- ? )) }
|
{ "fixnum>" "math.private" (( x y -- ? )) }
|
||||||
{ "fixnum>=" "math.private" (( x y -- ? )) }
|
{ "fixnum>=" "math.private" (( x y -- ? )) }
|
||||||
{ "(set-context)" "threads.private" (( obj context -- obj' )) }
|
{ "(set-context)" "threads.private" (( obj context -- obj' )) }
|
||||||
|
{ "(set-context-and-delete)" "threads.private" (( obj context -- * )) }
|
||||||
{ "(start-context)" "threads.private" (( obj quot -- obj' )) }
|
{ "(start-context)" "threads.private" (( obj quot -- obj' )) }
|
||||||
|
{ "(start-context-and-delete)" "threads.private" (( obj quot -- * )) }
|
||||||
} [ first3 make-sub-primitive ] each
|
} [ first3 make-sub-primitive ] each
|
||||||
|
|
||||||
! Primitive words
|
! Primitive words
|
||||||
|
@ -531,7 +533,7 @@ tuple
|
||||||
{ "set-string-nth-fast" "strings.private" "primitive_set_string_nth_fast" (( ch n string -- )) }
|
{ "set-string-nth-fast" "strings.private" "primitive_set_string_nth_fast" (( ch n string -- )) }
|
||||||
{ "set-string-nth-slow" "strings.private" "primitive_set_string_nth_slow" (( ch n string -- )) }
|
{ "set-string-nth-slow" "strings.private" "primitive_set_string_nth_slow" (( ch n string -- )) }
|
||||||
{ "string-nth" "strings.private" "primitive_string_nth" (( n string -- ch )) }
|
{ "string-nth" "strings.private" "primitive_string_nth" (( n string -- ch )) }
|
||||||
{ "(exit)" "system" "primitive_exit" (( n -- )) }
|
{ "(exit)" "system" "primitive_exit" (( n -- * )) }
|
||||||
{ "nano-count" "system" "primitive_nano_count" (( -- ns )) }
|
{ "nano-count" "system" "primitive_nano_count" (( -- ns )) }
|
||||||
{ "system-micros" "system" "primitive_system_micros" (( -- us )) }
|
{ "system-micros" "system" "primitive_system_micros" (( -- us )) }
|
||||||
{ "(sleep)" "threads.private" "primitive_sleep" (( nanos -- )) }
|
{ "(sleep)" "threads.private" "primitive_sleep" (( nanos -- )) }
|
||||||
|
@ -540,13 +542,12 @@ tuple
|
||||||
{ "context-object-for" "threads.private" "primitive_context_object_for" (( n context -- obj )) }
|
{ "context-object-for" "threads.private" "primitive_context_object_for" (( n context -- obj )) }
|
||||||
{ "datastack-for" "threads.private" "primitive_datastack_for" (( context -- array )) }
|
{ "datastack-for" "threads.private" "primitive_datastack_for" (( context -- array )) }
|
||||||
{ "retainstack-for" "threads.private" "primitive_retainstack_for" (( context -- array )) }
|
{ "retainstack-for" "threads.private" "primitive_retainstack_for" (( context -- array )) }
|
||||||
{ "delete-context" "threads.private" "primitive_delete_context" (( context -- )) }
|
|
||||||
{ "dispatch-stats" "tools.dispatch.private" "primitive_dispatch_stats" (( -- stats )) }
|
{ "dispatch-stats" "tools.dispatch.private" "primitive_dispatch_stats" (( -- stats )) }
|
||||||
{ "reset-dispatch-stats" "tools.dispatch.private" "primitive_reset_dispatch_stats" (( -- )) }
|
{ "reset-dispatch-stats" "tools.dispatch.private" "primitive_reset_dispatch_stats" (( -- )) }
|
||||||
{ "profiling" "tools.profiler.private" "primitive_profiling" (( ? -- )) }
|
{ "profiling" "tools.profiler.private" "primitive_profiling" (( ? -- )) }
|
||||||
{ "optimized?" "words" "primitive_optimized_p" (( word -- ? )) }
|
{ "optimized?" "words" "primitive_optimized_p" (( word -- ? )) }
|
||||||
{ "word-code" "words" "primitive_word_code" (( word -- start end )) }
|
{ "word-code" "words" "primitive_word_code" (( word -- start end )) }
|
||||||
{ "(word)" "words.private" "primitive_word" (( name vocab -- word )) }
|
{ "(word)" "words.private" "primitive_word" (( name vocab hashcode -- word )) }
|
||||||
} [ first4 make-primitive ] each
|
} [ first4 make-primitive ] each
|
||||||
|
|
||||||
! Bump build number
|
! Bump build number
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
! Copyright (C) 2007, 2009 Slava Pestov.
|
! Copyright (C) 2007, 2010 Slava Pestov.
|
||||||
! See http://factorcode.org/license.txt for BSD license.
|
! See http://factorcode.org/license.txt for BSD license.
|
||||||
USING: kernel kernel.private sequences math namespaces
|
USING: kernel kernel.private sequences math namespaces
|
||||||
init splitting assocs system.private layouts words ;
|
init splitting assocs system.private layouts words ;
|
||||||
|
@ -57,4 +57,4 @@ PRIVATE>
|
||||||
|
|
||||||
: embedded? ( -- ? ) 15 special-object ;
|
: embedded? ( -- ? ) 15 special-object ;
|
||||||
|
|
||||||
: exit ( n -- ) do-shutdown-hooks (exit) ;
|
: exit ( n -- * ) do-shutdown-hooks (exit) ;
|
||||||
|
|
|
@ -119,6 +119,11 @@ void factor_vm::delete_context(context *old_context)
|
||||||
active_contexts.erase(old_context);
|
active_contexts.erase(old_context);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
VM_C_API void delete_context(factor_vm *parent, context *old_context)
|
||||||
|
{
|
||||||
|
parent->delete_context(old_context);
|
||||||
|
}
|
||||||
|
|
||||||
void factor_vm::begin_callback()
|
void factor_vm::begin_callback()
|
||||||
{
|
{
|
||||||
ctx->reset();
|
ctx->reset();
|
||||||
|
@ -185,7 +190,10 @@ cell factor_vm::datastack_to_array(context *ctx)
|
||||||
{
|
{
|
||||||
cell array = stack_to_array(ctx->datastack_seg->start,ctx->datastack);
|
cell array = stack_to_array(ctx->datastack_seg->start,ctx->datastack);
|
||||||
if(array == false_object)
|
if(array == false_object)
|
||||||
|
{
|
||||||
general_error(ERROR_DATASTACK_UNDERFLOW,false_object,false_object);
|
general_error(ERROR_DATASTACK_UNDERFLOW,false_object,false_object);
|
||||||
|
return false_object;
|
||||||
|
}
|
||||||
else
|
else
|
||||||
return array;
|
return array;
|
||||||
}
|
}
|
||||||
|
@ -293,10 +301,4 @@ void factor_vm::primitive_context()
|
||||||
ctx->push(allot_alien(ctx));
|
ctx->push(allot_alien(ctx));
|
||||||
}
|
}
|
||||||
|
|
||||||
void factor_vm::primitive_delete_context()
|
|
||||||
{
|
|
||||||
context *old_context = (context *)pinned_alien_offset(ctx->pop());
|
|
||||||
delete_context(old_context);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -70,6 +70,7 @@ struct context {
|
||||||
};
|
};
|
||||||
|
|
||||||
VM_C_API context *new_context(factor_vm *parent);
|
VM_C_API context *new_context(factor_vm *parent);
|
||||||
|
VM_C_API void delete_context(factor_vm *parent, context *old_context);
|
||||||
VM_C_API void begin_callback(factor_vm *parent);
|
VM_C_API void begin_callback(factor_vm *parent);
|
||||||
VM_C_API void end_callback(factor_vm *parent);
|
VM_C_API void end_callback(factor_vm *parent);
|
||||||
|
|
||||||
|
|
|
@ -93,9 +93,6 @@ enum special_object {
|
||||||
OBJ_SLEEP_QUEUE = 66,
|
OBJ_SLEEP_QUEUE = 66,
|
||||||
|
|
||||||
OBJ_VM_COMPILER = 67, /* version string of the compiler we were built with */
|
OBJ_VM_COMPILER = 67, /* version string of the compiler we were built with */
|
||||||
|
|
||||||
OBJ_RECYCLE_THREAD = 68,
|
|
||||||
OBJ_RECYCLE_QUEUE = 69,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/* save-image-and-exit discards special objects that are filled in on startup
|
/* save-image-and-exit discards special objects that are filled in on startup
|
||||||
|
|
|
@ -50,7 +50,6 @@ namespace factor
|
||||||
_(data_room) \
|
_(data_room) \
|
||||||
_(datastack) \
|
_(datastack) \
|
||||||
_(datastack_for) \
|
_(datastack_for) \
|
||||||
_(delete_context) \
|
|
||||||
_(die) \
|
_(die) \
|
||||||
_(disable_gc_events) \
|
_(disable_gc_events) \
|
||||||
_(dispatch_stats) \
|
_(dispatch_stats) \
|
||||||
|
|
|
@ -136,7 +136,6 @@ struct factor_vm
|
||||||
void primitive_check_datastack();
|
void primitive_check_datastack();
|
||||||
void primitive_load_locals();
|
void primitive_load_locals();
|
||||||
void primitive_context();
|
void primitive_context();
|
||||||
void primitive_delete_context();
|
|
||||||
|
|
||||||
template<typename Iterator> void iterate_active_callstacks(Iterator &iter)
|
template<typename Iterator> void iterate_active_callstacks(Iterator &iter)
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in New Issue