From a9f90026dfca55e01e1a5c31ba17c2b335b31892 Mon Sep 17 00:00:00 2001 From: Slava Pestov Date: Wed, 6 Jan 2010 17:55:20 +1300 Subject: [PATCH] Update x86-32 for assembly entry point changes --- basis/compiler/constants/constants.factor | 5 + basis/cpu/x86/32/bootstrap.factor | 120 ++++++++++++++---- basis/cpu/x86/64/bootstrap.factor | 20 +-- vm/cpu-x86.32.S | 141 ---------------------- vm/entry_points.cpp | 7 ++ vm/entry_points.hpp | 1 + vm/factor.cpp | 6 +- vm/vm.hpp | 2 +- 8 files changed, 123 insertions(+), 179 deletions(-) diff --git a/basis/compiler/constants/constants.factor b/basis/compiler/constants/constants.factor index bc7f037b4a..499a1b192f 100644 --- a/basis/compiler/constants/constants.factor +++ b/basis/compiler/constants/constants.factor @@ -27,6 +27,11 @@ CONSTANT: deck-bits 18 : 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 +: vm-context-offset ( -- n ) 0 bootstrap-cells ; inline +: context-callstack-top-offset ( -- n ) 0 bootstrap-cells ; inline +: context-callstack-bottom-offset ( -- n ) 1 bootstrap-cells ; inline +: context-datastack-offset ( -- n ) 2 bootstrap-cells ; inline +: context-retainstack-offset ( -- n ) 3 bootstrap-cells ; inline ! Relocation classes CONSTANT: rc-absolute-cell 0 diff --git a/basis/cpu/x86/32/bootstrap.factor b/basis/cpu/x86/32/bootstrap.factor index 9c57804e3a..afcae6d4d9 100644 --- a/basis/cpu/x86/32/bootstrap.factor +++ b/basis/cpu/x86/32/bootstrap.factor @@ -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. USING: bootstrap.image.private kernel kernel.private namespaces system cpu.x86.assembler cpu.x86.assembler.operands layouts @@ -19,6 +19,8 @@ IN: bootstrap.x86 : safe-reg ( -- reg ) EAX ; : stack-reg ( -- reg ) ESP ; : frame-reg ( -- reg ) EBP ; +: vm-reg ( -- reg ) EBP ; +: ctx-reg ( -- reg ) ECX ; : nv-regs ( -- seq ) { ESI EDI EBX } ; : ds-reg ( -- reg ) ESI ; : rs-reg ( -- reg ) EDI ; @@ -35,50 +37,120 @@ IN: bootstrap.x86 ] jit-prolog jit-define : jit-load-vm ( -- ) - EBP 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 vm-context-offset [+] MOV ; : jit-save-context ( -- ) - ! VM pointer must be in EBP already - ECX EBP [] MOV - ! save ctx->callstack_top - EAX ESP -4 [+] LEA - ECX [] EAX MOV - ! save ctx->datastack - ECX 8 [+] ds-reg MOV - ! save ctx->retainstack - ECX 12 [+] rs-reg MOV ; + jit-load-context + EDX RSP -4 [+] LEA + ctx-reg context-callstack-top-offset [+] EDX MOV + ctx-reg context-datastack-offset [+] ds-reg MOV + ctx-reg context-retainstack-offset [+] rs-reg MOV ; : jit-restore-context ( -- ) - ! VM pointer must be in EBP already - ECX EBP [] MOV - ! restore ctx->datastack - ds-reg ECX 8 [+] MOV - ! restore ctx->retainstack - rs-reg ECX 12 [+] MOV ; + jit-load-context + ds-reg ctx-reg context-datastack-offset [+] MOV + rs-reg ctx-reg context-retainstack-offset [+] MOV ; [ jit-load-vm - ! save ds, rs registers jit-save-context ! call the primitive - ESP [] EBP MOV + ESP [] vm-reg MOV 0 CALL rc-relative rt-primitive jit-rel ! restore ds, rs registers jit-restore-context ] jit-primitive jit-define [ - ! load from stack + ! Load quotation + EAX EBP 8 [+] MOV + ! save ctx->callstack_bottom, load ds, rs registers + jit-load-vm + jit-restore-context + EDX stack-reg stack-frame-size 4 - [+] LEA + ctx-reg context-callstack-bottom-offset [+] EDX MOV + ! call the quotation + EAX quot-xt-offset [+] CALL + ! save ds, rs registers + jit-save-context +] \ c-to-factor define-sub-primitive + +[ EAX ds-reg [] MOV - ! pop stack ds-reg bootstrap-cell SUB - ! load VM pointer - EDX 0 MOV 0 rc-absolute-cell jit-vm ] [ EAX quot-xt-offset [+] CALL ] [ EAX quot-xt-offset [+] JMP ] \ (call) define-combinator-primitive +[ + ! Clear x87 stack, but preserve rounding mode and exception flags + ESP 2 SUB + ESP [] FNSTCW + FNINIT + ESP [] FLDCW + ESP 2 ADD + + ! Load arguments + EAX ESP stack-frame-size [+] MOV + EDX ESP stack-frame-size 4 + [+] MOV + + ! Unwind stack frames + ESP EDX MOV + + ! Load ds and rs registers + jit-load-vm + jit-restore-context + + ! Call quotation + EAX quot-xt-offset [+] JMP +] \ unwind-native-frames define-sub-primitive + +[ + ! Load callstack object + EBX ds-reg [] MOV + ds-reg bootstrap-cell SUB + ! Get ctx->callstack_bottom + jit-load-vm + jit-load-context + EAX ctx-reg context-callstack-bottom-offset [+] MOV + ! Get top of callstack object -- 'src' for memcpy + EBP EBX callstack-top-offset [+] LEA + ! Get callstack length, in bytes --- 'len' for memcpy + EDX EBX callstack-length-offset [+] MOV + EDX tag-bits get SHR + ! Compute new stack pointer -- 'dst' for memcpy + EAX EDX SUB + ! Install new stack pointer + RSP EAX MOV + ! Call memcpy + ESP 8 [+] EDX MOV + ESP 4 [+] EBP MOV + ESP [] EAX MOV + 0 CALL "memcpy" f rc-relative jit-dlsym + ! Return with new callstack + 0 RET +] \ set-callstack define-sub-primitive + +[ + jit-load-vm + jit-save-context + + ! Store arguments + ESP [] EAX MOV + ESP 4 [+] vm-reg MOV + + ! Call VM + 0 CALL "lazy_jit_compile" f rc-relative jit-dlsym +] +[ EAX quot-xt-offset [+] CALL ] +[ EAX quot-xt-offset [+] JMP ] +\ lazy-jit-compile define-combinator-primitive + ! Inline cache miss entry points : jit-load-return-address ( -- ) EBX ESP stack-frame-size bootstrap-cell - [+] MOV ; @@ -88,7 +160,7 @@ IN: bootstrap.x86 : jit-inline-cache-miss ( -- ) jit-load-vm jit-save-context - ESP 4 [+] EBP MOV + ESP 4 [+] vm-reg MOV ESP [] EBX MOV 0 CALL "inline_cache_miss" f rc-relative jit-dlsym jit-restore-context ; diff --git a/basis/cpu/x86/64/bootstrap.factor b/basis/cpu/x86/64/bootstrap.factor index 4c059141af..55dba215d7 100644 --- a/basis/cpu/x86/64/bootstrap.factor +++ b/basis/cpu/x86/64/bootstrap.factor @@ -4,7 +4,6 @@ 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 @@ -43,19 +42,19 @@ IN: bootstrap.x86 : jit-load-context ( -- ) ! VM pointer must be in vm-reg already - ctx-reg vm-reg "ctx" vm-field-offset [+] MOV ; + ctx-reg vm-reg vm-context-offset [+] MOV ; : jit-save-context ( -- ) 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 ; + ctx-reg context-callstack-top-offset [+] safe-reg MOV + ctx-reg context-datastack-offset [+] ds-reg MOV + ctx-reg context-retainstack-offset [+] rs-reg MOV ; : jit-restore-context ( -- ) jit-load-context - ds-reg ctx-reg "datastack" context-field-offset [+] MOV - rs-reg ctx-reg "retainstack" context-field-offset [+] MOV ; + ds-reg ctx-reg context-datastack-offset [+] MOV + rs-reg ctx-reg context-retainstack-offset [+] MOV ; [ jit-load-vm @@ -71,8 +70,8 @@ IN: bootstrap.x86 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 + safe-reg stack-reg stack-frame-size 8 - [+] LEA + ctx-reg context-callstack-bottom-offset [+] safe-reg MOV ! call the quotation arg1 quot-xt-offset [+] CALL jit-save-context @@ -111,7 +110,7 @@ IN: bootstrap.x86 ! Get ctx->callstack_bottom jit-load-vm jit-load-context - arg1 ctx-reg "callstack-bottom" context-field-offset [+] MOV + arg1 ctx-reg context-callstack-bottom-offset [+] MOV ! Get top of callstack object -- 'src' for memcpy arg2 arg4 callstack-top-offset [+] LEA ! Get callstack length, in bytes --- 'len' for memcpy @@ -119,6 +118,7 @@ IN: bootstrap.x86 arg3 tag-bits get SHR ! Compute new stack pointer -- 'dst' for memcpy arg1 arg3 SUB + ! Install new stack pointer RSP arg1 MOV ! Call memcpy; arguments are now in the correct registers safe-reg 0 MOV "memcpy" f rc-absolute-cell jit-dlsym diff --git a/vm/cpu-x86.32.S b/vm/cpu-x86.32.S index ee3ec25aa3..2ebece637d 100644 --- a/vm/cpu-x86.32.S +++ b/vm/cpu-x86.32.S @@ -1,148 +1,7 @@ #include "asm.h" -#define DS_REG %esi -#define RS_REG %edi #define RETURN_REG %eax -#define QUOT_XT_OFFSET 12 - -DEF(void,c_to_factor,(cell quot, void *vm)): - /* Load parameters */ - mov 4(%esp),%eax - mov 8(%esp),%edx - - /* Save non-volatile registers */ - push %ebx - push %ebp - push %esi - push %edi - - /* Save old stack pointer and align */ - mov %esp,%ebx - and $-16,%esp - push %ebx - - /* Set up stack frame for the call to the boot quotation */ - sub $4,%esp - push %edx - push %eax - - /* Load context */ - mov (%edx),%ecx - - /* Load ctx->datastack */ - mov 8(%ecx),DS_REG - - /* Load ctx->retainstack */ - mov 12(%ecx),RS_REG - - /* Save ctx->callstack_bottom */ - lea -4(%esp),%ebx - mov %ebx,4(%ecx) - - /* Call quot-xt */ - call *QUOT_XT_OFFSET(%eax) - - /* Tear down stack frame for the call to the boot quotation */ - pop %eax - pop %edx - add $4,%esp - - /* Undo stack alignment */ - mov (%esp),%esp - - /* Load context */ - mov (%edx),%ecx - - /* Save ctx->datastack */ - mov DS_REG,8(%ecx) - - /* Save ctx->retainstack */ - mov RS_REG,12(%ecx) - - /* Restore non-volatile registers */ - pop %edi - pop %esi - pop %ebp - pop %ebx - - ret - -DEF(void,set_callstack,(void *vm, stack_frame *to, stack_frame *from, cell length, void *memcpy)): - /* load arguments */ - mov 4(%esp),%ebx /* vm - to non-volatile register */ - mov 8(%esp),%ebp /* to */ - mov 12(%esp),%edx /* from */ - mov 16(%esp),%ecx /* length */ - mov 20(%esp),%eax /* memcpy */ - - /* compute new stack pointer */ - sub %ecx,%ebp - mov %ebp,%esp - - /* call memcpy */ - push %ecx /* pass length */ - push %edx /* pass src */ - push %ebp /* pass dst */ - call *%eax - add $12,%esp - - /* load context */ - mov (%ebx),%ecx - /* load datastack */ - mov 8(%ecx),DS_REG - /* load retainstack */ - mov 12(%ecx),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,%esp - fnstcw (%esp) - fninit - fldcw (%esp) - add $2,%esp - - /* load quotation and vm parameters */ - mov 4(%esp),%eax - mov 12(%esp),%edx - - /* load new stack pointer */ - mov 8(%esp),%esp - - /* load context */ - mov (%edx),%ecx - /* load datastack */ - mov 8(%ecx),DS_REG - /* load retainstack */ - mov 12(%ecx),RS_REG - - /* call the error handler */ - jmp *QUOT_XT_OFFSET(%eax) - -DEF(void,lazy_jit_compile_impl,(cell quot, void *vm)): - /* load context */ - mov (%edx),%ecx - /* save datastack */ - mov DS_REG,8(%ecx) - /* save retainstack */ - mov RS_REG,12(%ecx) - /* save callstack */ - lea -4(%esp),%ebp - mov %ebp,(%ecx) - - /* compile quotation */ - sub $4,%esp - push %edx - push %eax - call MANGLE(lazy_jit_compile) - add $12,%esp - - /* call quotation */ - jmp *QUOT_XT_OFFSET(%eax) - DEF(long long,read_timestamp_counter,(void)): rdtsc ret diff --git a/vm/entry_points.cpp b/vm/entry_points.cpp index 87a3c056e2..f5f37ce00e 100644 --- a/vm/entry_points.cpp +++ b/vm/entry_points.cpp @@ -19,4 +19,11 @@ void factor_vm::c_to_factor(cell quot) c_to_factor_func(quot); } +void factor_vm::unwind_native_frames(cell quot, stack_frame *to) +{ + tagged unwind_native_frames_word(special_objects[UNWIND_NATIVE_FRAMES_WORD]); + unwind_native_frames_func_type unwind_native_frames_func = (unwind_native_frames_func_type)unwind_native_frames_word->xt; + unwind_native_frames_func(quot,to); +} + } diff --git a/vm/entry_points.hpp b/vm/entry_points.hpp index 663eb7dbb4..873501f235 100644 --- a/vm/entry_points.hpp +++ b/vm/entry_points.hpp @@ -2,5 +2,6 @@ namespace factor { typedef void (* c_to_factor_func_type)(cell quot); +typedef void (* unwind_native_frames_func_type)(cell quot, stack_frame *to); } diff --git a/vm/factor.cpp b/vm/factor.cpp index 46eb2efdfd..453ec71682 100755 --- a/vm/factor.cpp +++ b/vm/factor.cpp @@ -79,8 +79,8 @@ void factor_vm::init_parameters_from_args(vm_parameters *p, int argc, vm_char ** } } -/* Do some initialization that we do once only */ -void factor_vm::do_stage1_init() +/* Compile code in boot image so that we can execute the startup quotation */ +void factor_vm::prepare_boot_image() { std::cout << "*** Stage 2 early init... "; fflush(stdout); @@ -146,7 +146,7 @@ void factor_vm::init_factor(vm_parameters *p) gc_off = false; if(!to_boolean(special_objects[OBJ_STAGE2])) - do_stage1_init(); + prepare_boot_image(); } /* May allocate memory */ diff --git a/vm/vm.hpp b/vm/vm.hpp index 3a87857488..5f0858dab3 100755 --- a/vm/vm.hpp +++ b/vm/vm.hpp @@ -645,7 +645,7 @@ struct factor_vm void default_parameters(vm_parameters *p); 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 prepare_boot_image(); void init_factor(vm_parameters *p); void pass_args_to_factor(int argc, vm_char **argv); void start_factor(vm_parameters *p);