-/* 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 968 2004-03-19 17:52:42Z jowenn $
+ 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 ***************************
* 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 16(%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 *
* 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 *
*******************************************************************************/
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 *************************
*******************************************************************************/
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.
* c-basic-offset: 4
* tab-width: 4
* End:
+ * vim:noexpandtab:sw=4:ts=4:
*/