Implement start-context and set-context primitives
parent
d98e752199
commit
1717b8d0f7
|
@ -3,7 +3,7 @@
|
||||||
USING: bootstrap.image.private kernel kernel.private namespaces
|
USING: bootstrap.image.private kernel kernel.private namespaces
|
||||||
system cpu.x86.assembler cpu.x86.assembler.operands layouts
|
system cpu.x86.assembler cpu.x86.assembler.operands layouts
|
||||||
vocabs parser compiler.constants sequences math math.private
|
vocabs parser compiler.constants sequences math math.private
|
||||||
generic.single.private ;
|
generic.single.private threads.private ;
|
||||||
IN: bootstrap.x86
|
IN: bootstrap.x86
|
||||||
|
|
||||||
4 \ cell set
|
4 \ cell set
|
||||||
|
@ -21,7 +21,7 @@ IN: bootstrap.x86
|
||||||
: vm-reg ( -- reg ) ECX ;
|
: vm-reg ( -- reg ) ECX ;
|
||||||
: ctx-reg ( -- reg ) EBP ;
|
: ctx-reg ( -- reg ) EBP ;
|
||||||
: nv-regs ( -- seq ) { ESI EDI EBX } ;
|
: nv-regs ( -- seq ) { ESI EDI EBX } ;
|
||||||
: nv-reg ( -- reg ) nv-regs first ;
|
: nv-reg ( -- reg ) EBX ;
|
||||||
: ds-reg ( -- reg ) ESI ;
|
: ds-reg ( -- reg ) ESI ;
|
||||||
: rs-reg ( -- reg ) EDI ;
|
: rs-reg ( -- reg ) EDI ;
|
||||||
: fixnum>slot@ ( -- ) temp0 2 SAR ;
|
: fixnum>slot@ ( -- ) temp0 2 SAR ;
|
||||||
|
@ -52,6 +52,7 @@ IN: bootstrap.x86
|
||||||
ctx-reg vm-reg vm-context-offset [+] MOV ;
|
ctx-reg vm-reg vm-context-offset [+] MOV ;
|
||||||
|
|
||||||
: jit-save-context ( -- )
|
: jit-save-context ( -- )
|
||||||
|
jit-load-context
|
||||||
EDX ESP -4 [+] LEA
|
EDX ESP -4 [+] LEA
|
||||||
ctx-reg context-callstack-top-offset [+] EDX MOV
|
ctx-reg context-callstack-top-offset [+] EDX MOV
|
||||||
ctx-reg context-datastack-offset [+] ds-reg MOV
|
ctx-reg context-datastack-offset [+] ds-reg MOV
|
||||||
|
@ -63,7 +64,6 @@ IN: bootstrap.x86
|
||||||
|
|
||||||
[
|
[
|
||||||
jit-load-vm
|
jit-load-vm
|
||||||
jit-load-context
|
|
||||||
jit-save-context
|
jit-save-context
|
||||||
! call the primitive
|
! call the primitive
|
||||||
ESP [] vm-reg MOV
|
ESP [] vm-reg MOV
|
||||||
|
@ -96,7 +96,6 @@ IN: bootstrap.x86
|
||||||
EAX quot-entry-point-offset [+] CALL
|
EAX quot-entry-point-offset [+] CALL
|
||||||
|
|
||||||
jit-load-vm
|
jit-load-vm
|
||||||
jit-load-context
|
|
||||||
jit-save-context
|
jit-save-context
|
||||||
|
|
||||||
! load C callstack pointer
|
! load C callstack pointer
|
||||||
|
@ -167,7 +166,6 @@ IN: bootstrap.x86
|
||||||
|
|
||||||
[
|
[
|
||||||
jit-load-vm
|
jit-load-vm
|
||||||
jit-load-context
|
|
||||||
jit-save-context
|
jit-save-context
|
||||||
|
|
||||||
! Store arguments
|
! Store arguments
|
||||||
|
@ -189,7 +187,6 @@ IN: bootstrap.x86
|
||||||
! frame, and the stack. The frame setup takes this into account.
|
! frame, and the stack. The frame setup takes this into account.
|
||||||
: jit-inline-cache-miss ( -- )
|
: jit-inline-cache-miss ( -- )
|
||||||
jit-load-vm
|
jit-load-vm
|
||||||
jit-load-context
|
|
||||||
jit-save-context
|
jit-save-context
|
||||||
ESP 4 [+] vm-reg MOV
|
ESP 4 [+] vm-reg MOV
|
||||||
ESP [] EBX MOV
|
ESP [] EBX MOV
|
||||||
|
@ -210,7 +207,6 @@ IN: bootstrap.x86
|
||||||
: jit-overflow ( insn func -- )
|
: jit-overflow ( insn func -- )
|
||||||
ds-reg 4 SUB
|
ds-reg 4 SUB
|
||||||
jit-load-vm
|
jit-load-vm
|
||||||
jit-load-context
|
|
||||||
jit-save-context
|
jit-save-context
|
||||||
EAX ds-reg [] MOV
|
EAX ds-reg [] MOV
|
||||||
EDX ds-reg 4 [+] MOV
|
EDX ds-reg 4 [+] MOV
|
||||||
|
@ -233,7 +229,6 @@ IN: bootstrap.x86
|
||||||
[
|
[
|
||||||
ds-reg 4 SUB
|
ds-reg 4 SUB
|
||||||
jit-load-vm
|
jit-load-vm
|
||||||
jit-load-context
|
|
||||||
jit-save-context
|
jit-save-context
|
||||||
EBX ds-reg [] MOV
|
EBX ds-reg [] MOV
|
||||||
EAX EBX MOV
|
EAX EBX MOV
|
||||||
|
@ -252,5 +247,58 @@ IN: bootstrap.x86
|
||||||
jit-conditional
|
jit-conditional
|
||||||
] \ fixnum* define-sub-primitive
|
] \ fixnum* define-sub-primitive
|
||||||
|
|
||||||
|
! Threads
|
||||||
|
: jit-set-context ( reg -- )
|
||||||
|
! Save ds, rs registers
|
||||||
|
jit-load-vm
|
||||||
|
jit-save-context
|
||||||
|
|
||||||
|
! Make the new context the current one
|
||||||
|
ctx-reg swap MOV
|
||||||
|
vm-reg vm-context-offset [+] ctx-reg MOV
|
||||||
|
|
||||||
|
! Load new stack pointer
|
||||||
|
ESP ctx-reg context-callstack-top-offset [+] MOV
|
||||||
|
|
||||||
|
! Load new ds, rs registers
|
||||||
|
jit-restore-context ;
|
||||||
|
|
||||||
|
[
|
||||||
|
! Create the new context in return-reg
|
||||||
|
jit-load-vm
|
||||||
|
ESP [] vm-reg MOV
|
||||||
|
"new_context" jit-call
|
||||||
|
|
||||||
|
! Save pointer to quotation and parameter, pop them off the
|
||||||
|
! datastack
|
||||||
|
EBX ds-reg MOV
|
||||||
|
ds-reg 8 SUB
|
||||||
|
|
||||||
|
! Make the new context the active context
|
||||||
|
EAX jit-set-context
|
||||||
|
|
||||||
|
! Push parameter
|
||||||
|
EAX EBX -4 [+] MOV
|
||||||
|
ds-reg 4 ADD
|
||||||
|
ds-reg [] EAX MOV
|
||||||
|
|
||||||
|
! Jump to initial quotation
|
||||||
|
EAX EBX [] MOV
|
||||||
|
EAX quot-entry-point-offset [+] JMP
|
||||||
|
] \ (start-context) define-sub-primitive
|
||||||
|
|
||||||
|
[
|
||||||
|
! Load context from datastack
|
||||||
|
EAX ds-reg [] MOV
|
||||||
|
EAX EAX alien-offset [+] MOV
|
||||||
|
ds-reg 4 SUB
|
||||||
|
|
||||||
|
! Make it the active context
|
||||||
|
EAX jit-set-context
|
||||||
|
|
||||||
|
! Twiddle stack for return
|
||||||
|
ESP 4 ADD
|
||||||
|
] \ (set-context) define-sub-primitive
|
||||||
|
|
||||||
<< "vocab:cpu/x86/bootstrap.factor" parse-file suffix! >>
|
<< "vocab:cpu/x86/bootstrap.factor" parse-file suffix! >>
|
||||||
call
|
call
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
USING: bootstrap.image.private kernel kernel.private namespaces
|
USING: bootstrap.image.private kernel kernel.private namespaces
|
||||||
system layouts vocabs parser compiler.constants math
|
system layouts vocabs parser compiler.constants math
|
||||||
math.private cpu.x86.assembler cpu.x86.assembler.operands
|
math.private cpu.x86.assembler cpu.x86.assembler.operands
|
||||||
sequences generic.single.private ;
|
sequences generic.single.private threads.private ;
|
||||||
IN: bootstrap.x86
|
IN: bootstrap.x86
|
||||||
|
|
||||||
8 \ cell set
|
8 \ cell set
|
||||||
|
@ -16,7 +16,7 @@ IN: bootstrap.x86
|
||||||
: temp2 ( -- reg ) RDX ;
|
: temp2 ( -- reg ) RDX ;
|
||||||
: temp3 ( -- reg ) RBX ;
|
: temp3 ( -- reg ) RBX ;
|
||||||
: return-reg ( -- reg ) RAX ;
|
: return-reg ( -- reg ) RAX ;
|
||||||
: nv-reg ( -- reg ) nv-regs first ;
|
: nv-reg ( -- reg ) RBX ;
|
||||||
: stack-reg ( -- reg ) RSP ;
|
: stack-reg ( -- reg ) RSP ;
|
||||||
: frame-reg ( -- reg ) RBP ;
|
: frame-reg ( -- reg ) RBP ;
|
||||||
: ctx-reg ( -- reg ) R12 ;
|
: ctx-reg ( -- reg ) R12 ;
|
||||||
|
@ -51,8 +51,8 @@ IN: bootstrap.x86
|
||||||
|
|
||||||
: jit-save-context ( -- )
|
: jit-save-context ( -- )
|
||||||
jit-load-context
|
jit-load-context
|
||||||
RAX RSP -8 [+] LEA
|
R11 RSP -8 [+] LEA
|
||||||
ctx-reg context-callstack-top-offset [+] RAX MOV
|
ctx-reg context-callstack-top-offset [+] R11 MOV
|
||||||
ctx-reg context-datastack-offset [+] ds-reg MOV
|
ctx-reg context-datastack-offset [+] ds-reg MOV
|
||||||
ctx-reg context-retainstack-offset [+] rs-reg MOV ;
|
ctx-reg context-retainstack-offset [+] rs-reg MOV ;
|
||||||
|
|
||||||
|
@ -222,5 +222,57 @@ IN: bootstrap.x86
|
||||||
jit-conditional
|
jit-conditional
|
||||||
] \ fixnum* define-sub-primitive
|
] \ fixnum* define-sub-primitive
|
||||||
|
|
||||||
|
! Threads
|
||||||
|
: jit-set-context ( reg -- )
|
||||||
|
! Save ds, rs registers
|
||||||
|
jit-save-context
|
||||||
|
|
||||||
|
! Make the new context the current one
|
||||||
|
ctx-reg swap MOV
|
||||||
|
vm-reg vm-context-offset [+] ctx-reg MOV
|
||||||
|
|
||||||
|
! Load new stack pointer
|
||||||
|
RSP ctx-reg context-callstack-top-offset [+] MOV
|
||||||
|
|
||||||
|
! Load new ds, rs registers
|
||||||
|
jit-restore-context ;
|
||||||
|
|
||||||
|
[
|
||||||
|
! Create the new context in return-reg
|
||||||
|
arg1 vm-reg MOV
|
||||||
|
"new_context" jit-call
|
||||||
|
|
||||||
|
! Load quotation from datastack
|
||||||
|
arg1 ds-reg [] MOV
|
||||||
|
|
||||||
|
! Load parameter from datastack
|
||||||
|
arg2 ds-reg -8 [+] MOV
|
||||||
|
|
||||||
|
ds-reg 16 SUB
|
||||||
|
|
||||||
|
! Make the new context the active context
|
||||||
|
return-reg jit-set-context
|
||||||
|
|
||||||
|
! Push parameter
|
||||||
|
ds-reg 8 ADD
|
||||||
|
ds-reg [] arg2 MOV
|
||||||
|
|
||||||
|
! Jump to initial quotation
|
||||||
|
arg1 quot-entry-point-offset [+] JMP
|
||||||
|
] \ (start-context) define-sub-primitive
|
||||||
|
|
||||||
|
[
|
||||||
|
! Load context from datastack
|
||||||
|
temp0 ds-reg [] MOV
|
||||||
|
temp0 temp0 alien-offset [+] MOV
|
||||||
|
ds-reg 8 SUB
|
||||||
|
|
||||||
|
! Make it the active context
|
||||||
|
temp0 jit-set-context
|
||||||
|
|
||||||
|
! Twiddle stack for return
|
||||||
|
RSP 8 ADD
|
||||||
|
] \ (set-context) define-sub-primitive
|
||||||
|
|
||||||
<< "vocab:cpu/x86/bootstrap.factor" parse-file suffix! >>
|
<< "vocab:cpu/x86/bootstrap.factor" parse-file suffix! >>
|
||||||
call
|
call
|
||||||
|
|
|
@ -42,7 +42,8 @@ big-endian off
|
||||||
nv-reg 0 MOV rc-absolute-cell rt-entry-point jit-rel
|
nv-reg 0 MOV rc-absolute-cell rt-entry-point jit-rel
|
||||||
nv-reg CALL
|
nv-reg CALL
|
||||||
|
|
||||||
! Load VM into vm-reg
|
! Load VM into vm-reg; only needed on x86-32, but doesn't
|
||||||
|
! hurt on x86-64
|
||||||
vm-reg 0 MOV rc-absolute-cell rt-vm jit-rel
|
vm-reg 0 MOV rc-absolute-cell rt-vm jit-rel
|
||||||
|
|
||||||
! Load C callstack pointer
|
! Load C callstack pointer
|
||||||
|
|
|
@ -513,7 +513,9 @@ M: bad-executable summary
|
||||||
|
|
||||||
\ delete-context { c-ptr } { } define-primitive
|
\ delete-context { c-ptr } { } define-primitive
|
||||||
|
|
||||||
\ start-context { quotation } { } define-primitive
|
\ (start-context) { object quotation } { } define-primitive
|
||||||
|
|
||||||
|
\ (set-context) { alien } { } define-primitive
|
||||||
|
|
||||||
\ special-object { fixnum } { object } define-primitive
|
\ special-object { fixnum } { object } define-primitive
|
||||||
\ special-object make-flushable
|
\ special-object make-flushable
|
||||||
|
|
|
@ -7,6 +7,16 @@ dlists assocs system combinators combinators.private init boxes
|
||||||
accessors math.order deques strings quotations fry ;
|
accessors math.order deques strings quotations fry ;
|
||||||
IN: threads
|
IN: threads
|
||||||
|
|
||||||
|
<PRIVATE
|
||||||
|
|
||||||
|
! (set-context) and (start-context) are sub-primitives, but
|
||||||
|
! we don't want them inlined into callers since their behavior
|
||||||
|
! depends on what frames are on the callstack
|
||||||
|
: start-context ( obj quot: ( obj -- * ) -- ) (start-context) ;
|
||||||
|
: set-context ( context -- ) (set-context) ;
|
||||||
|
|
||||||
|
PRIVATE>
|
||||||
|
|
||||||
SYMBOL: initial-thread
|
SYMBOL: initial-thread
|
||||||
|
|
||||||
TUPLE: thread
|
TUPLE: thread
|
||||||
|
|
|
@ -369,6 +369,8 @@ tuple
|
||||||
{ "fixnum<=" "math.private" (( x y -- z )) }
|
{ "fixnum<=" "math.private" (( x y -- z )) }
|
||||||
{ "fixnum>" "math.private" (( x y -- ? )) }
|
{ "fixnum>" "math.private" (( x y -- ? )) }
|
||||||
{ "fixnum>=" "math.private" (( x y -- ? )) }
|
{ "fixnum>=" "math.private" (( x y -- ? )) }
|
||||||
|
{ "(set-context)" "threads.private" (( context -- )) }
|
||||||
|
{ "(start-context)" "threads.private" (( obj quot -- )) }
|
||||||
} [ first3 make-sub-primitive ] each
|
} [ first3 make-sub-primitive ] each
|
||||||
|
|
||||||
! Primitive words
|
! Primitive words
|
||||||
|
@ -534,9 +536,8 @@ tuple
|
||||||
{ "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 -- )) }
|
||||||
{ "current-context" "threads.private" "primitive_current_context" (( -- c-ptr )) }
|
{ "context" "threads.private" "primitive_context" (( -- c-ptr )) }
|
||||||
{ "delete-context" "threads.private" "primitive_delete_context" (( c-ptr -- )) }
|
{ "delete-context" "threads.private" "primitive_delete_context" (( c-ptr -- )) }
|
||||||
{ "start-context" "threads.private" "primitive_start_context" (( quot -- )) }
|
|
||||||
{ "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" (( ? -- )) }
|
||||||
|
|
|
@ -97,6 +97,11 @@ context *factor_vm::new_context()
|
||||||
return new_context;
|
return new_context;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
context *new_context(factor_vm *parent)
|
||||||
|
{
|
||||||
|
return parent->new_context();
|
||||||
|
}
|
||||||
|
|
||||||
void factor_vm::delete_context(context *old_context)
|
void factor_vm::delete_context(context *old_context)
|
||||||
{
|
{
|
||||||
unused_contexts.push_back(old_context);
|
unused_contexts.push_back(old_context);
|
||||||
|
@ -225,18 +230,11 @@ void factor_vm::primitive_load_locals()
|
||||||
ctx->retainstack += sizeof(cell) * count;
|
ctx->retainstack += sizeof(cell) * count;
|
||||||
}
|
}
|
||||||
|
|
||||||
void factor_vm::primitive_current_context()
|
void factor_vm::primitive_context()
|
||||||
{
|
{
|
||||||
ctx->push(allot_alien(ctx));
|
ctx->push(allot_alien(ctx));
|
||||||
}
|
}
|
||||||
|
|
||||||
void factor_vm::primitive_start_context()
|
|
||||||
{
|
|
||||||
cell quot = ctx->pop();
|
|
||||||
ctx = new_context();
|
|
||||||
unwind_native_frames(quot,ctx->callstack_bottom);
|
|
||||||
}
|
|
||||||
|
|
||||||
void factor_vm::primitive_delete_context()
|
void factor_vm::primitive_delete_context()
|
||||||
{
|
{
|
||||||
context *old_context = (context *)pinned_alien_offset(ctx->pop());
|
context *old_context = (context *)pinned_alien_offset(ctx->pop());
|
||||||
|
|
|
@ -79,7 +79,8 @@ struct context {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
VM_C_API void begin_callback(factor_vm *vm);
|
VM_C_API context *new_context(factor_vm *parent);
|
||||||
VM_C_API void end_callback(factor_vm *vm);
|
VM_C_API void begin_callback(factor_vm *parent);
|
||||||
|
VM_C_API void end_callback(factor_vm *parent);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -43,9 +43,9 @@ namespace factor
|
||||||
_(code_room) \
|
_(code_room) \
|
||||||
_(compact_gc) \
|
_(compact_gc) \
|
||||||
_(compute_identity_hashcode) \
|
_(compute_identity_hashcode) \
|
||||||
|
_(context) \
|
||||||
_(context_object) \
|
_(context_object) \
|
||||||
_(current_callback) \
|
_(current_callback) \
|
||||||
_(current_context) \
|
|
||||||
_(data_room) \
|
_(data_room) \
|
||||||
_(datastack) \
|
_(datastack) \
|
||||||
_(delete_context) \
|
_(delete_context) \
|
||||||
|
@ -122,7 +122,6 @@ namespace factor
|
||||||
_(size) \
|
_(size) \
|
||||||
_(sleep) \
|
_(sleep) \
|
||||||
_(special_object) \
|
_(special_object) \
|
||||||
_(start_context) \
|
|
||||||
_(string) \
|
_(string) \
|
||||||
_(string_nth) \
|
_(string_nth) \
|
||||||
_(strip_stack_traces) \
|
_(strip_stack_traces) \
|
||||||
|
|
|
@ -125,8 +125,7 @@ struct factor_vm
|
||||||
void primitive_set_retainstack();
|
void primitive_set_retainstack();
|
||||||
void primitive_check_datastack();
|
void primitive_check_datastack();
|
||||||
void primitive_load_locals();
|
void primitive_load_locals();
|
||||||
void primitive_current_context();
|
void primitive_context();
|
||||||
void primitive_start_context();
|
|
||||||
void primitive_delete_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