X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;f=src%2Fvm%2Fjit%2Fi386%2Fasmpart.S;h=501ab37b56488728eea2ec28cc141e2ad47ee736;hb=56f36393b3193056068f0f3712360d9929aec170;hp=3951e1a24651481c9a5ffa9f6bd32373f305e645;hpb=bc55009838ad3931e78e6b3d54f9f4b75a6b4e66;p=cacao.git diff --git a/src/vm/jit/i386/asmpart.S b/src/vm/jit/i386/asmpart.S index 3951e1a24..501ab37b5 100644 --- a/src/vm/jit/i386/asmpart.S +++ b/src/vm/jit/i386/asmpart.S @@ -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. @@ -20,110 +19,93 @@ 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 779 2003-12-14 18:11:35Z stefan $ + Changes: Joseph Wenninger + Edwin Steiner + + $Id: asmpart.S 4643 2006-03-16 18:38:42Z edwin $ */ -#include "offsets.h" +#include "config.h" -/* data segment offsets */ +#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 MethodPointer -4 -#define FrameSize -8 -#define IsSync -12 -#define IsLeaf -16 -#define IntSave -20 -#define FltSave -24 -#define ExTableSize -28 -#define ExTableStart -28 +#include "vm/jit/methodheader.h" -#define ExEntrySize -16 -#define ExStartPC -4 -#define ExEndPC -8 -#define ExHandlerPC -12 -#define ExCatchType -16 - .text -/********************* exported functions and variables ***********************/ +/* exported functions and variables *******************************************/ - .globl has_no_x_instr_set - .globl asm_calljavafunction - .globl asm_calljavafunction2 - .globl asm_calljavafunction2long - .globl asm_calljavafunction2double + .globl asm_md_init + + .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_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 asm_builtin_trace - .globl asm_builtin_exittrace - .globl asm_xadd - -/*************************** imported functions *******************************/ - - .globl jit_compile - .globl builtin_monitorexit - .globl builtin_throw_exception - .globl builtin_trace_exception - .globl class_java_lang_Object - .globl findmethod -#if defined(USE_THREADS) && defined(NATIVE_THREADS) - .globl cast_lock - .globl cast_unlock -#endif + .globl asm_criticalsections + .globl asm_getclassvalues_atomic -/*********************** function has_no_x_instr_set *************************** -* * -* determines if the byte support instruction set (21164a and higher) * -* is available. * -* * -* Use it on i386 architecture to init the fpu. * -* * -*******************************************************************************/ -has_no_x_instr_set: - finit /* intitialize the fpu */ +/* asm_md_init ***************************************************************** - pushl $0x027f /* Round to nearest, 53-bit mode, exceptions masked */ - fldcw (%esp) - addl $4,%esp - - xor %eax,%eax /* result code 0 (not used for i386) */ - ret + Initialize machine dependent stuff. + + See: http://www.srware.com/linux_numerics.txt + + 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. + + Fixes: http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=350729 + +*******************************************************************************/ + +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 *************************** @@ -135,349 +117,220 @@ has_no_x_instr_set: * method into machine code. * * * * C-prototype: * -* javaobject_header *asm_calljavamethod (methodinfo *m, * -* void *arg1, void *arg2, void *arg3, void *arg4); * +* javaobject_header *asm_vm_call_method(methodinfo *m, * +* u4 count, u4 size, void *callblock); * * * *******************************************************************************/ -call_name2: - .ascii "calljavafunction\0\0" - .align 8 - .long 0 /* catch type all */ - .long calljava_xhandler2 /* handler pc */ - .long calljava_xhandler2 /* end pc */ - .long asm_calljavafunction /* start pc */ - .long 1 /* extable 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) - - mov %edx,12(%esp) - mov 16(%ebp),%eax - mov %eax,8(%esp) - - mov %edx,4(%esp) - mov 12(%ebp),%eax - mov %eax,(%esp) - mov 8(%ebp),%eax /* move function pointer to %eax */ - - lea asm_call_jit_compiler,%edx - call *%edx /* call JIT compiler */ - -calljava_jit2: -calljava_return2: -calljava_ret2: - add $32,%esp - pop %edi /* restore registers */ - pop %esi - pop %ebx - leave - ret + .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 */ + + push %ebx /* save registers */ + push %esi + push %edi + + 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 */ + 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 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 $sizevmarg,%eax /* goto next argument block */ + jmp calljava_copyloop + +calljava_copydone: + mov 2*4(%ebp),itmp1 /* move function pointer to itmp1 */ + + 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 */ - call builtin_throw_exception - add $4,%esp + push xptr /* pass exception pointer */ + call builtin_throw_exception + add $4,sp + xor v0,v0 /* return NULL */ + jmp L_asm_vm_call_method_return - add $32,%esp - pop %edi /* restore registers */ - pop %esi - pop %ebx - leave - ret - +/* asm_call_jit_compiler ******************************************************* -/********************* 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); * -* * -*******************************************************************************/ - -call_name3: - .ascii "calljavafunction2\0\0" + Invokes the compiler for untranslated JavaVM methods. - .align 8 - .long 0 /* catch type all */ - .long calljava_xhandler3 /* handler pc */ - .long calljava_xhandler3 /* end pc */ - .long asm_calljavafunction2 /* start pc */ - .long 1 /* extable size */ - .long 0 /* fltsave */ - .long 0 /* intsave */ - .long 0 /* isleaf */ - .long 0 /* IsSync */ - .long 32 /* frame size */ - .long 0 /* method pointer (pointer to name) */ + 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: -/********************* 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); * -* * -*******************************************************************************/ + Method address was either loaded using -call_name4: - .ascii "calljavafunction2double\0\0" + i386_mov_imm_reg(a, REG_ITMP2) ; invokestatic/special + i386_call_reg(REG_ITMP2) - .align 8 - .long 0 /* catch type all */ - .long calljava_xhandler3 /* handler pc */ - .long calljava_xhandler3 /* end pc */ - .long asm_calljavafunction2double /* start pc */ - .long 1 /* extable size */ - .long 0 /* fltsave */ - .long 0 /* intsave */ - .long 0 /* isleaf */ - .long 0 /* IsSync */ - .long 32 /* frame size */ - .long 0 /* method pointer (pointer to name) */ + or -/********************* 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); * -* * -*******************************************************************************/ + 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) -call_name5: - .ascii "calljavafunction2long\0\0" + In the static case the method pointer can be computed using the + return address and the lda function following the jmp instruction. - .align 8 - .long 0 /* catch type all */ - .long calljava_xhandler3 /* handler pc */ - .long calljava_xhandler3 /* end pc */ - .long asm_calljavafunction2long /* start pc */ - .long 1 /* extable 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: - push %ebp /* save ebp */ - - mov %esp,%eax /* save stackptr */ - mov 20(%esp),%ebp - - push %ebx /* save registers */ - push %esi - push %edi - - sub $32,%esp - - mov sizejniblock*3+offjniitem+4(%ebp),%ebx - mov %ebx,28(%esp) - mov sizejniblock*3+offjniitem(%ebp),%ebx - mov %ebx,24(%esp) - - mov sizejniblock*2+offjniitem+4(%ebp),%ebx - mov %ebx,20(%esp) - mov sizejniblock*2+offjniitem(%ebp),%ebx - mov %ebx,16(%esp) - - - mov sizejniblock+offjniitem+4(%ebp),%ebx - mov %ebx,12(%esp) - mov sizejniblock+offjniitem(%ebp),%ebx - mov %ebx,8(%esp) - - mov offjniitem+4(%ebp),%ebx - mov %ebx,4(%esp) - mov offjniitem(%ebp),%ebx - mov %ebx,0(%esp) - - mov %eax,%ebp - mov 8(%ebp),%eax /* move function pointer to %eax */ - - lea asm_call_jit_compiler,%edx - call *%edx /* call JIT compiler */ - -calljava_jit3: -calljava_return3: -calljava_ret3: - add $32,%esp - pop %edi /* restore registers */ - pop %esi - pop %ebx - leave - ret - -calljava_xhandler3: - 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 - - -/****************** 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: - push %ebx /* save register */ - push %ebp - - 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)? */ - jne L_not_static_special - - sub $6,%ebp /* calculate address of immediate */ - jmp L_call_jit_compile +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 (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,itmp3 /* calculate address of immediate */ + jmp L_call_jit_compile L_not_static_special: - cmp $0xd0,%bl /* called with `call *REG_ITMP1' (%eax) */ - 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 */ - jmp L_call_jit_compile + cmp $0xd0,itmp1b /* called with `call *REG_ITMP1' */ + jne L_not_virtual_interface + + 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_calljavamethod */ - 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 */ - call jit_compile - add $4,%esp - - pop %ebp /* restore address for method pointer */ - test %ebp,%ebp /* is address == 0 (asm_calljavamethod) */ - je L_call_method - - mov %eax,(%ebp) /* and now save the new pointer */ + 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 + 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 */ + + 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 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 * @@ -485,469 +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: - push %ebp - mov %esp,%ebp - - push %eax /* save exception pointer */ - push %ecx /* save exception pc */ +L_asm_handle_exception: /* required for PIC code */ + sub $((ARG_CNT+TMP_CNT)*4),sp /* create maybe-leaf stackframe */ -#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 $16,%esp - mov %eax,(%esp) /* exception pointer */ - mov MethodPointer(%edx),%eax /* method pointer */ - mov %eax,4(%esp) - mov %ecx,8(%esp) /* exception pc */ - movl $1,12(%esp) /* set no unwind flag */ - call builtin_trace_exception - add $16,%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 */ + SAVE_ARGUMENT_REGISTERS(0) /* we save arg and temp registers in */ + SAVE_TEMPORARY_REGISTERS(ARG_CNT) /* case this is a leaf method */ -#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 $((ARG_CNT+TMP_CNT)*4),itmp3/* prepare a3 for handle_exception */ + mov $1,t0 /* set maybe-leaf flag */ -int2: - mov -16(%eax),%esi +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 */ -int1: - mov -8(%eax),%edi + mov xpc,0*4(sp) /* pass exception pc */ + call codegen_findmethod + mov v0,6*4(sp) /* save data segment pointer */ - 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) + 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 -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 - + test v0,v0 + jz L_asm_handle_exception_not_catched -/********************* function asm_builtin_monitorenter *********************** -* * -* 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_builtin_monitorenter: - cmpl $0,4(%esp) - je nb_monitorenter /* if (null) throw exception */ - jmp builtin_monitorenter /* else call builtin_monitorenter */ + test t0,t0 /* test for maybe-leaf flag */ + jz L_asm_handle_exception_no_leaf -nb_monitorenter: - popl %ecx /* delete return address */ - subl $2,%ecx /* faulting address is return adress - 2 */ - movl proto_java_lang_NullPointerException,%eax - jmp asm_handle_exception - + RESTORE_ARGUMENT_REGISTERS(0) /* if this is a leaf method, we have */ + RESTORE_TEMPORARY_REGISTERS(ARG_CNT)/* to restore arg and temp registers */ -/********************* function asm_builtin_monitorexit ************************ -* * -* Does null check and calls monitorexit or throws an exception * -* * -*******************************************************************************/ + add $((ARG_CNT+TMP_CNT)*4),sp /* remove maybe-leaf stackframe */ -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: - popl %ecx /* delete return address */ - subl $2,%ecx /* faulting address is return adress - 2 */ - movl proto_java_lang_NullPointerException,%eax - jmp asm_handle_exception - - -/************************ function asm_builtin_ldiv **************************** -* * -* Does null check and calls ldiv or throws an exception * -* * -*******************************************************************************/ +L_asm_handle_exception_no_leaf: + jmp *xpc /* jump to exception handler */ -asm_builtin_ldiv: - movl 12(%esp),%eax - orl 16(%esp),%eax - test %eax,%eax /* if (null) throw exception */ - je nb_ldiv +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 */ - jmp builtin_ldiv + test t0,t0 + jz L_asm_handle_exception_no_leaf_stack -nb_ldiv: - popl %ecx /* delete return address */ - subl $2,%ecx /* faulting address is return adress - 2 */ - movl proto_java_lang_ArithmeticException,%eax - jmp asm_handle_exception - + add $((ARG_CNT+TMP_CNT)*4),sp /* remove maybe-leaf stackframe */ + xor t0,t0 /* clear the maybe-leaf flag */ -/************************ function asm_builtin_lrem **************************** -* * -* Does null check and calls lrem or throws an exception * -* * -*******************************************************************************/ +L_asm_handle_exception_no_leaf_stack: + mov FrameSize(itmp3),itmp2 /* get frame size */ + add sp,itmp2 /* pointer to save area */ + + push xptr /* we are out of registers */ -asm_builtin_lrem: - movl 12(%esp),%eax - orl 16(%esp),%eax - test %eax,%eax /* if (null) throw exception */ - je nb_lrem + mov IntSave(itmp3),itmp1 /* itmp1 = saved int register count */ + test itmp1,itmp1 + je noint - jmp builtin_lrem + cmp $1,itmp1 + je int1 + cmp $2,itmp1 + je int2 -nb_lrem: - popl %ecx /* delete return address */ - subl $2,%ecx /* faulting address is return adress - 2 */ - movl proto_java_lang_ArithmeticException,%eax - jmp asm_handle_exception + mov -3*4(itmp2),s0 +int2: + mov -2*4(itmp2),s1 +int1: + mov -1*4(itmp2),s2 + + shl $2,itmp1 /* multiply by 4 bytes */ + sub itmp1,itmp2 +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_x2x ***************************** -* * -* Wrapper functions for corner cases * -* * -*******************************************************************************/ + pop xpc /* the new xpc is return address */ + sub $2,xpc /* subtract 2-bytes for call */ -asm_builtin_f2i: - sub $4,%esp - fsts (%esp) - call builtin_f2i - add $4,%esp - ret + xor itmp3,itmp3 /* prepare a3 for handle_exception */ -asm_builtin_d2i: - sub $8,%esp - fstl (%esp) - call builtin_d2i - add $8,%esp - ret + jmp L_asm_handle_exception_stack_loop + -asm_builtin_f2l: - sub $4,%esp - fsts (%esp) - call builtin_f2l - add $4,%esp - ret +/* asm_wrapper_patcher ********************************************************* -asm_builtin_d2l: - sub $8,%esp - fstl (%esp) - call builtin_d2l - add $8,%esp - ret - - -/*********************** function new_builtin_checkcast ************************ -* * -* Does the cast check and eventually throws an exception * -* * -*******************************************************************************/ + XXX -asm_builtin_checkcast: - xorl %eax,%eax - movl $0,(%eax) - ret + 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_checkarraycast *********************** -* * -* Does the cast check and eventually throws an exception * -* * *******************************************************************************/ -asm_builtin_checkarraycast: - subl $8,%esp /* build stack frame (2 * 4 bytes) */ +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 */ - movl 12(%esp),%eax /* 8 (frame) + 4 (return) */ - movl %eax,(%esp) /* save object pointer */ +#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 */ - movl 20(%esp),%eax - movl %eax,4(%esp) + pop xpc /* get and remove return address */ + jmp L_asm_handle_exception - call builtin_checkarraycast /* builtin_checkarraycast */ - - test %eax,%eax /* if (false) throw exception */ - je nb_carray_throw - movl 12(%esp),%eax /* return object pointer */ - addl $8,%esp - ret +/* asm_replacement_out ********************************************************* -nb_carray_throw: - addl $8,%esp - - popl %ecx /* delete return address */ - subl $2,%ecx /* faulting address is return adress - 2 */ - movl proto_java_lang_ClassCastException,%eax - jmp asm_handle_exception + This code is jumped to from the replacement-out stubs that are executed + when a thread reaches an activated replacement point. + + The purpose of asm_replacement_out is to read out the parts of the + execution state that cannot be accessed from C code, store this state, + and then call the C function replace_me. + + Stack layout: + 4 start of stack inside method to replace + 0 rplpoint * info on the replacement point that was reached - -/******************* function asm_builtin_newarray ***************************** -* * -* Does the cast check and eventually throws an exception * -* * *******************************************************************************/ -asm_builtin_newarray: - subl $8,%esp /* build stack frame (2 * 4 bytes) */ +/* 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 - movl 12(%esp),%eax - movl %eax,(%esp) + /* calculate sp of method */ + mov sp,itmp1 + add $(sizeexecutionstate + REPLACEMENT_ROOM + 4),itmp1 + mov itmp1,(offes_sp)(sp) - movl 20(%esp),%eax - movl %eax,4(%esp) + /* pv must be looked up via AVL tree */ + movl $0,(offes_pv)(sp) - call builtin_newarray - - addl $8,%esp - ret + /* 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 */ - -/******************* function asm_builtin_aastore ****************************** -* * -* Does the cast check and eventually throws an exception * -* * -*******************************************************************************/ +/* asm_replacement_in ********************************************************** -asm_builtin_aastore: - subl $12,%esp /* build stack frame (3 * 4 bytes) */ + This code writes the given execution state and jumps to the replacement + code. - movl 16(%esp),%eax /* 12 (frame) + 4 (return) */ - test %eax,%eax /* if null pointer throw exception */ - je nb_aastore_null + This function never returns! - movl offarraysize(%eax),%edx /* load size */ - movl 24(%esp),%ecx /* index */ - cmpl %edx,%ecx /* do bound check */ - ja nb_aastore_bound /* if out of bounds throw exception */ + C prototype: + void asm_replacement_in(executionstate *es); - shll $2,%ecx /* index * 4 */ - addl %eax,%ecx /* add index * 4 to arrayref */ - - movl %ecx,8(%esp) /* save store position */ - - movl 16(%esp),%eax /* 12 (frame) + 4 (return) */ - movl %eax,(%esp) +*******************************************************************************/ - movl 32(%esp),%eax /* object is second argument */ - movl %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_throw + /* 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 - movl 32(%esp),%eax - movl 8(%esp),%ecx - movl %eax,offobjarrdata(%ecx)/* store objectptr in array */ - - addl $12,%esp - ret - -nb_aastore_null: - addl $12,%esp - popl %ecx /* delete return address */ - subl $2,%ecx /* faulting address is return adress - 2 */ - movl proto_java_lang_NullPointerException,%eax - jmp asm_handle_exception - -nb_aastore_bound: - addl $12,%esp - popl %ecx /* delete return address */ - subl $2,%ecx /* faulting address is return adress - 2 */ - movl proto_java_lang_ArrayIndexOutOfBoundsException,%eax - jmp asm_handle_exception - -nb_aastore_throw: - addl $12,%esp - popl %ecx /* delete return address */ - subl $2,%ecx /* faulting address is return adress - 2 */ - movl proto_java_lang_ArrayStoreException,%eax - jmp asm_handle_exception + mov (EBP*8+offes_intregs)(%ebp),%ebp - -/******************* function asm_builtin_arrayinstanceof ********************** + /* jump to new code */ + ret + +/************************ function asm_builtin_x2x ***************************** * * -* Does the instanceof check of arrays * +* Wrapper functions for corner cases * * * *******************************************************************************/ -asm_builtin_arrayinstanceof: - subl $8,%esp /* build stack frame (2 * 4 bytes) */ +asm_builtin_f2i: + sub $4,%esp + fsts (%esp) + call builtin_f2i + add $4,%esp + ret - movl 12(%esp),%eax - movl %eax,(%esp) +asm_builtin_d2i: + sub $8,%esp + fstl (%esp) + call builtin_d2i + add $8,%esp + ret - movl 20(%esp),%eax - movl %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 - - addl $8,%esp - ret - /******************* function asm_initialize_thread_stack ********************** * * * initialized a thread stack * @@ -956,21 +677,21 @@ asm_builtin_arrayinstanceof: *******************************************************************************/ asm_initialize_thread_stack: - movl 8(%esp),%eax /* (to)->stackEnd */ - subl $36,%eax /* 4 bytes * 8 regs + 4 bytes func */ - - xorl %edx,%edx - movl %edx,0(%eax) - movl %edx,4(%eax) - movl %edx,8(%eax) - movl %edx,12(%eax) - movl %edx,16(%eax) - movl %edx,20(%eax) - movl %edx,24(%eax) - movl %edx,28(%eax) - - movl 4(%esp),%edx /* save (u1*) (func) */ - movl %edx,32(%eax) + mov 8(%esp),%eax /* (to)->stackEnd */ + sub $36,%eax /* 4 bytes * 8 regs + 4 bytes func */ + + xor %edx,%edx + mov %edx,0(%eax) + mov %edx,4(%eax) + mov %edx,8(%eax) + mov %edx,12(%eax) + mov %edx,16(%eax) + mov %edx,20(%eax) + mov %edx,24(%eax) + mov %edx,28(%eax) + + mov 4(%esp),%edx /* save (u1*) (func) */ + mov %edx,32(%eax) ret /* return restorepoint in %eax */ @@ -984,40 +705,40 @@ asm_initialize_thread_stack: *******************************************************************************/ asm_perform_threadswitch: - subl $36,%esp - - movl %eax,0(%esp) - movl %ecx,4(%esp) - movl %edx,8(%esp) - movl %ebx,12(%esp) - movl %esp,16(%esp) - movl %ebp,20(%esp) - movl %esi,24(%esp) - movl %edi,28(%esp) - - movl 36(%esp),%eax /* save current return address */ - movl %eax,32(%esp) - - movl 40(%esp),%eax /* first argument **from */ - movl %esp,0(%eax) - - movl 48(%esp),%eax /* third argument **stackTop */ - movl %esp,0(%eax) - - movl 44(%esp),%eax /* second argument **to */ - movl 0(%eax),%esp /* load new stack pointer */ - - movl 0(%esp),%eax - movl 4(%esp),%ecx - movl 8(%esp),%edx - movl 12(%esp),%ebx - /* skip stack pointer */ - movl 20(%esp),%ebp - movl 24(%esp),%esi - movl 28(%esp),%edi - - addl $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 ************************* @@ -1034,152 +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 */ + mov 12(%esp),%eax /* third argument **stacktopsave */ + mov %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 */ - - 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 - - -/********************* function asm_getcallingmethod *************************** -* * -* classinfo *asm_getcallingmethod (); * -* * -* goes back stack frames to get the calling method * -* * -* t2 .. sp * -* t3 .. ra * -* t4 .. pv * -* * -*******************************************************************************/ - -asm_getcallingmethod: - xorl %eax,%eax -/* movl $0,(%eax) */ - ret - - -/*********************** function asm_builtin_trace **************************** -* * -* Intended to be called from the native stub. Saves all argument registers * -* and calls builtin_trace_args. * -* * -*******************************************************************************/ - -asm_builtin_trace: - pusha - subl $68,%esp /* 4 + 8 * 4 + 68 = 104 */ - - movl 104(%esp),%eax - movl 108(%esp),%edx - movl %eax,(%esp) - movl %edx,4(%esp) - - movl 112(%esp),%eax - movl 116(%esp),%edx - movl %eax,8(%esp) - movl %edx,12(%esp) - - movl 120(%esp),%eax - movl 124(%esp),%edx - movl %eax,16(%esp) - movl %edx,20(%esp) - - movl 128(%esp),%eax - movl 132(%esp),%edx - movl %eax,24(%esp) - movl %edx,28(%esp) - - movl 136(%esp),%eax - movl 140(%esp),%edx - movl %eax,32(%esp) - movl %edx,36(%esp) - - movl 144(%esp),%eax - movl 148(%esp),%edx - movl %eax,40(%esp) - movl %edx,44(%esp) - - movl 152(%esp),%eax - movl 156(%esp),%edx - movl %eax,48(%esp) - movl %edx,52(%esp) - - movl 160(%esp),%eax - movl 164(%esp),%edx - movl %eax,56(%esp) - movl %edx,60(%esp) - - movl 168(%esp),%eax - movl %eax,64(%esp) - - call builtin_trace_args - addl $68,%esp - - popa - ret - - -/********************* function asm_builtin_exittrace ************************** -* * -* Intended to be called from the native stub. Saves return value and calls * -* builtin_displaymethodstop. * -* * -*******************************************************************************/ - -asm_builtin_exittrace: - pusha - subl $24,%esp - - movl 60(%esp),%eax /* 4 + 8 * 4 + 24 = 60 */ - movl %eax,(%esp) - - movl 64(%esp),%eax - movl 68(%esp),%edx - movl %eax,4(%esp) - movl %edx,8(%esp) - - movl 72(%esp),%eax - movl 76(%esp),%edx - movl %eax,12(%esp) - movl %edx,16(%esp) + mov 8(%esp),%eax /* load function pointer */ + mov 16(%esp),%ecx /* fourth argument *p */ + + mov %edx,%esp /* switch to new stack */ + + 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_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_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 - movl 80(%esp),%eax - movl %eax,20(%esp) - call builtin_displaymethodstop - addl $24,%esp +/* Disable exec-stacks, required for Gentoo ***********************************/ - popa - ret +#if defined(__GCC__) && defined(__ELF__) + .section .note.GNU-stack,"",@progbits +#endif -asm_xadd: - mov 4(%esp),%ecx - mov 8(%esp),%eax - lock - xaddl %eax,0(%ecx) - incl %eax - ret /* * These are local overrides for various environment variables in Emacs. @@ -1192,4 +833,5 @@ asm_xadd: * c-basic-offset: 4 * tab-width: 4 * End: + * vim:noexpandtab:sw=4:ts=4: */