* src/vm/jit/i386/asmpart.S (asm_replacement_out): Added pv.
[cacao.git] / src / vm / jit / i386 / asmpart.S
index bcd685fbcecee66bb11391c23a8533411437b75d..501ab37b56488728eea2ec28cc141e2ad47ee736 100644 (file)
@@ -1,10 +1,9 @@
-/* jit/i386/asmpart.S - Java-C interface functions for i386
+/* src/vm/jit/i386/asmpart.S - Java-C interface functions for i386
 
-   Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003
-   Institut f. Computersprachen, TU Wien
-   R. Grafl, A. Krall, C. Kruegel, C. Oates, R. Obermaisser, M. Probst,
-   S. Ring, E. Steiner, C. Thalinger, D. Thuernbeck, P. Tomsich,
-   J. Wenninger
+   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
 
    This file is part of CACAO.
 
 
    You should have received a copy of the GNU General Public License
    along with this program; if not, write to the Free Software
-   Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
-   02111-1307, USA.
+   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+   02110-1301, USA.
 
-   Contact: cacao@complang.tuwien.ac.at
+   Contact: cacao@cacaojvm.org
 
    Authors: Andreas Krall
             Reinhard Grafl
             Christian Thalinger
 
-   $Id: asmpart.S 986 2004-03-29 07:02:38Z stefan $
+   Changes: Joseph Wenninger
+            Edwin Steiner
 
-*/
+   $Id: asmpart.S 4643 2006-03-16 18:38:42Z edwin $
 
+*/
 
-#include "offsets.h"
 
-/* data segment offsets */
+#include "config.h"
 
-#define MethodPointer          -4
-#define FrameSize              -8
-#define IsSync                 -12
-#define IsLeaf                 -16
-#define IntSave                -20
-#define FltSave                -24
-#define LineNumberTableSize    -28
-#define LineNumberTableStart   -32
-#define ExTableSize            -36
-#define ExTableStart           -36
+#include "vm/jit/abi.h"
+#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"
 
-#define ExEntrySize     -16
-#define ExStartPC       -4
-#define ExEndPC         -8
-#define ExHandlerPC     -12
-#define ExCatchType     -16
+#include "vm/jit/methodheader.h"
 
 
-#define LineEntrySize  -8
-#define LinePC         0
-#define LineLine       -4
-               
        .text
 
 
-/********************* exported functions and variables ***********************/
+/* exported functions and variables *******************************************/
+
+       .globl asm_md_init
 
-       .globl has_no_x_instr_set
-       .globl asm_calljavafunction
-       .globl asm_calljavafunction2
-       .globl asm_calljavafunction2long
-       .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_dumpregistersandcall
-       .globl asm_handle_builtin_exception
        .globl asm_handle_nat_exception
        .globl asm_handle_exception
-       .globl asm_check_clinit
-       .globl asm_builtin_checkcast    
-       .globl asm_builtin_checkarraycast
-       .globl asm_builtin_newarray
-       .globl asm_builtin_anewarray
-       .globl asm_builtin_newarray_array
-       .globl asm_builtin_aastore
-       .globl asm_builtin_monitorenter
-       .globl asm_builtin_monitorexit
-       .globl asm_builtin_ldiv
-       .globl asm_builtin_lrem
-    .globl asm_builtin_f2i
-    .globl asm_builtin_f2l
-    .globl asm_builtin_d2i
-    .globl asm_builtin_d2l
-       .globl asm_builtin_arrayinstanceof
+
+       .globl asm_wrapper_patcher
+
+       .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_perform_threadswitch
        .globl asm_initialize_thread_stack
        .globl asm_switchstackandcall
-       .globl asm_getcallingmethod
-       .globl Java_java_lang_VMSecurityManager_getClassContext
-       .globl Java_java_lang_VMSecurityManager_currentClassLoader    
-       .globl asm_builtin_new
-       .globl asm_get_stackTrace
-
-
-/*************************** imported functions *******************************/
-
-       .globl jit_compile
-       .globl builtin_monitorexit
-       .globl builtin_throw_exception
-       .globl builtin_trace_exception
-       .globl class_java_lang_Object
-       .globl findmethod
-       .globl builtin_asm_createclasscontextarray
-       .globl builtin_asm_getclassloader
-#if defined(USE_THREADS) && defined(NATIVE_THREADS)
-       .globl cast_lock
-       .globl cast_unlock
-#endif
+       .globl asm_criticalsections
+       .globl asm_getclassvalues_atomic
 
 
-/********************* 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_calljavamethod (methodinfo *m,                     *
-*         void *arg1, void *arg2, void *arg3, void *arg4);                     *
-*                                                                              *
-*******************************************************************************/
+/* asm_md_init *****************************************************************
 
-call_name:
-       .ascii  "calljavafunction\0\0"
+   Initialize machine dependent stuff.
 
-       .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   32                        /* frame size                           */
-       .long   0                         /* method pointer (pointer to name)     */
-
-asm_calljavafunction:
-               push    %ebp                  /* allocate stack space                 */
-               mov             %esp, %ebp
-
-        push    %ebx                  /* save registers                       */
-        push    %esi
-        push    %edi
-        
-               sub             $32,%esp              /* pass the remaining parameters        */
-               xor             %edx,%edx
-
-               mov             %edx,28(%esp)         /* convert parms to 8 byte              */
-               mov             24(%ebp),%eax
-               mov             %eax,24(%esp)
-               
-               mov             %edx,20(%esp)
-               mov             20(%ebp),%eax
-               mov             %eax,16(%esp)
+   See: http://www.srware.com/linux_numerics.txt
 
-               mov             %edx,12(%esp)
-               mov             16(%ebp),%eax
-               mov             %eax,8(%esp)
+   This puts the X86 FPU in 64-bit precision mode.  The default under
+   Linux is to use 80-bit mode, which produces subtle differences from
+   FreeBSD and other systems, eg, (int)(1000*atof("0.3")) is 300 in
+   64-bit mode, 299 in 80-bit mode.
 
-               mov             %edx,4(%esp)
-               mov             12(%ebp),%eax
-               mov             %eax,(%esp)
+   Fixes: http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=350729
 
-               mov             8(%ebp),%eax          /* move function pointer to %eax        */
+*******************************************************************************/
 
-               lea             asm_call_jit_compiler,%edx 
-               call    *%edx                 /* call JIT compiler                    */
-       
-calljava_return:
-        add     $32,%esp
-        pop     %edi                 /* restore registers                     */
-        pop     %esi
-        pop     %ebx
-               leave
-               ret
-
-calljava_xhandler:
-               push    %eax                              /* pass exception pointer               */
-               call    builtin_throw_exception
-               add     $4,%esp
-
-               add     $32,%esp
-        pop     %edi                 /* restore registers                     */
-        pop     %esi
-        pop     %ebx
-        leave
-               ret
+asm_md_init:
+       sub     $4,sp                       /* allocate space for the FPU state   */
+       fnstcw  (sp)                        /* get the FPU state                  */
+       mov     (sp),%eax
+       and     $0xfcff,%ax                 /* remove the extended mode flag      */
+       or      $0x0200,%ax                 /* put the double mode flag           */
+       mov     %eax,(sp)                   /* store new FPU state                */
+       fldcw   (sp)                        /* setup new FPU state                */
+       add     $4,sp
+       ret
 
 
 /********************* function asm_calljavafunction ***************************
@@ -212,200 +117,220 @@ calljava_xhandler:
 *   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);                                 *
 *                                                                              *
 *******************************************************************************/
 
-call_name2:
-       .ascii  "calljavafunction2\0\0"
-
        .align  8
-       .long   0                         /* catch type all                       */
-       .long   calljava_xhandler2        /* handler pc                           */
-       .long   calljava_xhandler2        /* end pc                               */
-       .long   asm_calljavafunction2     /* 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   32                        /* frame size                           */
-       .long   0                         /* method pointer (pointer to name)     */
-
-asm_calljavafunction2:
-asm_calljavafunction2double:
-asm_calljavafunction2long:
+
+       .long   0                           /* catch type all                     */
+       .long   calljava_xhandler2          /* handler pc                         */
+       .long   calljava_xhandler2          /* end 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             */
+       .long   0                           /* fltsave                            */
+       .long   0                           /* intsave                            */
+       .long   0                           /* isleaf                             */
+       .long   0                           /* IsSync                             */
+       .long   0                           /* frame size                         */
+       .long   0                           /* method pointer (pointer to name)   */
+
+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                 */
-       mov     12(%ebp),%ecx             /* arg count                            */
+       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!!!)   */
        test    %ecx,%ecx                 /* maybe we have no args                */
        jle     calljava_copydone
 
        mov     %ecx,%edx                 /* calculate stack size                 */
-       shl     $3,%edx
-       mov     %edx,%esi                 /* save in callee saved register        */
-       sub     %esi,%esp                 /* stack frame for arguments            */
-       mov     %esp,%edi
+       mov     %eax,%edi                 /* save pointer to arg block            */
+
+calljava_calcstacksize:
+       mov     offvmargtype(%eax),%ebx
+       test    $1,%ebx                   /* two word type?                       */
+       jz      calljava_onewordtype
+       add     $4,%esi                   /* add 1 slot to stackframe size        */
+
+calljava_onewordtype:
+       add     $4,%esi                   /* add 1 slot to stackframe size        */
+       sub     $1,%edx
+       test    %edx,%edx                 /* any args left?                       */
+       jz      calljava_setstack
+       add     $sizevmarg,%eax             /* goto next argument block           */
+       jmp     calljava_calcstacksize
+               
+calljava_setstack:                             
+       mov     %edi,%eax                 /* restore pointer to arg block         */
+       sub     %esi,%esp                 /* create stackframe for arguments      */
+       mov     %esp,%edi                 /* move stackpointer into temp variable */
 
 calljava_copyloop:
-    mov     offjniitem(%eax),%edx
-    mov     %edx,0(%edi)
-    mov     offjniitem+4(%eax),%edx
-    mov     %edx,4(%edi)
-
-       sub     $1,%ecx                   /* are there any args left?             */
+       mov     offvmargdata(%eax),%edx     /* copy 4 Byte of Argument            */
+       mov     %edx,(%edi)
+       add     $4,%edi                     /* increase sp to next argument       */
+       mov     offvmargtype(%eax),%ebx     /* type -> ebx                        */
+       test    $1,%ebx                     /* two word type?                     */
+       jz      calljava_copynext
+
+       mov     offvmargdata+4(%eax),%edx   /* copy upper 4 byte of 2 word type   */
+       mov     %edx,(%edi)                     
+       add     $4,%edi                     /* increase sp to next argument       */
+
+calljava_copynext:             
+       sub     $1,%ecx                     /* are there any args left?           */
        test    %ecx,%ecx
        jle     calljava_copydone
 
-       add     $sizejniblock,%eax        /* goto next argument block             */
-    add     $8,%edi                   /* increase sp to next argument         */
+       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,%edx 
-       call    *%edx                     /* call JIT compiler                    */
-       
-calljava_return2:
-       add     %esi,%esp                 /* remove arg stack frame               */
-       pop     %edi                      /* restore registers                    */
+       lea     L_asm_call_jit_compiler,itmp3
+       call    *itmp3                      /* call JIT compiler                  */
+
+L_asm_vm_call_method_return:
+       add     %esi,%esp                   /* remove arg stack frame             */
+       pop     %edi                        /* restore registers                  */
        pop     %esi
        pop     %ebx
        leave
        ret
 
 calljava_xhandler2:
-       push    %eax                      /* pass exception pointer               */
+       push    xptr                        /* pass exception pointer             */
        call    builtin_throw_exception
-       add     $4,%esp
-    
-       add     %esi,%esp                 /* remove arg stack frame               */
-       pop     %edi                      /* restore registers                    */
-       pop     %esi
-       pop     %ebx
-       leave
-       ret
+       add     $4,sp
+       xor     v0,v0                       /* return NULL                        */
+       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:
-       push    %ebx                /* save register                              */
-    push    %ebp
+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                */
                        
-       mov     8(%esp),%ebp        /* get return address (2 push)                */
-       mov     -1(%ebp),%bl        /* get function code                          */
-       cmp     $0xd1,%bl           /* called with `call *REG_ITMP2' (%ecx)?      */
+       mov     (4+2)*4+sizestackframeinfo(sp),itmp3 /* get return address        */
+       mov     -1(itmp3),itmp1b            /* get function code                  */
+       cmp     $0xd1,itmp1b                /* called with `call *REG_ITMP2'?     */
        jne             L_not_static_special
 
-       sub     $6,%ebp             /* calculate address of immediate             */
+       sub     $6,itmp3                    /* calculate address of immediate     */
        jmp             L_call_jit_compile
                
 L_not_static_special:
-       cmp     $0xd0,%bl           /* called with `call *REG_ITMP1' (%eax)       */
+       cmp     $0xd0,itmp1b                /* called with `call *REG_ITMP1'      */
        jne             L_not_virtual_interface
        
-       sub     $6,%ebp             /* calculate address of offset                */
-       mov     (%ebp),%ebp         /* get offset                                 */
-       add     %ecx,%ebp           /* add base address to get method address     */
+       sub     $6,itmp3                    /* calculate address of offset        */
+       mov     (itmp3),itmp3               /* get offset                         */
+       add     itmp2,itmp3                 /* add base address to get method adr */
        jmp             L_call_jit_compile
 
-L_not_virtual_interface:        /* a call from asm_calljavafunction           */
-       xor     %ebp,%ebp
+L_not_virtual_interface:
+       xor     itmp3,itmp3                 /* a call from asm_calljavafunction   */
                
 L_call_jit_compile:
-       push    %ebp                /* save address for method pointer            */
-
-       push    %eax                /* push methodpointer on stack                */
+       mov     itmp3,(4+1)*4(sp)           /* save address for method pointer    */
+
+       mov     sp,itmp1                    /* create stackframe info             */
+       add     $((4+2)*4),itmp1
+       mov     itmp1,0*4(sp)               /* stackframeinfo pointer             */
+       movl    $0,1*4(sp)                  /* if pv is NULL, use findmethod      */
+       mov     sp,itmp2
+       add     $((1+4+2)*4+sizestackframeinfo),itmp2 /* pass java sp             */
+       mov     itmp2,2*4(sp)
+       mov     ((0+4+2)*4+sizestackframeinfo)(sp),itmp3 /* pass java ra          */
+       mov     itmp3,3*4(sp)
+       call    stacktrace_create_inline_stackframeinfo
+
+       mov     (4+0)*4(sp),itmp1           /* pass method pointer                */
+       mov     itmp1,0*4(sp)
        call    jit_compile
-       add     $4,%esp
+       mov     v0,(4+0)*4(sp)              /* save return value                  */
+
+       mov     sp,itmp1                    /* remove stackframe info             */
+       add     $((4+2)*4),itmp1
+       mov     itmp1,0*4(sp)               /* stackframeinfo pointer             */
+       call    stacktrace_remove_stackframeinfo
+
+       mov     (4+0)*4(sp),v0              /* restore return value               */
+       mov     (4+1)*4(sp),itmp3           /* restore address for method pointer */
+
+       add     $((4+2)*4+sizestackframeinfo),sp /* remove stack frame            */
 
-       pop     %ebp                /* restore address for method pointer         */
-       test    %ebp,%ebp           /* is address == 0 (asm_calljavafunction)     */
+       test    v0,v0                       /* check for exception                */
+       je      L_asm_call_jit_compiler_exception
+
+       test    itmp3,itmp3                 /* was this a JIT call?               */
        je              L_call_method
        
-       mov     %eax,(%ebp)         /* and now save the new pointer               */
+       mov     v0,(itmp3)                  /* save the new method pointer        */
 
 L_call_method:
-       pop     %ebp                /* restore registers                          */
-       pop     %ebx
-               
-       jmp             *%eax               /* ...and now call the new method             */
+       jmp             *v0                         /* ...and now call the new method     */
 
+L_asm_call_jit_compiler_exception:
+#if defined(USE_THREADS) && defined(NATIVE_THREADS)
+       call    builtin_asm_get_exceptionptrptr
+       mov     v0,itmp2                    /* v0 == itmp1                        */
+#else
+       lea     _exceptionptr,itmp2
+#endif
+       mov     (itmp2),xptr                /* get the exception pointer          */
+       movl    $0,(itmp2)                  /* clear the exception pointer        */
+
+       pop     xpc                         /* get return address                 */
+       sub     $2,xpc                      /* faulting address is ra - 2         */
+       jmp     L_asm_handle_exception
 
-/****************** function asm_dumpregistersandcall **************************
-*                                                                              *
-*   This funtion saves all callee saved registers and calls the function       *
-*   which is passed as parameter.                                              *
-*                                                                              *
-*   This function is needed by the garbage collector, which needs to access    *
-*   all registers which are stored on the stack. Unused registers are          *
-*   cleared to avoid interferances with the GC.                                *
-*                                                                              *
-*   void asm_dumpregistersandcall (functionptr f);                             *
-*                                                                              *
-*******************************************************************************/
 
-asm_dumpregistersandcall:
-        xor     %eax,%eax
-        mov     %eax,(%eax)
-
-               push    %ebp
-        push    %ecx
-        push    %edx
-               push    %ebx
-               push    %esi
-               push    %edi
-                               
-               mov     4(%ebp),%eax            /* load function pointer */
-               call    *%eax                           /* call function */
-
-               pop             %edi
-               pop             %esi
-               pop             %ebx
-        pop     %edx
-               pop     %ecx
-               pop             %ebp
-        
-               ret
-        
-
-/********************* function asm_handle_exception ***************************
+/* asm_handle_exception ********************************************************
 *                                                                              *
 *   This function handles an exception. It does not use the usual calling      *
 *   conventions. The exception pointer is passed in REG_ITMP1 and the          *
@@ -413,540 +338,337 @@ asm_dumpregistersandcall:
 *   the local exception table for a handler. If no one is found, it unwinds    *
 *   stacks and continues searching the callers.                                *
 *                                                                              *
-*   void asm_handle_exception (exceptionptr, exceptionpc);                     *
-*                                                                              *
 *******************************************************************************/
 
-asm_handle_builtin_exception:
-        add     $4,%esp                                                /* clear return address of this call */
-        mov     (%esp),%eax                 /* get exceptionptr               */
-        leave                               /* leave builtin function         */
-        mov     (%esp),%edx                 /* get exceptionpc                */
-        sub     $2,%edx                     /* size of builtin call           */
-        jmp     asm_handle_exception
-        
 asm_handle_nat_exception:
-               add     $4,%esp                                         /* clear return address of native stub */
+       add     $4,sp                       /* clear return address of native stub*/
                
 asm_handle_exception:
-#if 0
-               push %ebp
-               mov %esp,%ebp
-               push %eax       /* exception pointer */
-               push %ecx       /* excepiton pc */
+L_asm_handle_exception:                 /* required for PIC code              */
+       sub     $((ARG_CNT+TMP_CNT)*4),sp   /* create maybe-leaf stackframe       */
 
-               call asm_get_stackTrace
+       SAVE_ARGUMENT_REGISTERS(0)          /* we save arg and temp registers in  */
+       SAVE_TEMPORARY_REGISTERS(ARG_CNT)   /* case this is a leaf method         */
 
-               pop %ecx
-               pop %eax
-               pop %ebp
-#endif
-asm_handle_exception_loop:
-               push    %ebp
-               mov     %esp,%ebp
-        
-               push    %eax                                            /* save exception pointer         */
-               push    %ecx                        /* save exception pc              */
+       mov     $((ARG_CNT+TMP_CNT)*4),itmp3/* prepare a3 for handle_exception    */
+       mov     $1,t0                       /* set maybe-leaf flag                */
 
-#if defined(USE_THREADS) && defined(NATIVE_THREADS)
-               call    cast_lock
-#endif
-               
-               call    findmethod                  /* get the data segment ptr       */
-               mov     %eax,%edx
-                       
-               mov     -4(%ebp),%eax
-               mov     -8(%ebp),%ecx               /* could be changed in findmethod */
-
-               push    %edx                                            /* save data segment pointer      */
-               push    %ebx
-               push    %esi
-               push    %edi
-               
-ex_stack_loop:
-               sub     $20,%esp
-               mov     %eax,(%esp)                                     /* exception pointer              */
-               mov     MethodPointer(%edx),%eax        /* method pointer                 */
-               mov     %eax,4(%esp)
-               mov     %ecx,8(%esp)                            /* exception pc                   */
-
-               movl    $0,12(%esp)             /* line number */
-
-               movl    $1,16(%esp)                                     /* set no unwind flag             */
-               call    builtin_trace_exception
-               add     $20,%esp
-               mov     -12(%ebp),%esi                          /* %esi = data segment pointer    */
-               mov     ExTableSize(%esi),%ecx          /* %ecx = exception table size    */
-               test    %ecx,%ecx                                       /* if empty table skip            */
-               je      empty_table
-
-               lea             ExTableStart(%esi),%edi         /* %edi = start of exception table*/
-               mov     -4(%ebp),%eax               /* get xptr                       */
-               
-ex_table_loop:
-               mov     -8(%ebp),%edx                           /* get xpc                        */
-
-               mov     ExStartPC(%edi),%ebx            /* %ebx = exception start pc      */
-               cmp     %edx,%ebx                                       /* %ebx = (startpc <= xpc)        */
-               jg      ex_table_cont                           /* if (false) continue            */
-               mov     ExEndPC(%edi),%ebx                      /* %ebx = exception end pc        */
-               cmp     %ebx,%edx                                       /* %ebx = (xpc < endpc)           */
-               jge     ex_table_cont                           /* if (false) continue            */
-               mov     ExCatchType(%edi),%ebx          /* arg1 = exception catch type    */
-               test    %ebx,%ebx                                       /* NULL catches everything        */
-               je      ex_handle_it
-
-               mov     offobjvftbl(%eax),%esi          /* %esi = vftblptr(xptr)          */
-               mov     offclassvftbl(%ebx),%ebx    /* %ebx = vftblptr(catchtype) class (not obj) */
-               mov     offbaseval(%esi),%esi           /* %esi = baseval(xptr)           */
-               mov     offbaseval(%ebx),%edx           /* %edx = baseval(catchtype)      */
-               mov     offdiffval(%ebx),%ebx           /* %ebx = diffval(catchtype)      */
-               sub     %edx,%esi                                       /* %esi = baseval(xptr) - baseval(catchtype) */
-               cmp     %ebx,%esi                                       /* xptr is instanceof catchtype   */
-               ja      ex_table_cont
-               
-ex_handle_it:
-               mov     ExHandlerPC(%edi),%edx
-               
-               pop     %edi                        /* restore registers              */
-               pop     %esi
-               pop     %ebx
-        add     $8,%esp                     /* suck %ecx, %edx                */
-        pop     %eax                        /* restore xptr                   */
+L_asm_handle_exception_stack_loop:
+       sub     $(10*4),sp                  /* create stackframe                  */
+       mov     xptr,4*4(sp)                /* save exception pointer             */
+       mov     xpc,5*4(sp)                 /* save exception pc                  */
+       add     sp,itmp3                    /* calculate Java sp into a3...       */
+       add     $(10*4),itmp3
+       mov     itmp3,7*4(sp)               /* ...and save it                     */
+       mov     t0,8*4(sp)                  /* save maybe-leaf flag               */
 
-#if defined(USE_THREADS) && defined(NATIVE_THREADS)
-               call cast_unlock
-#endif
-        
-               leave
-               jmp             *%edx                       /* jump to exception handler      */
-
-ex_table_cont:
-               lea     ExEntrySize(%edi),%edi
-               dec     %ecx
-               test    %ecx,%ecx
-               jg      ex_table_loop
-               
-empty_table:
-        pop     %edi
-        pop     %esi
-        pop     %ebx
-        pop     %edx                        /* restore data segment pointer   */
-        pop     %ecx
-        pop     %eax
-        pop     %ebp
-
-        push    %eax                        /* save exception pointer         */
-        
-ex_already_cleared:
-               mov     IsSync(%edx),%eax                       /* %eax = SyncOffset              */
-               test    %eax,%eax                                       /* if zero no monitorexit         */
-               je      no_monitor_exit
-
-        add     %esp,%eax
-        mov     -4(%eax),%eax               /* we have the xptr on the stack  */
-        push    %edx                        /* save regs                      */
-        push    %eax
-               call    builtin_monitorexit
-               add     $4,%esp
-        pop     %edx                        /* restore regs                   */
-        
-no_monitor_exit:
-        mov     %esp,%eax
-        add     FrameSize(%edx),%eax        /* %eax = frame size              */
-        add     $4,%eax                     /* we have the xptr on the stack  */
-        
-               mov     IntSave(%edx),%ecx          /* %ecx = saved int register count*/
-               test    %ecx,%ecx
-               je      noint
-               cmp     $1,%ecx
-               je      int1
-               cmp     $2,%ecx
-               je      int2
-               cmp     $3,%ecx
-               je      int3
-
-int4:  
-               mov     -32(%eax),%ebx
-
-int3:  
-               mov     -24(%eax),%ebp
+       mov     xpc,0*4(sp)                 /* pass exception pc                  */
+       call    codegen_findmethod
+       mov     v0,6*4(sp)                  /* save data segment pointer          */
 
-int2:  
-               mov     -16(%eax),%esi
-
-int1:  
-               mov     -8(%eax),%edi
+       mov     4*4(sp),itmp3               /* pass exception pointer             */
+       mov     itmp3,0*4(sp)
+       mov     5*4(sp),itmp3               /* pass exception pc                  */
+       mov     itmp3,1*4(sp)
+       mov     v0,2*4(sp)                  /* pass data segment pointer          */
+       mov     7*4(sp),itmp3               /* pass Java stack pointer            */
+       mov     itmp3,3*4(sp)
+       call    exceptions_handle_exception
 
-               shl     $3,%ecx                                         /* multiply by 8 bytes             */
-               sub     %ecx,%eax
-               
-noint:
-               mov     FltSave(%edx),%ecx                      /* %ecx = saved flt register count */
-               test    %ecx,%ecx
-               je      noflt
-               cmp     $1,%ecx
-               je      flt1
-               cmp     $2,%ecx
-               je      flt2
-               cmp     $3,%ecx
-               je      flt3
-               
-flt4:  
-               fldl    -32(%eax)
-               fstp    %st(1)
-
-flt3:  
-               fldl    -24(%eax)
-               fstp    %st(2)
-               
-flt2:  
-               fldl    -16(%eax)
-               fstp    %st(3)
-               
-flt1:  
-               fldl    -8(%eax)
-               fstp    %st(4)
-               
-noflt:
-        pop     %eax                        /* restore exception pointer      */
-        
-        mov     FrameSize(%edx),%ecx        /* %ecx = frame size              */
-        add     %ecx,%esp                   /* unwind stack                   */
-        
-               pop     %ecx                        /* the new xpc is return address  */
-               sub     $2,%ecx
-               
-               jmp             asm_handle_exception_loop
-               
+       test    v0,v0
+       jz      L_asm_handle_exception_not_catched
 
-/********************* function asm_check_clinit *******************************
-*                                                                              *
-*   Does null check and calls monitorenter or throws an exception              *
-*                                                                              *
-*******************************************************************************/
+       mov     v0,xpc                      /* move handlerpc into xpc            */
+       mov     4*4(sp),xptr                /* restore exception pointer          */
+       mov     8*4(sp),t0                  /* get maybe-leaf flag                */
+       add     $(10*4),sp                  /* free stackframe                    */
 
-asm_check_clinit:
-               mov             offclassinit(%eax),%ecx     /* get initialized flag           */
-               test    %ecx,%ecx
-               jnz             L_is_initialized
+       test    t0,t0                       /* test for maybe-leaf flag           */
+       jz      L_asm_handle_exception_no_leaf
 
+       RESTORE_ARGUMENT_REGISTERS(0)       /* if this is a leaf method, we have  */
+       RESTORE_TEMPORARY_REGISTERS(ARG_CNT)/* to restore arg and temp registers  */
 
-                sub             $16,%esp                                 /* build stack frame (4 * 4 bytes) */
+       add     $((ARG_CNT+TMP_CNT)*4),sp   /* remove maybe-leaf stackframe       */
 
-                mov             %eax,(%esp)
+L_asm_handle_exception_no_leaf:
+       jmp     *xpc                        /* jump to exception handler          */
 
-               call    builtin_asm_get_stackframeinfo
-               movl    $0,12(%esp)
-               mov     %eax,8(%esp)
-               mov     (%eax),%ecx
-               mov     %ecx,4(%esp)
-               mov     %esp,%ecx
-               add     $4,%ecx
-               mov     %ecx,(%eax)
+L_asm_handle_exception_not_catched:
+       mov     4*4(sp),xptr                /* restore exception pointer          */
+       mov     6*4(sp),itmp3               /* restore data segment pointer       */
+       mov     8*4(sp),t0                  /* get maybe-leaf flag                */
+       add     $(10*4),sp                  /* free stackframe                    */
 
-               call    class_init                  /* call class_init function       */
+       test    t0,t0
+       jz      L_asm_handle_exception_no_leaf_stack
 
-               mov     4(%esp),%ebx
-               mov     8(%esp),%ecx
-               mov     %ebx,(%ecx)
+       add     $((ARG_CNT+TMP_CNT)*4),sp   /* remove maybe-leaf stackframe       */
+       xor     t0,t0                       /* clear the maybe-leaf flag          */
 
-                add             $16,%esp
+L_asm_handle_exception_no_leaf_stack:
+       mov     FrameSize(itmp3),itmp2      /* get frame size                     */
+       add     sp,itmp2                    /* pointer to save area               */
 
-L_is_initialized:
-               mov             (%esp),%eax                 /* get return address             */
-               sub             $12,%eax                    /* asm_putstatic call code size   */
-               movb    $0xeb,(%eax)                /* jmp rel8                       */
-               movb    $10,1(%eax)                 /* 8-bit offset                   */
-               ret
+       push    xptr                        /* we are out of registers            */
 
+       mov     IntSave(itmp3),itmp1        /* itmp1 = saved int register count   */
+       test    itmp1,itmp1
+       je      noint
 
-/********************* function asm_builtin_monitorenter ***********************
-*                                                                              *
-*   Does null check and calls monitorenter or throws an exception              *
-*                                                                              *
-*******************************************************************************/
+       cmp     $1,itmp1
+       je      int1
+       cmp     $2,itmp1
+       je      int2
 
-asm_builtin_monitorenter:
-               cmpl    $0,4(%esp)
-               je      nb_monitorenter         /* if (null) throw exception          */
-               jmp             builtin_monitorenter    /* else call builtin_monitorenter     */
+       mov     -3*4(itmp2),s0
+int2:  
+       mov     -2*4(itmp2),s1
+int1:  
+       mov     -1*4(itmp2),s2
 
-nb_monitorenter:
-               push    string_java_lang_NullPointerException
-               call    new_exception
-               add     $(1*4),%esp
+       shl     $2,itmp1                    /* multiply by 4 bytes                */
+       sub     itmp1,itmp2
                
-               pop     %ecx                    /* delete return address */
-               sub     $2,%ecx                 /* faulting address is return adress - 2 */
-               jmp     asm_handle_exception
+noint:
+#if 0
+       mov     FltSave(itmp3),itmp1        /* itmp1 = saved flt register count   */
+       test    itmp1,itmp1
+       je      noflt
+
+       cmp     $1,itmp1
+       je      flt1
+       cmp     $2,itmp1
+       je      flt2
+       cmp     $3,itmp1
+       je      flt3
+               
+       fldl    -4*8(itmp2)
+       fstp    %st(1)
+flt3:
+       fldl    -3*8(itmp2)
+       fstp    %st(2)
+flt2:
+       fldl    -2*8(itmp2)
+       fstp    %st(3)
+flt1:
+       fldl    -1*8(itmp2)
+       fstp    %st(4)
                
+noflt:
+#endif
+       pop     xptr                        /* restore exception pointer          */
+       mov     FrameSize(itmp3),itmp2      /* get frame size                     */
+       add     itmp2,sp                    /* unwind stack                       */
 
-/********************* function asm_builtin_monitorexit ************************
-*                                                                              *
-*   Does null check and calls monitorexit or throws an exception               *
-*                                                                              *
-*******************************************************************************/
-
-asm_builtin_monitorexit:
-               mov     4(%esp),%eax
-        test    %eax,%eax
-               je      nb_monitorexit                  /* if (null) throw exception          */
-        push    %ecx                    /* save registers which could be used */
-        push    %edx
-        push    %eax
-               call    builtin_monitorexit             /* else call builtin_monitorenter     */
-        add     $4,%esp
-        pop     %edx                    /* restore registers which could be used */
-        pop     %ecx
-        ret
-
-nb_monitorexit:
-               push    string_java_lang_NullPointerException
-               call    new_exception
-               add     $(1*4),%esp
-               
-               pop     %ecx                    /* delete return address              */
-               sub     $2,%ecx                 /* faulting address is return adress - 2 */
-               jmp     asm_handle_exception
+       pop     xpc                         /* the new xpc is return address      */
+       sub     $2,xpc                      /* subtract 2-bytes for call          */
 
+       xor     itmp3,itmp3                 /* prepare a3 for handle_exception    */
 
-/************************ function asm_builtin_ldiv ****************************
-*                                                                              *
-*   Does null check and calls ldiv or throws an exception                      *
-*                                                                              *
-*******************************************************************************/
+       jmp     L_asm_handle_exception_stack_loop
+               
 
-asm_builtin_ldiv:
-               mov     12(%esp),%eax
-               or      16(%esp),%eax
-               test    %eax,%eax               /* if (null) throw exception          */
-               je      nb_ldiv
+/* asm_wrapper_patcher *********************************************************
 
-               jmp     builtin_ldiv
+   XXX
 
-nb_ldiv:
-               push    string_java_lang_ArithmeticException_message
-               push    string_java_lang_ArithmeticException
-               call    new_exception_message
-               add     $(2*4),%esp
-               
-               pop             %ecx                                    /* delete return address              */
-               sub             $2,%ecx                                 /* faulting address is return adress - 2 */
-               jmp             asm_handle_exception
-                               
+   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
 
-/************************ function asm_builtin_lrem ****************************
-*                                                                              *
-*   Does null check and calls lrem or throws an exception                      *
-*                                                                              *
 *******************************************************************************/
 
-asm_builtin_lrem:
-               mov     12(%esp),%eax
-               or      16(%esp),%eax
-               test    %eax,%eax               /* if (null) throw exception          */
-               je      nb_lrem
+asm_wrapper_patcher:
+       sub     $((2+4)*4+sizestackframeinfo),sp /* create stack frame            */
+
+       mov     itmp1,(0+4)*4(sp)           /* save itmp1 and itmp2               */
+       mov     itmp2,(1+4)*4(sp)           /* may be used by some instructions   */
+
+       mov     sp,itmp1                    /* create stackframe info             */
+       add     $((2+4)*4),itmp1
+       mov     itmp1,0*4(sp)               /* stackframeinfo pointer             */
+       movl    $0,1*4(sp)                  /* if pv is NULL, use findmethod      */
+       mov     sp,itmp2
+       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                 */
+       add     $((1+2+4)*4+sizestackframeinfo),itmp1  /* skip function pointer   */
+       mov     itmp1,0*4(sp)
+       mov     (0+2+4)*4+sizestackframeinfo(sp),itmp1 /* get function pointer    */
+       call    *itmp1                      /* call the patcher function          */
+       mov     v0,1*4(sp)                  /* save return value                  */
+
+       mov     sp,itmp1                    /* remove stackframe info             */
+       add     $((2+4)*4),itmp1
+       mov     itmp1,0*4(sp)               /* stackframeinfo pointer             */
+       call    stacktrace_remove_stackframeinfo
+
+       mov     1*4(sp),itmp3               /* restore return value               */
+       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 */
 
-               jmp     builtin_lrem
+#if defined(USE_THREADS) && defined(NATIVE_THREADS)
+       call    builtin_asm_get_exceptionptrptr
+       mov     v0,itmp2
+#else
+       lea     _exceptionptr,itmp2
+#endif
+       mov     (itmp2),xptr                /* get the exception pointer          */
+       movl    $0,(itmp2)                  /* clear the exception pointer        */
 
-nb_lrem:
-               push    string_java_lang_ArithmeticException_message
-               push    string_java_lang_ArithmeticException
-               call    new_exception_message
-               add     $(2*4),%esp
+       pop     xpc                         /* get and remove return address      */
+       jmp     L_asm_handle_exception
 
-               pop             %ecx                                    /* delete return address              */
-               sub             $2,%ecx                                 /* faulting address is return adress - 2 */
-               jmp             asm_handle_exception
-               
 
-/************************ function asm_builtin_x2x *****************************
-*                                                                              *
-*   Wrapper functions for corner cases                                         *
-*                                                                              *
-*******************************************************************************/
+/* asm_replacement_out *********************************************************
 
-asm_builtin_f2i:
-        sub     $4,%esp
-        fsts    (%esp)
-        call    builtin_f2i
-        add     $4,%esp
-        ret            
+   This code is jumped to from the replacement-out stubs that are executed
+   when a thread reaches an activated replacement point.
 
-asm_builtin_d2i:
-        sub     $8,%esp
-        fstl    (%esp)
-        call    builtin_d2i
-        add     $8,%esp
-        ret            
+   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.
 
-asm_builtin_f2l:
-        sub     $4,%esp
-        fsts    (%esp)
-        call    builtin_f2l
-        add     $4,%esp
-        ret            
+   Stack layout:
+      4                 start of stack inside method to replace
+      0   rplpoint *    info on the replacement point that was reached
 
-asm_builtin_d2l:
-        sub     $8,%esp
-        fstl    (%esp)
-        call    builtin_d2l
-        add     $8,%esp
-        ret            
-
-        
-/******************* function asm_builtin_checkarraycast ***********************
-*                                                                              *
-*   Does the cast check and eventually throws an exception                     *
-*                                                                              *
 *******************************************************************************/
 
-asm_builtin_checkarraycast:
-               sub             $8,%esp                                 /* build stack frame (2 * 4 bytes)    */
-
-               mov             12(%esp),%eax           /* 8 (frame) + 4 (return)             */
-               mov             %eax,(%esp)                             /* save object pointer                */
-
-               mov             20(%esp),%eax
-               mov             %eax,4(%esp)
+/* 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
 
-               call    builtin_checkarraycast  /* builtin_checkarraycast             */
-       
-               test    %eax,%eax               /* if (false) throw exception         */
-               je              nb_carray_throw
+       /* calculate sp of method */
+       mov     sp,itmp1
+       add     $(sizeexecutionstate + REPLACEMENT_ROOM + 4),itmp1
+       mov     itmp1,(offes_sp)(sp)
 
-               mov             12(%esp),%eax                   /* return object pointer              */
-               add             $8,%esp
-               ret
+       /* pv must be looked up via AVL tree */
+       movl    $0,(offes_pv)(sp)
 
-nb_carray_throw:
-               push    string_java_lang_ClassCastException
-               call    new_exception
-               add     $(1*4),%esp
-               
-               add             $8,%esp
-               
-               pop             %ecx                                    /* delete return address              */
-               sub             $2,%ecx                                 /* faulting address is return adress - 2 */
-               jmp             asm_handle_exception
-
-               
-/******************* function asm_builtin_newarray *****************************
-*                                                                              *
-*   Does the cast check and eventually throws an exception                     *
-*                                                                              *
-*******************************************************************************/
+       /* 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_builtin_newarray:
-               sub             $8,%esp                                 /* build stack frame (2 * 4 bytes) */
+/* asm_replacement_in **********************************************************
 
-               mov             12(%esp),%eax
-               mov             %eax,(%esp)
+   This code writes the given execution state and jumps to the replacement
+   code.
 
-               mov             20(%esp),%eax
-               mov             %eax,4(%esp)
+   This function never returns!
 
-               call    builtin_newarray
-       
-               add             $8,%esp
-               ret
+   C prototype:
+      void asm_replacement_in(executionstate *es);
 
-               
-/******************* function asm_builtin_aastore ******************************
-*                                                                              *
-*   Does the cast check and eventually throws an exception                     *
-*                                                                              *
 *******************************************************************************/
 
-asm_builtin_aastore:
-               sub     $12,%esp                /* build stack frame (3 * 4 bytes)    */
-
-               mov     16(%esp),%eax           /* 12 (frame) + 4 (return)            */
-               test    %eax,%eax               /* if null pointer throw exception    */
-               je      nb_aastore_null
-
-               mov     offarraysize(%eax),%edx /* load size                          */
-               mov     24(%esp),%ecx           /* index                              */
-               cmp     %edx,%ecx               /* do bound check                     */
-               jae     nb_aastore_bound        /* if out of bounds throw exception   */
-
-               shl     $2,%ecx                 /* index * 4                          */
-               add     %eax,%ecx               /* add index * 4 to arrayref          */
-                  
-               mov     %ecx,8(%esp)            /* save store position                */
-                  
-               mov     16(%esp),%eax           /* 12 (frame) + 4 (return)            */
-               mov     %eax,(%esp)
-                  
-               mov     32(%esp),%eax           /* object is second argument          */
-               mov     %eax,4(%esp)
-               
-               call    builtin_canstore        /* builtin_canstore(arrayref,object)  */
+asm_replacement_in:
+       mov     4(sp),%ebp                  /* executionstate *es                 */
 
-               test    %eax,%eax               /* if (false) throw exception         */
-               je      nb_aastore_store
+       /* 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     32(%esp),%eax
-               mov     8(%esp),%ecx
-               mov     %eax,offobjarrdata(%ecx)/* store objectptr in array           */
-               
-               add     $12,%esp
-               ret
+       mov     (EBP*8+offes_intregs)(%ebp),%ebp
 
-nb_aastore_null:
-               push    string_java_lang_NullPointerException
-               call    new_exception
-               add     $(1*4),%esp
-               
-               add     $12,%esp
-               pop     %ecx                    /* delete return address              */
-               sub     $2,%ecx                 /* faulting address is return adress - 2 */
-               jmp             asm_handle_exception
-
-nb_aastore_bound:
-               push    %ecx                    /* itmp2 contains array index         */
-               push    string_java_lang_ArrayIndexOutOfBoundsException
-               call    new_exception_int
-               add     $(2*4),%esp
-
-               add     $12,%esp
-               pop     %ecx                    /* delete return address              */
-               sub     $2,%ecx                 /* faulting address is return adress - 2 */
-               jmp     asm_handle_exception
-               
-nb_aastore_store:
-               push    string_java_lang_ArrayStoreException
-               call    new_exception
-               add     $(1*4),%esp
-               
-               add     $12,%esp
-               pop     %ecx                    /* delete return address              */
-               sub     $2,%ecx                 /* faulting address is return adress - 2 */
-               jmp     asm_handle_exception
+       /* jump to new code */
+       ret
 
-               
-/******************* function asm_builtin_arrayinstanceof **********************
+/************************ function asm_builtin_x2x *****************************
 *                                                                              *
-*   Does the instanceof check of arrays                                        *
+*   Wrapper functions for corner cases                                         *
 *                                                                              *
 *******************************************************************************/
 
-asm_builtin_arrayinstanceof:
-               sub             $8,%esp                 /* build stack frame (2 * 4 bytes)    */
+asm_builtin_f2i:
+       sub     $4,%esp
+       fsts    (%esp)
+       call    builtin_f2i
+       add     $4,%esp
+       ret
 
-               mov     12(%esp),%eax
-               mov     %eax,(%esp)
+asm_builtin_d2i:
+       sub     $8,%esp
+       fstl    (%esp)
+       call    builtin_d2i
+       add     $8,%esp
+       ret
 
-               mov     20(%esp),%eax
-               mov     %eax,4(%esp)
+asm_builtin_f2l:
+       sub     $4,%esp
+       fsts    (%esp)
+       call    builtin_f2l
+       add     $4,%esp
+       ret
+
+asm_builtin_d2l:
+       sub     $8,%esp
+       fstl    (%esp)
+       call    builtin_d2l
+       add     $8,%esp
+       ret
 
-               call    builtin_arrayinstanceof
-       
-               add     $8,%esp
-               ret
 
-               
 /******************* function asm_initialize_thread_stack **********************
 *                                                                              *
 * initialized a thread stack                                                   *
@@ -983,40 +705,40 @@ asm_initialize_thread_stack:
 *******************************************************************************/
 
 asm_perform_threadswitch:
-               sub     $36,%esp
-                  
-               mov     %eax,0(%esp)
-               mov     %ecx,4(%esp)
-               mov     %edx,8(%esp)
-               mov     %ebx,12(%esp)
-               mov     %esp,16(%esp)
-               mov     %ebp,20(%esp)
-               mov     %esi,24(%esp)
-               mov     %edi,28(%esp)
-                  
-               mov     36(%esp),%eax           /* save current return address        */
-               mov     %eax,32(%esp)
-                  
-               mov     40(%esp),%eax           /* first argument **from              */
-               mov     %esp,0(%eax)
-                  
-               mov     48(%esp),%eax           /* third argument **stackTop          */
-               mov     %esp,0(%eax)
-                  
-               mov     44(%esp),%eax           /* second argument **to               */
-               mov     0(%eax),%esp            /* load new stack pointer             */
-                  
-               mov     0(%esp),%eax
-               mov     4(%esp),%ecx
-               mov     8(%esp),%edx
-               mov     12(%esp),%ebx
-                                                               /* skip stack pointer */
-               mov     20(%esp),%ebp
-               mov     24(%esp),%esi
-               mov     28(%esp),%edi
-                  
-               add     $32,%esp                /* leave return address on stack      */
-               ret
+       sub     $36,%esp
+          
+       mov     %eax,0(%esp)
+       mov     %ecx,4(%esp)
+       mov     %edx,8(%esp)
+       mov     %ebx,12(%esp)
+       mov     %esp,16(%esp)
+       mov     %ebp,20(%esp)
+       mov     %esi,24(%esp)
+       mov     %edi,28(%esp)
+          
+       mov     36(%esp),%eax         /* save current return address              */
+       mov     %eax,32(%esp)
+          
+       mov     40(%esp),%eax         /* first argument **from                    */
+       mov     %esp,0(%eax)
+          
+       mov     48(%esp),%eax         /* third argument **stackTop                */
+       mov     %esp,0(%eax)
+          
+       mov     44(%esp),%eax         /* second argument **to                     */
+       mov     0(%eax),%esp          /* load new stack pointer                   */
+          
+       mov     0(%esp),%eax
+       mov     4(%esp),%ecx
+       mov     8(%esp),%edx
+       mov     12(%esp),%ebx
+                                     /* skip stack pointer                       */
+       mov     20(%esp),%ebp
+       mov     24(%esp),%esi
+       mov     28(%esp),%edi
+          
+       add     $32,%esp              /* leave return address on stack            */
+       ret
                
 
 /********************* function asm_switchstackandcall *************************
@@ -1033,343 +755,72 @@ asm_perform_threadswitch:
 *******************************************************************************/
 
 asm_switchstackandcall:
-               movl    4(%esp),%edx                    /* first argument *stack              */
-               subl    $8,%edx                                 /* allocate new stack                 */
+       mov     4(%esp),%edx          /* first argument *stack                    */
+       sub     $8,%edx               /* allocate new stack                       */
 
-               movl    (%esp),%eax                             /* save return address on new stack   */
-               movl    %eax,(%edx)
+       mov     (%esp),%eax           /* save return address on new stack         */
+       mov     %eax,(%edx)
 
-               movl    %esp,4(%edx)                    /* save old stack pointer on new stack*/
+       mov     %esp,4(%edx)          /* save old stack pointer on new stack      */
 
-               movl    12(%esp),%eax                   /* third argument **stacktopsave      */
-               movl    %esp,(%eax)                             /* save old stack pointer to variable */
-
-               movl    8(%esp),%eax                    /* load function pointer              */
-               movl    16(%esp),%ecx                   /* fourth argument *p                 */
-               
-               movl    %edx,%esp                               /* switch to new stack                */
+       mov     12(%esp),%eax         /* third argument **stacktopsave            */
+       mov     %esp,(%eax)           /* save old stack pointer to variable       */
 
-               subl    $4,%esp
-               movl    %ecx,0(%esp)                    /* pass pointer                       */
-               call    *%eax                                   /* and call function                  */
-               addl    $4,%esp
-
-               movl    (%esp),%edx                             /* load return address                */
-               movl    4(%esp),%esp                    /* switch to old stack                */
-               movl    %edx,(%esp)
-               ret
-
-               
-Java_java_lang_VMSecurityManager_currentClassLoader:
-       lea  builtin_asm_getclassloader,%eax 
-       push %eax       /*store collector function pointer*/
-       jmp getClassContext_begin
-Java_java_lang_VMSecurityManager_getClassContext:
-       lea  builtin_asm_createclasscontextarray,%eax 
-       push %eax /*store collector function pointer*/
-getClassContext_begin: /*start the real work*/
-
-       mov %esp,%eax
-       sub $4,%eax
-       sub $68,%esp /*64 memory location without overwriting return adress and collector function adress*/
-       mov %esp,%ebx   /*end of allocated memory block for classpointers is the adress of the working data block +4 */
-       push $0 /*%esp+32 was native*/
-       push %eax /*%esp+24 blkbegin*/
-       push %eax /*%esp+20 currentpos*/
-       push %ebx /*%esp+16 blkend*/
-
-       call builtin_asm_get_threadrootmethod
-       push %eax /*%esp+12*/
-       movl 104(%esp),%eax /*(stack contains: threadRootMethod,blkend,blkpos,blkbegin,was native, data(64kB),collector,ret,env,class,frame stack info of stub, we want the frame stack info  of thestub*/
-       movl %esp,%edx
-       addl $116, %edx
-       push %edx /*esp+8*/ /*position of return address of native stub*/
-       call builtin_asm_get_stackframeinfo
-       movl (%eax),%eax /*comment ??*/
-       push 0(%eax) /*esp+4*/ /*address of frame info block*/
-       movl 124(%esp),%edx
-
-/*DEBUG*/
-/*     mov %esp,%eax
-       addl $116,%eax
-       push %eax
-       call i386_native_stub_debug
-       pop %eax*/
-
-       push %edx /*esp+0*/ /*return adress out of native stub*/
-       call findmethod /*find calling java method, this one is still to be skipped (==SecurityManager.getClassContext (or .currentClassLoader)*/
-
-/*DEBUGGING*/
-/*     push %eax
-       movl MethodPointer(%eax),%eax
-       push %eax
-       call temporaryGetClassContextHelper
-       pop %eax
-       call traverseStackInfo
-       pop %eax
-*/
-
-       movl 20(%esp),%edx
-       movl MethodPointer(%eax),%ebx
-       movl offclassmethodinfo(%ebx),%ecx
-       movl %ecx,(%edx)
-       subl $4,%edx
-       movl %edx,20(%esp)
-
-       mov 8(%esp),%ebx /*pos of return adress */
-       add FrameSize(%eax),%ebx
-       add $4,%ebx     /*adress of new return adress (out of Securitymanager.*/
-       mov %ebx,8(%esp) 
-       mov %eax,(%esp)
-
-       /* by now we have skipped this method call*/
-
-getClassContext_next:  
-       movl 8(%esp),%eax
-       movl (%eax),%eax
-       movl %eax,(%esp) /*return adress*/
-
-       call findmethod
-
-       cmp $1,32(%esp)
-       mov 8(%esp),%ebx
-       add FrameSize(%eax),%ebx
-       add $4,%ebx
-       mov %ebx,8(%esp) /*store adress of next return adress*/
-getClassContext_nextRetStored:
-
-       mov MethodPointer(%eax),%ecx    /*get struct methodinfo*/
-
-       cmp $0,%ecx
-       je getClassContext_nativeCall
-       /*save class pointer*/
-       movl $0,32(%esp)
-getClassContext_saveClassPointer:
-       movl 20(%esp),%ebx      /*get temporary memory adress in stack*/
-       movl offclassmethodinfo(%ecx),%edx /* get class pointer of method*/
-       movl %edx,(%ebx) /*save */
-       sub $4,%ebx     /*calculate next position */
-       movl %ebx,20(%esp) /* check if the new adress would overwrite our working data */
-       cmp %ebx,16(%esp)
-       je getClassContext_incStack
-getClassContext_checkLeave:
+       mov     8(%esp),%eax          /* load function pointer                    */
+       mov     16(%esp),%ecx         /* fourth argument *p                       */
        
-       cmp 12(%esp),%ecx       /*check if we reached the toplevel method of our thread*/
-       je  getClassContext_leave /*yes ->leave*/
+       mov     %edx,%esp             /* switch to new stack                      */
 
-/*DEBUGING*/
-/*     mov %ecx,(%esp)
-       call temporaryGetClassContextHelper
-*/
-       
-       
-       jmp getClassContext_next /*continue*/
-
-
-getClassContext_nativeCall:
-       movl $1,32(%esp)
-       movl 4(%esp),%eax       /*get top most element on stackframe help information stack*/
-       movl 0(%eax),%ecx 
-       movl %ecx,4(%esp)
-       addl $8,%eax
-       movl (%eax),%ecx
-       addl $4,%eax
-       movl %eax,8(%esp)
-       
-       cmp $0,%ecx
-       je getClassContext_checkLeave
-       jmp getClassContext_saveClassPointer
-
-getClassContext_incStack:
-       /*make another 64 in our temporary storage free and store the workingdata */
-       movl %esp,%edx
-       subl $40,%esp /*should be 32*/
-       push 32(%edx)
-       push 28(%edx)
-       push 24(%edx)
-       push 20(%edx)
-       push 16(%edx)
-       push 12(%edx)
-       push 8(%edx)
-       push 4(%edx)
-       push 0(%edx)
-       subl $64,16(%esp)
-
-       jmp getClassContext_checkLeave /* continue */
-
-getClassContext_leave:
-/*DEBUGING*/
-/*     mov %ecx,(%esp)
-       call temporaryGetClassContextHelper*/
-
-       /*call collector function with begin/end of temporary classarray*/
-       push 24(%esp)
-       push 24(%esp)
-       
-       movl 32(%esp),%eax
-       add $4,%eax
-       movl (%eax),%ebx
-       call *%ebx
-
-       /* free stack memory of this function*/
-       mov 32(%esp),%esp
-       add $8,%esp
-       ret
+       sub     $4,%esp
+       mov     %ecx,0(%esp)          /* pass pointer                             */
+       call    *%eax                 /* and call function                        */
+       add     $4,%esp
 
+       mov     (%esp),%edx           /* load return address                      */
+       mov     4(%esp),%esp          /* switch to old stack                      */
+       mov     %edx,(%esp)
+       ret
 
-asm_builtin_new:
-/*optimize a littlebit */
-               mov %esp,%eax
-/*DEBUG*/
-/*             push %eax
-               call i386_native_stub_debug
-               pop %eax */
                
-               movl 4(%esp),%eax
-               mov     offclassinit(%eax),%ecx     /* get initialized flag           */
-               test    %ecx,%ecx
-               jnz             L_builtin_new_noinit
-
-                sub             $16,%esp                                 /* build stack frame (4 * 4 bytes) */
-
-                mov             20(%esp),%eax
-                mov             %eax,(%esp)
-
-               call    builtin_asm_get_stackframeinfo
-               movl    $0,12(%esp)
-               mov     %eax,8(%esp)
-               mov     (%eax),%ebx
-               mov     %ebx,4(%esp)
-               mov     %esp,%ecx
-               add     $4,%ecx
-               mov     %ecx,(%eax)
-
-                call    builtin_new
-
-               mov     4(%esp),%ebx
-               mov     8(%esp),%ecx
-               mov     %ebx,(%ecx)
-
-                add             $16,%esp
-
-               jmp L_builtin_new_patch
-
-
-L_builtin_new_noinit:
-               mov 4(%esp),%eax
-               push %eax
-               call builtin_new
-               add $4,%esp
-               /*jmp L_builtin_new_patch*/
-
-L_builtin_new_patch:
-/*add patching code here */
-               lea builtin_new,%edx
-               mov (%esp),%ecx
-               mov %edx,-6(%ecx)       /*patch calling instruction, t directly call builtin_new the next time*/
-               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
 
+       .data
 
-asm_get_stackTrace:
-       push %ebp /*(%ebp-4)*/
-       mov %esp,%ebp
-       add $4,%ebp
-       push %edi /*(%ebp-8)*/
-       push %esi /*(%ebp-12)*/
-       push %ebx /*(%ebp-16)*/
-       call builtin_asm_get_stackframeinfo
-       movl (%eax),%eax
-       pushl 0(%eax) /*(%ebp-20)*/
-       lea 12(%eax),%edi
-       call builtin_asm_get_threadrootmethod
-       pushl %eax /*(%ebp-24)*/
+asm_criticalsections:
+#if defined(USE_THREADS) && defined(NATIVE_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
 
-       pushl (%edi)
-asm_get_stackTraceLoop:
-       call findmethod
-       mov %eax,%esi
-       add $4,%esp
-       pushl $1 /*no indent*/
 
-       mov (%edi),%edx
-       sub $4,%edx
+/* Disable exec-stacks, required for Gentoo ***********************************/
 
-get_stackTrace_line:
-       movl LineNumberTableSize(%esi),%ecx
-       test    %ecx,%ecx /* skip if empty line table */
-       je      get_stackTrace_noLineInfo
+#if defined(__GCC__) && defined(__ELF__)
+       .section .note.GNU-stack,"",@progbits
+#endif
 
-       movl LineNumberTableStart(%esi),%ebx
-       
-get_stackTrace_lineLoop:
-       cmp %edx,LinePC(%ebx)
-       jg get_stackTrace_nextLineInfo
-
-       pushl LineLine(%ebx)
-       jmp get_stackTrace_cont
-
-get_stackTrace_nextLineInfo:   
-       lea LineEntrySize(%ebx),%ebx
-       dec %ecx
-       test %ecx,%ecx
-
-       jne get_stackTrace_lineLoop
-
-get_stackTrace_noLineInfo:
-       pushl $0
-
-
-get_stackTrace_cont:
-       pushl (%edi) /*4*/
-       pushl MethodPointer(%esi)
-       pushl $0 /*8(%ebp)*/ /*exception ptr*/
-       call builtin_trace_exception
-       add $12,%esp
-
-       movl MethodPointer(%esi),%eax
-       movl %eax,4(%esp)
-       test %eax,%eax
-       je get_stackTrace_nat
-
-       cmp %eax,-24(%ebp)
-       je get_stackTrace_leave
-
-       mov FrameSize(%esi),%eax
-       add $4,%edi
-       add %eax,%edi
-       pushl (%edi)
-       jmp asm_get_stackTraceLoop
-
-get_stackTrace_nat:
-       add $8,%esp
-       movl -20(%ebp),%eax
-       cmp $0,%eax
-       je get_stackTrace_leave
-       movl  0(%eax),%ebx
-       movl  %ebx,-20(%ebp)
-       pushl 8(%eax)
-       pushl $0
-       lea 12(%eax),%edi
-       pushl (%edi)
-       jmp asm_get_stackTraceLoop
-
-get_stackTrace_leave:
-       mov %esp,%eax
-       lea -24(%ebp),%ebx
-       push %ebx
-       push %eax
-       push 4(%ebp)
-       call builtin_stacktrace_copy
-
-       lea -16(%ebp),%esp
-       pop %ebx
-       pop %esi
-       pop %edi
-       pop %ebp
-       ret
 
 /*
  * These are local overrides for various environment variables in Emacs.
@@ -1382,4 +833,5 @@ get_stackTrace_leave:
  * c-basic-offset: 4
  * tab-width: 4
  * End:
+ * vim:noexpandtab:sw=4:ts=4:
  */