src/vm/cycles-stats.h: Switched from asm_get_cycle_count to md_get_cycle_count.
[cacao.git] / src / vm / jit / i386 / asmpart.S
index c5f4904714ddbb3033bdedde5fe977a313badb32..b9be6e191288c242139bfc018248b49e875043d0 100644 (file)
@@ -1,9 +1,7 @@
 /* src/vm/jit/i386/asmpart.S - Java-C interface functions for i386
 
-   Copyright (C) 1996-2005, 2006 R. Grafl, A. Krall, C. Kruegel,
-   C. Oates, R. Obermaisser, M. Platter, M. Probst, S. Ring,
-   E. Steiner, C. Thalinger, D. Thuernbeck, P. Tomsich, C. Ullrich,
-   J. Wenninger, Institut f. Computersprachen - TU Wien
+   Copyright (C) 1996-2005, 2006, 2007, 2008
+   CACAOVM - Verein zur Foerderung der freien virtuellen Maschine CACAO
 
    This file is part of CACAO.
 
    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
    02110-1301, USA.
 
-   Contact: cacao@cacaojvm.org
-
-   Authors: Andreas Krall
-            Reinhard Grafl
-            Christian Thalinger
-
-   Changes: Joseph Wenninger
-            Edwin Steiner
-
-   $Id: asmpart.S 5255 2006-08-21 15:17:48Z twisti $
-
 */
 
 
@@ -42,7 +29,6 @@
 
 #include "vm/jit/i386/arch.h"
 #include "vm/jit/i386/md-abi.h"
-#include "vm/jit/i386/offsets.h"
 
 #include "vm/jit/abi-asm.h"
 #include "vm/jit/methodheader.h"
        .globl asm_vm_call_method_float
        .globl asm_vm_call_method_double
        .globl asm_vm_call_method_exception_handler
+       .globl asm_vm_call_method_end
 
-       .globl asm_call_jit_compiler
        .globl asm_handle_nat_exception
        .globl asm_handle_exception
 
        .globl asm_abstractmethoderror
 
-       .globl asm_patcher_wrapper
-
-       .globl asm_replacement_out
-       .globl asm_replacement_in
-
        .globl asm_builtin_f2i
        .globl asm_builtin_f2l
        .globl asm_builtin_d2i
        .globl asm_builtin_d2l
 
-       .globl asm_criticalsections
-       .globl asm_getclassvalues_atomic
+       .globl asm_compare_and_swap
+       .globl asm_memory_barrier
 
-       .globl asm_get_cycle_count
+#if defined(ENABLE_ESCAPE_CHECK)
+       .globl asm_escape_check
+#endif
 
 
 /* asm_md_init *****************************************************************
@@ -127,17 +110,9 @@ asm_md_init:
 
        .align  8
 
-       .long   0                           /* catch type all                     */
-       .long   0                           /* handler pc                         */
-       .long   0                           /* end pc                             */
-       .long   0                           /* 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                           /* codeinfo pointer                   */
 
@@ -147,7 +122,7 @@ asm_vm_call_method_long:
 asm_vm_call_method_float:
 asm_vm_call_method_double:
        push    bp
-       mov     sp,bp                       /* save stackptr                      */
+       mov     sp,bp                       /* save stack pointer                 */
        sub     $(4*4),sp                   /* create stackframe                  */
        and     $0xfffffff0,sp              /* align stack to 16-byte             */
 
@@ -155,65 +130,36 @@ asm_vm_call_method_double:
        mov     s1,1*4(sp)
        mov     s2,2*4(sp)
 
-       mov     4*4(bp),itmp1               /* pointer to arg block (4(push)+4(return)+4+4)*/
-       mov     3*4(bp),itmp2               /* arg count            (4(push)+4(return)+4 */
-
-       mov     sp,s1                       /* save the stackpointer              */
-
-       test    itmp2,itmp2                 /* maybe we have no args              */
-       jle     L_asm_vm_call_method_copy_done
+       mov     sp,s1                       /* save stack pointer                 */
 
-       mov     itmp2,itmp3                 /* calculate stack size               */
-       mov     itmp1,%edi                  /* save pointer to arg block          */
+       mov     3*4(bp),t0                  /* address of data structure          */
+       mov     4*4(bp),itmp1               /* number of stack arguments          */
 
-calljava_calcstacksize:
-       mov     offvmargtype(itmp1),t0
-       test    $1,t0                       /* two word type?                     */
-       jz      calljava_onewordtype
+       cmp     $0,itmp1
+       je      L_asm_vm_call_method_stack_copy_done
 
-       sub     $4,sp                       /* add 1 slot to stackframe size      */
+       mov     itmp1,itmp2
+       add     $1,itmp2                    /* keep stack 16-byte aligned         */
+       and     $0xfffffffe,itmp2
+       shl     $3,itmp2                    /* calculate stack size               */
+       sub     itmp2,sp                    /* create stack frame                 */
+       mov     sp,itmp2                    /* temporary stack pointer            */
 
-calljava_onewordtype:
-       sub     $4,sp                       /* add 1 slot to stackframe size      */
-       sub     $1,itmp3
-       test    itmp3,itmp3                 /* any args left?                     */
-       jz      calljava_setstack
-
-       add     $sizevmarg,itmp1            /* goto next argument block           */
-       jmp     calljava_calcstacksize
-               
-calljava_setstack:                             
-       mov     %edi,itmp1                  /* restore pointer to arg block       */
-       and     $0xfffffff0,sp              /* align stack to 16-byte             */
-       mov     sp,itmp3                    /* initialize pointer for copying     */
+L_asm_vm_call_method_stack_copy_loop:
+       mov     0(t0),itmp3                 /* load argument                      */
+       mov     itmp3,0(itmp2)              /* store argument on stack            */
+       mov     4(t0),itmp3
+       mov     itmp3,4(itmp2)
 
-calljava_copyloop:
-       mov     offvmargdata(itmp1),t0      /* get 4-bytes of argument            */
-       mov     t0,(itmp3)                  /* and store them on the stack        */
-       add     $4,itmp3                    /* increase sp to next argument       */
+       sub     $1,itmp1                    /* subtract 1 argument                */
+       add     $8,t0                       /* set address of next argument       */
+       add     $8,itmp2                    /* increase SP                        */
 
-       mov     offvmargtype(itmp1),t0      /* get the argument type              */
-       test    $1,t0                       /* two word type?                     */
-       jz      calljava_copynext
+       cmp     $0,itmp1
+       jg      L_asm_vm_call_method_stack_copy_loop
 
-       mov     offvmargdata+4(itmp1),t0    /* get upper 4-bytes of 2 word type   */
-       mov     t0,(itmp3)                      
-       add     $4,itmp3                    /* increase sp to next argument       */
-
-calljava_copynext:             
-       sub     $1,itmp2                    /* are there any args left?           */
-       test    itmp2,itmp2
-       jle     L_asm_vm_call_method_copy_done
-
-       add     $sizevmarg,itmp1            /* goto next argument block           */
-       jmp     calljava_copyloop
-
-L_asm_vm_call_method_copy_done:
-       mov     2*4(bp),itmp1               /* move function pointer to itmp1     */
-
-       lea     L_asm_call_jit_compiler,mptr
-       mov     mptr,3*4(s1)
-       lea     (3*4-256)(s1),mptr          /* We subtract 256 to force the next  */
+L_asm_vm_call_method_stack_copy_done:
+       lea     (2*4-256)(bp),mptr          /* We subtract 256 to force the next  */
                                            /* move instruction to have a 32-bit  */
                                            /* offset.                            */
 
@@ -234,64 +180,10 @@ asm_vm_call_method_exception_handler:
        push    xptr                        /* pass exception pointer             */
        call    builtin_throw_exception
        add     $4,sp
+asm_vm_call_method_end:
        jmp     L_asm_vm_call_method_return
 
 
-/* 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*4),sp                   /* keep stack 16-byte aligned         */
-
-       mov     itmp1,0*4(sp)               /* pass methodinfo pointer            */
-       mov     mptr,1*4(sp)                /* pass method pointer                */
-       mov     sp,itmp2                    /* pass java sp                       */
-       add     $((1+4)*4),itmp2
-       mov     itmp2,2*4(sp)
-       mov     4*4(sp),itmp3               /* pass java ra                       */
-       mov     itmp3,3*4(sp)
-       call    jit_asm_compile
-
-       add     $(4*4),sp                   /* remove stack frame                 */
-
-       test    v0,v0                       /* check for exception                */
-       je      L_asm_call_jit_compiler_exception
-
-       jmp             *v0                         /* ...and now call the new method     */
-
-L_asm_call_jit_compiler_exception:
-       call    exceptions_get_and_clear_exception
-                                           /* v0 == xptr                         */
-       pop     xpc                         /* get return address                 */
-       sub     $2,xpc                      /* faulting address is ra - 2         */
-       jmp     L_asm_handle_exception
-
-
 /* asm_handle_exception ********************************************************
 *                                                                              *
 *   This function handles an exception. It does not use the usual calling      *
@@ -325,7 +217,7 @@ L_asm_handle_exception_stack_loop:
        mov     t0,8*4(sp)                  /* save maybe-leaf flag               */
 
        mov     xpc,0*4(sp)                 /* pass exception pc                  */
-       call    codegen_get_pv_from_pc
+       call    methodtree_find
        mov     v0,6*4(sp)                  /* save data segment pointer          */
 
        mov     4*4(sp),itmp3               /* pass exception pointer             */
@@ -383,11 +275,11 @@ L_asm_handle_exception_no_leaf_stack:
        cmp     $2,itmp1
        je      int2
 
-       mov     -3*4(itmp2),s0
+       mov     -4-3*8(itmp2),s0
 int2:  
-       mov     -2*4(itmp2),s1
+       mov     -4-2*8(itmp2),s1
 int1:  
-       mov     -1*4(itmp2),s2
+       mov     -4-1*8(itmp2),s2
 
        shl     $2,itmp1                    /* multiply by 4 bytes                */
        sub     itmp1,itmp2
@@ -454,149 +346,6 @@ asm_abstractmethoderror:
        jmp     L_asm_handle_exception
 
 
-/* asm_patcher_wrapper *********************************************************
-
-   XXX
-
-   Stack layout:
-     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)
-      4   unresolved field reference
-      0   patcher function pointer to call
-
-*******************************************************************************/
-
-asm_patcher_wrapper:
-       sub     $((1+4+4)*4),sp             /* keep stack 16-byte aligned         */
-
-       mov     itmp1,(0+4)*4(sp)           /* save itmp1 and itmp2               */
-       mov     itmp2,(1+4)*4(sp)
-
-       mov     sp,itmp1                    /* pass SP of patcher stub            */
-       add     $((1+4+4)*4),itmp1
-       mov     itmp1,0*4(sp)
-       movl    $0,1*4(sp)                  /* pass PV (if NULL, use findmethod)  */
-       movl    $0,2*4(sp)                  /* pass RA (it's on the stack)        */
-       call    patcher_wrapper
-       mov     v0,itmp3                    /* save return value                  */
-
-       mov     (0+4)*4(sp),itmp1           /* restore itmp1 and itmp2            */
-       mov     (1+4)*4(sp),itmp2
-
-       test    itmp3,itmp3                 /* exception thrown?                  */
-       jne     L_asm_patcher_wrapper_exception
-
-       mov     (5+1+4+4)*4(sp),itmp3       /* restore itmp3                      */
-       add     $((6+1+4+4)*4),sp           /* remove stack frame, keep RA        */
-
-       ret                                 /* jump to new patched code           */
-
-L_asm_patcher_wrapper_exception:
-       add     $((6+2+4)*4),sp             /* remove stack frame, keep RA        */
-       add     $((6+1+4+4)*4),sp           /* remove stack frame, keep RA        */
-       mov     itmp3,xptr                  /* get exception                      */
-       pop     xpc                         /* get and remove return address      */
-       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         */
-
-
-/* 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 *****************************
 *                                                                              *
 *   Wrapper functions for corner cases                                         *
@@ -632,57 +381,70 @@ asm_builtin_d2l:
        ret
 
 
-asm_getclassvalues_atomic:
-_crit_restart2:
-       mov     4(%esp),%ecx        /* super */
-       mov     8(%esp),%edx        /* sub */
-_crit_begin2:
-       mov     offbaseval(%ecx),%eax
-       mov     offdiffval(%ecx),%ecx
-       mov     offbaseval(%edx),%edx
-_crit_end2:
-       push    %ebx
-       mov     16(%esp),%ebx      /* out */
-       mov     %eax,offcast_super_baseval(%ebx)
-       mov     %ecx,offcast_super_diffval(%ebx)
-       mov     %edx,offcast_sub_baseval(%ebx)
-       pop     %ebx
-       ret
+/* asm_compare_and_swap ********************************************************
 
-       .data
+   Does an atomic compare and swap.  Required for the lock
+   implementation.
 
-asm_criticalsections:
-#if defined(ENABLE_THREADS)
-#if 0
-       .long   _crit_begin1
-       .long   _crit_end1
-       .long   _crit_restart1
-#endif
-       .long   _crit_begin2
-       .long   _crit_end2
-       .long   _crit_restart2
-#endif
-       .long 0
+   Atomically do the following: Check if the location still contains
+   `oldval`. If so, replace it by `newval` and return `oldval`.
 
+   RETURN VALUE:
+       the old value at *p
 
-/* Disable exec-stacks, required for Gentoo ***********************************/
+   long compare_and_swap(volatile long *p, long oldval, long newval);
 
-#if defined(__GCC__) && defined(__ELF__)
-       .section .note.GNU-stack,"",@progbits
-#endif
+*******************************************************************************/
+
+asm_compare_and_swap:
+       mov     1*4(sp),%ecx            /* load p into a register                 */
+       mov     2*4(sp),%eax            /* load oldval into return register       */
+       mov     3*4(sp),%edx            /* load newval into a register            */
+       lock; cmpxchgl %edx,0(%ecx)
+       ret
 
 
-/* asm_get_cycle_count *********************************************************
+/* asm_memory_barrier **********************************************************
 
-   Get the current time-stamp counter from the CPU.
+   A memory barrier for the Java Memory Model.
 
 *******************************************************************************/
 
-asm_get_cycle_count:
-       rdtsc
+asm_memory_barrier:
+       lock; add $0,0(sp)
        ret
 
 
+#if defined(ENABLE_ESCAPE_CHECK)
+asm_escape_check:
+       sub     $24,%esp
+
+       mov     t0, 4(%esp)
+       mov     itmp1, 8(%esp)
+       mov     itmp2, 12(%esp)
+       mov     itmp3, 16(%esp)
+
+       mov     28(%esp), itmp1
+       mov     itmp1, (%esp)
+
+       call    escape_analysis_escape_check
+
+       mov     4(%esp), t0
+       mov     8(%esp), itmp1
+       mov     12(%esp), itmp2
+       mov     16(%esp), itmp3
+
+       add     $24,sp
+       ret
+#endif
+
+
+/* disable exec-stacks ********************************************************/
+
+#if defined(__linux__) && defined(__ELF__)
+       .section .note.GNU-stack,"",%progbits
+#endif
+
 /*
  * These are local overrides for various environment variables in Emacs.
  * Please do not remove this and leave it at the end of the file, where