* src/vm/jit/i386/asmpart.S (asm_replacement_out): Added pv.
[cacao.git] / src / vm / jit / i386 / asmpart.S
index 3a73e902c93682ecf4c14778e2782f6ec5f5fd26..501ab37b56488728eea2ec28cc141e2ad47ee736 100644 (file)
@@ -29,8 +29,9 @@
             Christian Thalinger
 
    Changes: Joseph Wenninger
+            Edwin Steiner
 
-   $Id: asmpart.S 4440 2006-02-05 12:03:43Z twisti $
+   $Id: asmpart.S 4643 2006-03-16 18:38:42Z edwin $
 
 */
 
@@ -41,6 +42,7 @@
 #include "vm/jit/i386/md-abi.h"
 #include "vm/jit/i386/md-asm.h"
 #include "vm/jit/i386/offsets.h"
+#include "vm/jit/i386/arch.h"
 
 #include "vm/jit/methodheader.h"
 
 
        .globl asm_md_init
 
-       .globl asm_calljavafunction
-       .globl asm_calljavafunction_int
-
-       .globl asm_calljavafunction2
-       .globl asm_calljavafunction2int
-       .globl asm_calljavafunction2long
-       .globl asm_calljavafunction2float
-       .globl asm_calljavafunction2double
+       .globl asm_vm_call_method
+       .globl asm_vm_call_method_int
+       .globl asm_vm_call_method_long
+       .globl asm_vm_call_method_float
+       .globl asm_vm_call_method_double
 
        .globl asm_call_jit_compiler
        .globl asm_handle_nat_exception
@@ -67,6 +66,9 @@
 
        .globl asm_wrapper_patcher
 
+       .globl asm_replacement_out
+       .globl asm_replacement_in
+
        .globl asm_builtin_f2i
        .globl asm_builtin_f2l
        .globl asm_builtin_d2i
@@ -115,80 +117,7 @@ asm_md_init:
 *   method into machine code.                                                  *
 *                                                                              *
 *   C-prototype:                                                               *
-*    javaobject_header *asm_calljavamethod (methodinfo *m,                     *
-*         void *arg1, void *arg2, void *arg3, void *arg4);                     *
-*                                                                              *
-*******************************************************************************/
-
-       .align  8
-
-       .long   0                           /* catch type all                     */
-       .long   calljava_xhandler           /* handler pc                         */
-       .long   calljava_xhandler           /* end pc                             */
-       .long   asm_calljavafunction        /* start pc                           */
-       .long   1                           /* extable size                       */
-       .long   0                           /* line number table start            */
-       .long   0                           /* line number table size             */
-       .long   0                           /* fltsave                            */
-       .long   0                           /* intsave                            */
-       .long   0                           /* isleaf                             */
-       .long   0                           /* IsSync                             */
-       .long   0                           /* frame size                         */
-       .long   0                           /* method pointer (pointer to name)   */
-
-asm_calljavafunction:
-asm_calljavafunction_int:
-       push    bp                          /* allocate stack space               */
-       mov     sp,bp
-
-       push    %ebx                        /* save registers                     */
-       push    %esi
-       push    %edi
-
-       sub             $(4*4),sp                   /* 4 adress parameters * 4 Bytes      */
-       mov     5*4(bp),itmp1               /* copy adress parameters to new block*/
-       mov     itmp1,3*4(sp)
-               
-       mov     5*4(bp),itmp1
-       mov     itmp1,2*4(sp)
-
-       mov     4*4(bp),itmp1
-       mov     itmp1,1*4(sp)
-
-       mov     3*4(bp),itmp1
-       mov     itmp1,0*4(sp)
-               
-       mov     2*4(bp),itmp1               /* move function pointer to %eax      */
-
-       lea     asm_call_jit_compiler,itmp3
-       call    *itmp3                      /* call JIT compiler                  */
-
-L_asm_calljavafunction_return:
-       add     $(4*4),sp
-       pop     %edi                        /* restore registers                  */
-       pop     %esi
-       pop     %ebx
-       leave
-       ret
-
-calljava_xhandler:
-       push    xptr                        /* pass exception pointer             */
-       call    builtin_throw_exception
-       add     $4,sp
-       xor     v0,v0                       /* return NULL                        */
-       jmp     L_asm_calljavafunction_return
-
-
-/********************* function asm_calljavafunction ***************************
-*                                                                              *
-*   This function calls a Java-method (which possibly needs compilation)       *
-*   with up to 4 address parameters.                                           *
-*                                                                              *
-*   This functions calls the JIT-compiler which eventually translates the      *
-*   method into machine code.                                                  *
-*                                                                              *
-*   C-prototype:                                                               *
-*    javaobject_header *asm_calljavafunction2(methodinfo *m,                   *
+*    javaobject_header *asm_vm_call_method(methodinfo *m,                      *
 *         u4 count, u4 size, void *callblock);                                 *
 *                                                                              *
 *******************************************************************************/
@@ -198,7 +127,7 @@ calljava_xhandler:
        .long   0                           /* catch type all                     */
        .long   calljava_xhandler2          /* handler pc                         */
        .long   calljava_xhandler2          /* end pc                             */
-       .long   asm_calljavafunction2       /* start pc                           */
+       .long   L_asm_vm_call_method        /* start pc                           */
        .long   1                           /* extable size                       */
        .long   0                           /* line number table start            */
        .long   0                           /* line number table size             */
@@ -209,20 +138,21 @@ calljava_xhandler:
        .long   0                           /* frame size                         */
        .long   0                           /* method pointer (pointer to name)   */
 
-asm_calljavafunction2:
-asm_calljavafunction2int:
-asm_calljavafunction2long:
-asm_calljavafunction2float:
-asm_calljavafunction2double:
+asm_vm_call_method:
+asm_vm_call_method_int:
+asm_vm_call_method_long:
+asm_vm_call_method_float:
+asm_vm_call_method_double:
+L_asm_vm_call_method:                   /* required for PIC code              */
        push    %ebp
-       mov     %esp,%ebp                 /* save stackptr                        */
+       mov     %esp,%ebp                   /* save stackptr                      */
 
-       push    %ebx                      /* save registers                       */
+       push    %ebx                        /* save registers                     */
        push    %esi
        push    %edi
 
-       mov     20(%ebp),%eax             /* pointer to arg block (4(push)+4(return)+4+4+4)*/
-       mov     12(%ebp),%ecx             /* arg count            (4(push)+4(return)+4     */
+       mov     4*4(%ebp),%eax              /* pointer to arg block (4(push)+4(return)+4+4)*/
+       mov     3*4(%ebp),%ecx              /* arg count            (4(push)+4(return)+4 */
 
        xor     %esi,%esi                 /* clear stackframe size (MUST be       */
                                          /* before args check, may be zero!!!)   */
@@ -233,7 +163,7 @@ asm_calljavafunction2double:
        mov     %eax,%edi                 /* save pointer to arg block            */
 
 calljava_calcstacksize:
-       mov     offjniitemtype(%eax),%ebx
+       mov     offvmargtype(%eax),%ebx
        test    $1,%ebx                   /* two word type?                       */
        jz      calljava_onewordtype
        add     $4,%esi                   /* add 1 slot to stackframe size        */
@@ -243,7 +173,7 @@ calljava_onewordtype:
        sub     $1,%edx
        test    %edx,%edx                 /* any args left?                       */
        jz      calljava_setstack
-       add     $sizejniblock,%eax        /* goto next argument block             */
+       add     $sizevmarg,%eax             /* goto next argument block           */
        jmp     calljava_calcstacksize
                
 calljava_setstack:                             
@@ -252,32 +182,32 @@ calljava_setstack:
        mov     %esp,%edi                 /* move stackpointer into temp variable */
 
 calljava_copyloop:
-       mov     offjniitem(%eax),%edx     /* copy 4 Byte of Argument              */
+       mov     offvmargdata(%eax),%edx     /* copy 4 Byte of Argument            */
        mov     %edx,(%edi)
-       add     $4,%edi                   /* increase sp to next argument         */
-       mov     offjniitemtype(%eax),%ebx /* type -> ebx                          */
-       test    $1,%ebx                   /* Two Word Type?                       */
+       add     $4,%edi                     /* increase sp to next argument       */
+       mov     offvmargtype(%eax),%ebx     /* type -> ebx                        */
+       test    $1,%ebx                     /* two word type?                     */
        jz      calljava_copynext
 
-       mov     offjniitem+4(%eax),%edx   /* copy upper 4 Byte of 2 Word Type     */
+       mov     offvmargdata+4(%eax),%edx   /* copy upper 4 byte of 2 word type   */
        mov     %edx,(%edi)                     
-       add     $4,%edi                   /* increase sp to next argument         */
+       add     $4,%edi                     /* increase sp to next argument       */
 
 calljava_copynext:             
-       sub     $1,%ecx                   /* are there any args left?             */
+       sub     $1,%ecx                     /* are there any args left?           */
        test    %ecx,%ecx
        jle     calljava_copydone
 
-       add     $sizejniblock,%eax        /* goto next argument block             */
+       add     $sizevmarg,%eax             /* goto next argument block           */
        jmp     calljava_copyloop
 
 calljava_copydone:
-       mov     8(%ebp),%eax              /* move function pointer to %eax        */
+       mov     2*4(%ebp),itmp1             /* move function pointer to itmp1     */
 
-       lea     asm_call_jit_compiler,itmp3
+       lea     L_asm_call_jit_compiler,itmp3
        call    *itmp3                      /* call JIT compiler                  */
 
-L_asm_calljavafunction2_return:
+L_asm_vm_call_method_return:
        add     %esi,%esp                   /* remove arg stack frame             */
        pop     %edi                        /* restore registers                  */
        pop     %esi
@@ -290,37 +220,38 @@ calljava_xhandler2:
        call    builtin_throw_exception
        add     $4,sp
        xor     v0,v0                       /* return NULL                        */
-       jmp     L_asm_calljavafunction2_return
+       jmp     L_asm_vm_call_method_return
 
 
-/****************** function asm_call_jit_compiler *****************************
-*                                                                              *
-*   invokes the compiler for untranslated JavaVM methods.                      *
-*                                                                              *
-*   Register R0 contains a pointer to the method info structure (prepared      *
-*   by createcompilerstub). Using the return address in R26 and the            *
-*   offset in the LDA instruction or using the value in methodptr R28 the      *
-*   patching address for storing the method address can be computed:           *
-*                                                                              *
-*   method address was either loaded using                                     *
-*                                                                              *
-*   i386_mov_imm_reg(a, REG_ITMP2)                ; invokestatic/special       *
-*   i386_call_reg(REG_ITMP2)                                                   *
-*                                                                              *
-*   or                                                                         *
-*                                                                              *
-*   i386_mov_membase_reg(REG_SP, 0, REG_ITMP1)    ; invokevirtual/interface    *
-*   i386_mov_membase_reg(REG_ITMP1, OFFSET(, vftbl), REG_ITMP2)                *
-*   i386_mov_membase_reg(REG_ITMP2, OFFSET(vftbl, table[0]) + \                *
-*       sizeof(methodptr) * m->vftblindex, REG_ITMP1)                          *
-*   i386_call_reg(REG_ITMP1)                                                   *
-*                                                                              *
-*   in the static case the method pointer can be computed using the            *
-*   return address and the lda function following the jmp instruction          *
-*                                                                              *
+/* asm_call_jit_compiler *******************************************************
+
+   Invokes the compiler for untranslated JavaVM methods.
+
+   Register R0 contains a pointer to the method info structure (prepared
+   by createcompilerstub). Using the return address in R26 and the
+   offset in the LDA instruction or using the value in methodptr R28 the
+   patching address for storing the method address can be computed:
+
+   Method address was either loaded using
+
+   i386_mov_imm_reg(a, REG_ITMP2)                ; invokestatic/special
+   i386_call_reg(REG_ITMP2)
+
+   or
+
+   i386_mov_membase_reg(REG_SP, 0, REG_ITMP1)    ; invokevirtual/interface
+   i386_mov_membase_reg(REG_ITMP1, OFFSET(, vftbl), REG_ITMP2)
+   i386_mov_membase_reg(REG_ITMP2, OFFSET(vftbl, table[0]) + \
+       sizeof(methodptr) * m->vftblindex, REG_ITMP1)
+   i386_call_reg(REG_ITMP1)
+
+   In the static case the method pointer can be computed using the
+   return address and the lda function following the jmp instruction.
+
 *******************************************************************************/
 
 asm_call_jit_compiler:
+L_asm_call_jit_compiler:                /* required for PIC code              */
        sub     $((4+2)*4+sizestackframeinfo),sp /* create stack frame            */
        mov     itmp1,(4+0)*4(sp)           /* save method pointer                */
                        
@@ -396,7 +327,7 @@ L_asm_call_jit_compiler_exception:
 
        pop     xpc                         /* get return address                 */
        sub     $2,xpc                      /* faulting address is ra - 2         */
-       jmp     asm_handle_exception
+       jmp     L_asm_handle_exception
 
 
 /* asm_handle_exception ********************************************************
@@ -413,6 +344,7 @@ asm_handle_nat_exception:
        add     $4,sp                       /* clear return address of native stub*/
                
 asm_handle_exception:
+L_asm_handle_exception:                 /* required for PIC code              */
        sub     $((ARG_CNT+TMP_CNT)*4),sp   /* create maybe-leaf stackframe       */
 
        SAVE_ARGUMENT_REGISTERS(0)          /* we save arg and temp registers in  */
@@ -542,7 +474,8 @@ noflt:
    XXX
 
    Stack layout:
-     20   return address
+     24   return address
+     20   REG_ITMP3
      16   pointer to virtual java_objectheader
      12   last byte of machine code (xmcode)
       8   machine code (which is patched back later)
@@ -562,10 +495,10 @@ asm_wrapper_patcher:
        mov     itmp1,0*4(sp)               /* stackframeinfo pointer             */
        movl    $0,1*4(sp)                  /* if pv is NULL, use findmethod      */
        mov     sp,itmp2
-       add     $((6+2+4)*4+sizestackframeinfo),itmp2
-       mov     itmp2,2*4(sp)
-       mov     ((5+2+4)*4+sizestackframeinfo)(sp),itmp3
-       mov     itmp3,3*4(sp)
+       add     $((7+2+4)*4+sizestackframeinfo),itmp2
+       mov     itmp2,2*4(sp)               /* pass Java sp                       */
+       mov     ((6+2+4)*4+sizestackframeinfo)(sp),itmp3
+       mov     itmp3,3*4(sp)               /* pass ra to java function           */
        call    stacktrace_create_inline_stackframeinfo
 
        mov     sp,itmp1                    /* pass stack pointer                 */
@@ -580,16 +513,20 @@ asm_wrapper_patcher:
        mov     itmp1,0*4(sp)               /* stackframeinfo pointer             */
        call    stacktrace_remove_stackframeinfo
 
-       mov     (0+4)*4(sp),itmp1           /* restore itmp1 and itmp2            */
-       mov     (1+4)*4(sp),itmp2           /* may be used by some instructions   */
        mov     1*4(sp),itmp3               /* restore return value               */
-
-       add     $((5+2+4)*4+sizestackframeinfo),sp /* remove stack frame, keep ra */
        test    itmp3,itmp3                 /* exception thrown?                  */
        jz      L_asm_wrapper_patcher_exception
+
+       mov     (0+4)*4(sp),itmp1           /* restore itmp1 and itmp2            */
+       mov     (1+4)*4(sp),itmp2           /* may be used by some instructions   */
+       mov     ((5+2+4)*4+sizestackframeinfo)(sp),itmp3
+       add     $((6+2+4)*4+sizestackframeinfo),sp /* remove stack frame, keep ra */
+
        ret                                 /* call new patched code              */
 
 L_asm_wrapper_patcher_exception:
+       add     $((6+2+4)*4+sizestackframeinfo),sp /* remove stack frame, keep ra */
+
 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
        call    builtin_asm_get_exceptionptrptr
        mov     v0,itmp2
@@ -600,8 +537,102 @@ L_asm_wrapper_patcher_exception:
        movl    $0,(itmp2)                  /* clear the exception pointer        */
 
        pop     xpc                         /* get and remove return address      */
-       jmp     asm_handle_exception
+       jmp     L_asm_handle_exception
+
+
+/* asm_replacement_out *********************************************************
+
+   This code is jumped to from the replacement-out stubs that are executed
+   when a thread reaches an activated replacement point.
+
+   The purpose of asm_replacement_out is to read out the parts of the
+   execution state that cannot be accessed from C code, store this state,
+   and then call the C function replace_me.
+
+   Stack layout:
+      4                 start of stack inside method to replace
+      0   rplpoint *    info on the replacement point that was reached
+
+*******************************************************************************/
+
+/* some room to accomodate changes of the stack frame size during replacement */
+       /* XXX we should find a cleaner solution here */
+#define REPLACEMENT_ROOM  512
+
+asm_replacement_out:
+    /* create stack frame */
+       sub     $(sizeexecutionstate + REPLACEMENT_ROOM),sp
+
+       /* save registers in execution state */
+       mov     %eax,(EAX*8+offes_intregs)(sp)
+       mov     %ebx,(EBX*8+offes_intregs)(sp)
+       mov     %ecx,(ECX*8+offes_intregs)(sp)
+       mov     %edx,(EDX*8+offes_intregs)(sp)
+       mov     %esi,(ESI*8+offes_intregs)(sp)
+       mov     %edi,(EDI*8+offes_intregs)(sp)
+       mov     %ebp,(EBP*8+offes_intregs)(sp)
+       movl    $0  ,(ESP*8+offes_intregs)(sp) /* not used */
+
+#ifndef NDEBUG
+       /* clear high 32bit */
+       movl    $0,(4+0*8+offes_intregs)(sp)
+       movl    $0,(4+1*8+offes_intregs)(sp)
+       movl    $0,(4+2*8+offes_intregs)(sp)
+       movl    $0,(4+3*8+offes_intregs)(sp)
+       movl    $0,(4+4*8+offes_intregs)(sp)
+       movl    $0,(4+5*8+offes_intregs)(sp)
+       movl    $0,(4+6*8+offes_intregs)(sp)
+       movl    $0,(4+7*8+offes_intregs)(sp)
+#endif
+
+       /* calculate sp of method */
+       mov     sp,itmp1
+       add     $(sizeexecutionstate + REPLACEMENT_ROOM + 4),itmp1
+       mov     itmp1,(offes_sp)(sp)
+
+       /* pv must be looked up via AVL tree */
+       movl    $0,(offes_pv)(sp)
 
+       /* call replace_me */
+       mov     -4(itmp1),itmp1             /* rplpoint *                         */
+    push    sp                          /* arg1: execution state              */
+    push    itmp1                       /* arg0: replacement point            */
+    call    replace_me                  /* call C function replace_me         */
+    call    abort                       /* NEVER REACHED                      */
+
+/* asm_replacement_in **********************************************************
+
+   This code writes the given execution state and jumps to the replacement
+   code.
+
+   This function never returns!
+
+   C prototype:
+      void asm_replacement_in(executionstate *es);
+
+*******************************************************************************/
+
+asm_replacement_in:
+       mov     4(sp),%ebp                  /* executionstate *es                 */
+
+       /* set new sp */
+       mov     (offes_sp)(%ebp),%esp
+       
+       /* store address of new code */
+       push    (offes_pc)(%ebp)
+       
+       /* copy registers from execution state */
+       mov     (EAX*8+offes_intregs)(%ebp),%eax
+       mov     (EBX*8+offes_intregs)(%ebp),%ebx
+       mov     (ECX*8+offes_intregs)(%ebp),%ecx
+       mov     (EDX*8+offes_intregs)(%ebp),%edx
+       mov     (ESI*8+offes_intregs)(%ebp),%esi
+       mov     (EDI*8+offes_intregs)(%ebp),%edi
+
+       mov     (EBP*8+offes_intregs)(%ebp),%ebp
+
+       /* jump to new code */
+       ret
 
 /************************ function asm_builtin_x2x *****************************
 *                                                                              *
@@ -802,4 +833,5 @@ asm_criticalsections:
  * c-basic-offset: 4
  * tab-width: 4
  * End:
+ * vim:noexpandtab:sw=4:ts=4:
  */