/* src/vm/jit/i386/asmpart.S - Java-C interface functions for i386
- Copyright (C) 1996-2005, 2006, 2007 R. Grafl, A. Krall, C. Kruegel,
- C. Oates, R. Obermaisser, M. Platter, M. Probst, S. Ring,
- E. Steiner, C. Thalinger, D. Thuernbeck, P. Tomsich, C. Ullrich,
- J. Wenninger, Institut f. Computersprachen - TU Wien
+ Copyright (C) 1996-2005, 2006, 2007, 2008
+ CACAOVM - Verein zur Foerderung der freien virtuellen Maschine CACAO
This file is part of CACAO.
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301, USA.
- $Id: asmpart.S 7601 2007-03-28 23:02:50Z michi $
-
*/
#include "vm/jit/i386/arch.h"
#include "vm/jit/i386/md-abi.h"
-#include "vm/jit/i386/offsets.h"
#include "vm/jit/abi-asm.h"
#include "vm/jit/methodheader.h"
.globl asm_vm_call_method_exception_handler
.globl asm_vm_call_method_end
- .globl asm_call_jit_compiler
.globl asm_handle_nat_exception
.globl asm_handle_exception
.globl asm_abstractmethoderror
- .globl asm_patcher_wrapper
-
-#if defined(ENABLE_REPLACEMENT)
- .globl asm_replacement_out
- .globl asm_replacement_in
-#endif
-
.globl asm_builtin_f2i
.globl asm_builtin_f2l
.globl asm_builtin_d2i
.globl asm_compare_and_swap
.globl asm_memory_barrier
- .globl asm_criticalsections
- .globl asm_getclassvalues_atomic
-
- .globl asm_get_cycle_count
+#if defined(ENABLE_ESCAPE_CHECK)
+ .globl asm_escape_check
+#endif
/* asm_md_init *****************************************************************
.align 8
- .long 0 /* catch type all */
- .long 0 /* handler pc */
- .long 0 /* end pc */
- .long 0 /* start pc */
- .long 1 /* extable size */
- .long 0 /* line number table start */
- .long 0 /* line number table size */
.long 0 /* fltsave */
.long 0 /* intsave */
.long 0 /* isleaf */
- .long 0 /* IsSync */
.long 0 /* frame size */
.long 0 /* codeinfo pointer */
asm_vm_call_method_float:
asm_vm_call_method_double:
push bp
- mov sp,bp /* save stackptr */
+ mov sp,bp /* save stack pointer */
sub $(4*4),sp /* create stackframe */
and $0xfffffff0,sp /* align stack to 16-byte */
mov s1,1*4(sp)
mov s2,2*4(sp)
- mov 4*4(bp),itmp1 /* pointer to arg block (4(push)+4(return)+4+4)*/
- mov 3*4(bp),itmp2 /* arg count (4(push)+4(return)+4 */
-
- mov sp,s1 /* save the stackpointer */
-
- test itmp2,itmp2 /* maybe we have no args */
- jle L_asm_vm_call_method_copy_done
-
- mov itmp2,itmp3 /* calculate stack size */
- mov itmp1,%edi /* save pointer to arg block */
-
-calljava_calcstacksize:
- mov offvmargtype(itmp1),t0
- test $1,t0 /* two word type? */
- jz calljava_onewordtype
-
- sub $4,sp /* add 1 slot to stackframe size */
-
-calljava_onewordtype:
- sub $4,sp /* add 1 slot to stackframe size */
- sub $1,itmp3
- test itmp3,itmp3 /* any args left? */
- jz calljava_setstack
+ mov sp,s1 /* save stack pointer */
- add $sizevmarg,itmp1 /* goto next argument block */
- jmp calljava_calcstacksize
-
-calljava_setstack:
- mov %edi,itmp1 /* restore pointer to arg block */
- and $0xfffffff0,sp /* align stack to 16-byte */
- mov sp,itmp3 /* initialize pointer for copying */
-
-calljava_copyloop:
- mov offvmargdata(itmp1),t0 /* get 4-bytes of argument */
- mov t0,(itmp3) /* and store them on the stack */
- add $4,itmp3 /* increase sp to next argument */
+ mov 3*4(bp),t0 /* address of data structure */
+ mov 4*4(bp),itmp1 /* number of stack arguments */
- mov offvmargtype(itmp1),t0 /* get the argument type */
- test $1,t0 /* two word type? */
- jz calljava_copynext
+ cmp $0,itmp1
+ je L_asm_vm_call_method_stack_copy_done
- mov offvmargdata+4(itmp1),t0 /* get upper 4-bytes of 2 word type */
- mov t0,(itmp3)
- add $4,itmp3 /* increase sp to next argument */
+ mov itmp1,itmp2
+ add $1,itmp2 /* keep stack 16-byte aligned */
+ and $0xfffffffe,itmp2
+ shl $3,itmp2 /* calculate stack size */
+ sub itmp2,sp /* create stack frame */
+ mov sp,itmp2 /* temporary stack pointer */
-calljava_copynext:
- sub $1,itmp2 /* are there any args left? */
- test itmp2,itmp2
- jle L_asm_vm_call_method_copy_done
+L_asm_vm_call_method_stack_copy_loop:
+ mov 0(t0),itmp3 /* load argument */
+ mov itmp3,0(itmp2) /* store argument on stack */
+ mov 4(t0),itmp3
+ mov itmp3,4(itmp2)
- add $sizevmarg,itmp1 /* goto next argument block */
- jmp calljava_copyloop
+ sub $1,itmp1 /* subtract 1 argument */
+ add $8,t0 /* set address of next argument */
+ add $8,itmp2 /* increase SP */
-L_asm_vm_call_method_copy_done:
- mov 2*4(bp),itmp1 /* move function pointer to itmp1 */
+ cmp $0,itmp1
+ jg L_asm_vm_call_method_stack_copy_loop
- lea L_asm_call_jit_compiler,mptr
- mov mptr,3*4(s1)
- lea (3*4-256)(s1),mptr /* We subtract 256 to force the next */
+L_asm_vm_call_method_stack_copy_done:
+ lea (2*4-256)(bp),mptr /* We subtract 256 to force the next */
/* move instruction to have a 32-bit */
/* offset. */
jmp L_asm_vm_call_method_return
-/* asm_call_jit_compiler *******************************************************
-
- Invokes the compiler for untranslated JavaVM methods.
-
- Register R0 contains a pointer to the method info structure (prepared
- by createcompilerstub). Using the return address in R26 and the
- offset in the LDA instruction or using the value in methodptr R28 the
- patching address for storing the method address can be computed:
-
- Method address was either loaded using
-
- i386_mov_imm_reg(a, REG_ITMP2) ; invokestatic/special
- i386_call_reg(REG_ITMP2)
-
- or
-
- i386_mov_membase_reg(REG_SP, 0, REG_ITMP1) ; invokevirtual/interface
- i386_mov_membase_reg(REG_ITMP1, OFFSET(, vftbl), REG_ITMP2)
- i386_mov_membase_reg(REG_ITMP2, OFFSET(vftbl, table[0]) + \
- sizeof(methodptr) * m->vftblindex, REG_ITMP1)
- i386_call_reg(REG_ITMP1)
-
- In the static case the method pointer can be computed using the
- return address and the lda function following the jmp instruction.
-
-*******************************************************************************/
-
-asm_call_jit_compiler:
-L_asm_call_jit_compiler: /* required for PIC code */
- sub $(4*4),sp /* keep stack 16-byte aligned */
-
- mov itmp1,0*4(sp) /* pass methodinfo pointer */
- mov mptr,1*4(sp) /* pass method pointer */
- mov sp,itmp2 /* pass java sp */
- add $((1+4)*4),itmp2
- mov itmp2,2*4(sp)
- mov 4*4(sp),itmp3 /* pass java ra */
- mov itmp3,3*4(sp)
- call jit_asm_compile
-
- add $(4*4),sp /* remove stack frame */
-
- test v0,v0 /* check for exception */
- je L_asm_call_jit_compiler_exception
-
- jmp *v0 /* ...and now call the new method */
-
-L_asm_call_jit_compiler_exception:
- call exceptions_get_and_clear_exception
- /* v0 == xptr */
- pop xpc /* get return address */
- sub $2,xpc /* faulting address is ra - 2 */
- jmp L_asm_handle_exception
-
-
/* asm_handle_exception ********************************************************
* *
* This function handles an exception. It does not use the usual calling *
mov t0,8*4(sp) /* save maybe-leaf flag */
mov xpc,0*4(sp) /* pass exception pc */
- call codegen_get_pv_from_pc
+ call methodtree_find
mov v0,6*4(sp) /* save data segment pointer */
mov 4*4(sp),itmp3 /* pass exception pointer */
cmp $2,itmp1
je int2
- mov -3*4(itmp2),s0
+ mov -4-3*8(itmp2),s0
int2:
- mov -2*4(itmp2),s1
+ mov -4-2*8(itmp2),s1
int1:
- mov -1*4(itmp2),s2
+ mov -4-1*8(itmp2),s2
shl $2,itmp1 /* multiply by 4 bytes */
sub itmp1,itmp2
jmp L_asm_handle_exception
-/* asm_patcher_wrapper *********************************************************
-
- XXX
-
- Stack layout:
- 24 return address
- 20 REG_ITMP3
- 16 pointer to virtual java_objectheader
- 12 last byte of machine code (xmcode)
- 8 machine code (which is patched back later)
- 4 unresolved field reference
- 0 patcher function pointer to call
-
-*******************************************************************************/
-
-asm_patcher_wrapper:
- sub $((1+4+4)*4),sp /* keep stack 16-byte aligned */
-
- mov itmp1,(0+4)*4(sp) /* save itmp1 and itmp2 */
- mov itmp2,(1+4)*4(sp)
-
- mov sp,itmp1 /* pass SP of patcher stub */
- add $((1+4+4)*4),itmp1
- mov itmp1,0*4(sp)
- movl $0,1*4(sp) /* pass PV (if NULL, use findmethod) */
- movl $0,2*4(sp) /* pass RA (it's on the stack) */
- call patcher_wrapper
- mov v0,itmp3 /* save return value */
-
- mov (0+4)*4(sp),itmp1 /* restore itmp1 and itmp2 */
- mov (1+4)*4(sp),itmp2
-
- test itmp3,itmp3 /* exception thrown? */
- jne L_asm_patcher_wrapper_exception
-
- mov (5+1+4+4)*4(sp),itmp3 /* restore itmp3 */
- add $((6+1+4+4)*4),sp /* remove stack frame, keep RA */
-
- ret /* jump to new patched code */
-
-L_asm_patcher_wrapper_exception:
- add $((6+1+4+4)*4),sp /* remove stack frame, keep RA */
- mov itmp3,xptr /* get exception */
- pop xpc /* get and remove return address */
- jmp L_asm_handle_exception
-
-#if defined(ENABLE_REPLACEMENT)
-
-/* 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*4+offes_intregs)(sp)
- mov %ebx,(EBX*4+offes_intregs)(sp)
- mov %ecx,(ECX*4+offes_intregs)(sp)
- mov %edx,(EDX*4+offes_intregs)(sp)
- mov %esi,(ESI*4+offes_intregs)(sp)
- mov %edi,(EDI*4+offes_intregs)(sp)
- mov %ebp,(EBP*4+offes_intregs)(sp)
- movl $0 ,(ESP*4+offes_intregs)(sp) /* not used */
-
- /* calculate sp of method */
- mov sp,itmp1
- add $(sizeexecutionstate + REPLACEMENT_ROOM + 4),itmp1
- mov itmp1,(offes_sp)(sp)
-
- /* pv must be looked up via AVL tree */
- movl $0,(offes_pv)(sp)
-
- /* call replace_me */
- mov -4(itmp1),itmp1 /* rplpoint * */
- push sp /* arg1: execution state */
- push itmp1 /* arg0: replacement point */
- call replace_me /* call C function replace_me */
-
-
-/* asm_replacement_in **********************************************************
-
- This code writes the given execution state and jumps to the replacement
- code.
-
- This function never returns!
-
- C prototype:
- void asm_replacement_in(executionstate *es, replace_safestack_t *st);
-
-*******************************************************************************/
-
-asm_replacement_in:
- /* get arguments */
- mov 8(sp),%esi /* replace_safestack_t *st */
- mov 4(sp),%ebp /* executionstate *es == safe stack */
-
- /* switch to the safe stack and build a stack frame */
- mov %ebp,sp
- sub $(1*4),sp
-
- /* call replace_build_execution_state(st) */
- mov %esi,(0*4)(sp)
- call replace_build_execution_state
-
- /* set new sp */
- mov (offes_sp)(%ebp),sp
-
- /* push address of new code */
- push (offes_pc)(%ebp)
-
- /* allocate an executionstate_t on the stack */
- sub $(sizeexecutionstate),sp
-
- /* call replace_free_safestack(st,& of allocated executionstate_t) */
- push sp /* tmpes */
- push %esi /* st */
- call replace_free_safestack
- add $(2*4),sp
-
- /* copy registers from execution state */
- mov (EAX*4+offes_intregs)(sp),%eax
- mov (EBX*4+offes_intregs)(sp),%ebx
- mov (ECX*4+offes_intregs)(sp),%ecx
- mov (EDX*4+offes_intregs)(sp),%edx
- mov (ESI*4+offes_intregs)(sp),%esi
- mov (EDI*4+offes_intregs)(sp),%edi
- mov (EBP*4+offes_intregs)(sp),%ebp
-
- /* pop the execution state off the stack */
- add $(sizeexecutionstate),sp
-
- /* jump to new code, hold your thumbs! ;) */
- ret
-
-#endif /* defined(ENABLE_REPLACEMENT) */
-
-
/************************ function asm_builtin_x2x *****************************
* *
* Wrapper functions for corner cases *
lock; add $0,0(sp)
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
+#if defined(ENABLE_ESCAPE_CHECK)
+asm_escape_check:
+ sub $24,%esp
-asm_criticalsections:
-#if defined(ENABLE_THREADS)
-#if 0
- .long _crit_begin1
- .long _crit_end1
- .long _crit_restart1
-#endif
- .long _crit_begin2
- .long _crit_end2
- .long _crit_restart2
-#endif
- .long 0
+ mov t0, 4(%esp)
+ mov itmp1, 8(%esp)
+ mov itmp2, 12(%esp)
+ mov itmp3, 16(%esp)
+ mov 28(%esp), itmp1
+ mov itmp1, (%esp)
-/* Disable exec-stacks, required for Gentoo ***********************************/
-
-#if defined(__GCC__) && defined(__ELF__)
- .section .note.GNU-stack,"",@progbits
-#endif
-
+ call escape_analysis_escape_check
-/* asm_get_cycle_count *********************************************************
+ mov 4(%esp), t0
+ mov 8(%esp), itmp1
+ mov 12(%esp), itmp2
+ mov 16(%esp), itmp3
- Get the current time-stamp counter from the CPU.
+ add $24,sp
+ ret
+#endif
-*******************************************************************************/
-asm_get_cycle_count:
- rdtsc
- ret
+/* disable exec-stacks ********************************************************/
+#if defined(__linux__) && defined(__ELF__)
+ .section .note.GNU-stack,"",%progbits
+#endif
/*
* These are local overrides for various environment variables in Emacs.