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