* src/vm/jit/i386/asmpart.S (asm_call_jit_compiler): Removed.
* src/vm/jit/i386/codegen.c (codegen_emit_stub_compiler): Likewise.
* src/vm/jit/i386/codegen.h (COMPILERSTUB_CODESIZE): Adapted size.
(M_BYTE1, M_BYTE2): New macros.
(M_CLTD, M_RET, M_NOP): Use M_BYTE1.
(M_UD2): Use M_BYTE2.
* src/vm/jit/i386/emit.c (emit_trap_compiler): New function.
(emit_trap): Use macros.
(emit_cltd, emit_ret, emit_nop): Removed.
* src/vm/jit/i386/emit.h (emit_cltd, emit_ret, emit_nop): Likewise.
* src/vm/jit/i386/linux/md-os.c (md_signal_handler_sigsegv): Added JIT
compiler code.
#ifndef _ARCH_H
#define _ARCH_H
+#define JIT_COMPILER_VIA_SIGNAL
+
#include "config.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
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 *
if (cd->stackframesize)
M_AADD_IMM(cd->stackframesize * 8, REG_SP);
- emit_ret(cd);
+ M_RET;
}
break;
}
-/* codegen_emit_stub_compiler **************************************************
-
- Emit a stub routine which calls the compiler.
-
-*******************************************************************************/
-
-void codegen_emit_stub_compiler(jitdata *jd)
-{
- methodinfo *m;
- codegendata *cd;
-
- /* get required compiler data */
-
- m = jd->m;
- cd = jd->cd;
-
- /* code for the stub */
-
- M_MOV_IMM(m, REG_ITMP1);
- M_MOV_IMM(asm_call_jit_compiler, REG_ITMP3);
- M_JMP(REG_ITMP3);
-}
-
-
/* codegen_emit_stub_native ****************************************************
Emits a stub routine which calls a native method.
/* stub defines ***************************************************************/
-#define COMPILERSTUB_CODESIZE 12
+#define COMPILERSTUB_CODESIZE 6
/* macros to create code ******************************************************/
+#define M_BYTE1(a) \
+ do { \
+ *(cd->mcodeptr) = (a); \
+ cd->mcodeptr++; \
+ } while (0)
+
+
+#define M_BYTE2(a, b) \
+ do { \
+ M_BYTE1(a); \
+ M_BYTE1(b); \
+ } while (0)
+
+
#define M_ILD(a,b,disp) emit_mov_membase_reg(cd, (b), (disp), (a))
#define M_ILD32(a,b,disp) emit_mov_membase32_reg(cd, (b), (disp), (a))
#define M_CZEXT(a,b) emit_movzwl_reg_reg(cd, (a), (b))
-#define M_CLTD emit_cltd(cd)
+#define M_CLTD M_BYTE1(0x99)
#define M_SLL(a) emit_shift_reg(cd, SHIFT_SHL, (a))
#define M_SRA(a) emit_shift_reg(cd, SHIFT_SAR, (a))
#define M_CALL(a) emit_call_reg(cd, (a))
#define M_CALL_IMM(a) emit_call_imm(cd, (a))
-#define M_RET emit_ret(cd)
+#define M_RET M_BYTE1(0xc3)
#define M_BEQ(a) emit_jcc(cd, CC_E, (a))
#define M_BNE(a) emit_jcc(cd, CC_NE, (a))
#define M_JMP(a) emit_jmp_reg(cd, (a))
#define M_JMP_IMM(a) emit_jmp_imm(cd, (a))
-#define M_NOP emit_nop(cd)
+#define M_NOP M_BYTE1(0x90)
+#define M_UD2 M_BYTE2(0x0f, 0x0b)
#define M_FLD(a,b,disp) emit_flds_membase(cd, (b), (disp))
}
+/* emit_trap_compiler **********************************************************
+
+ Emit a trap instruction which calls the JIT compiler.
+
+*******************************************************************************/
+
+void emit_trap_compiler(codegendata *cd)
+{
+ M_ALD_MEM(REG_METHODPTR, EXCEPTION_HARDWARE_COMPILER);
+}
+
+
/* emit_trap *******************************************************************
Emit a trap instruction and return the original machine code.
#if 0
/* XXX this breaks GDB, so we disable it for now */
*(cd->mcodeptr++) = 0xcc;
+ M_INT3;
#else
- *(cd->mcodeptr++) = 0x0f;
- *(cd->mcodeptr++) = 0x0b;
+ M_UD2;
#endif
return (uint32_t) mcode;
}
-void emit_cltd(codegendata *cd)
-{
- *(cd->mcodeptr++) = 0x99;
-}
-
-
void emit_imul_reg_reg(codegendata *cd, s4 reg, s4 dreg)
{
*(cd->mcodeptr++) = 0x0f;
}
-void emit_ret(codegendata *cd)
-{
- *(cd->mcodeptr++) = 0xc3;
-}
-
-
/*
* shift ops
}
-void emit_nop(codegendata *cd)
-{
- *(cd->mcodeptr++) = 0x90;
-}
-
-
void emit_lock(codegendata *cd)
{
*(cd->mcodeptr++) = 0xf0;
void emit_test_reg_reg(codegendata *cd, s4 reg, s4 dreg);
void emit_test_imm_reg(codegendata *cd, s4 imm, s4 dreg);
void emit_dec_mem(codegendata *cd, s4 mem);
-void emit_cltd(codegendata *cd);
void emit_imul_reg_reg(codegendata *cd, s4 reg, s4 dreg);
void emit_imul_membase_reg(codegendata *cd, s4 basereg, s4 disp, s4 dreg);
void emit_imul_imm_reg(codegendata *cd, s4 imm, s4 reg);
void emit_imul_imm_membase_reg(codegendata *cd, s4 imm, s4 basereg, s4 disp, s4 dreg);
void emit_mul_reg(codegendata *cd, s4 reg);
void emit_idiv_reg(codegendata *cd, s4 reg);
-void emit_ret(codegendata *cd);
void emit_shift_reg(codegendata *cd, s4 opc, s4 reg);
void emit_shift_imm_reg(codegendata *cd, s4 opc, s4 imm, s4 reg);
void emit_shld_reg_reg(codegendata *cd, s4 reg, s4 dreg);
void emit_push_imm(codegendata *cd, s4 imm);
void emit_pop_reg(codegendata *cd, s4 reg);
void emit_push_reg(codegendata *cd, s4 reg);
-void emit_nop(codegendata *cd);
void emit_lock(codegendata *cd);
void emit_call_reg(codegendata *cd, s4 reg);
void emit_call_imm(codegendata *cd, s4 imm);
ptrint val;
s4 type;
void *p;
+ java_object_t *o;
_uc = (ucontext_t *) _p;
_mc = &_uc->uc_mcontext;
here. */
val = _mc->gregs[REG_EAX - d];
+
+ if (type == EXCEPTION_HARDWARE_COMPILER) {
+ /* We use a framesize of zero here because the call pushed
+ the return addres onto the stack. */
+
+ ra = md_stacktrace_get_returnaddress(sp, 0);
+
+ /* And remove the RA from the stack. */
+
+ sp = sp + 1 * SIZEOF_VOID_P;
+ }
}
else {
/* this was a normal NPE */
p = signal_handle(type, val, pv, sp, ra, xpc, _p);
- /* set registers */
+ /* Set registers. */
- _mc->gregs[REG_EAX] = (intptr_t) p;
- _mc->gregs[REG_ECX] = (intptr_t) xpc; /* REG_ITMP2_XPC */
- _mc->gregs[REG_EIP] = (intptr_t) asm_handle_exception;
+ if (type == EXCEPTION_HARDWARE_COMPILER) {
+ if (p == NULL) {
+ o = exceptions_get_and_clear_exception();
+
+ ra = ra - 2; /* XPC is before the actual call */
+
+ _mc->gregs[REG_ESP] = (uintptr_t) sp; /* Remove RA from stack. */
+
+ _mc->gregs[REG_EAX] = (uintptr_t) o;
+ _mc->gregs[REG_ECX] = (uintptr_t) ra; /* REG_ITMP2_XPC */
+ _mc->gregs[REG_EIP] = (uintptr_t) asm_handle_exception;
+ }
+ else {
+ _mc->gregs[REG_EIP] = (uintptr_t) p;
+ }
+ }
+ else {
+ _mc->gregs[REG_EAX] = (intptr_t) p;
+ _mc->gregs[REG_ECX] = (intptr_t) xpc; /* REG_ITMP2_XPC */
+ _mc->gregs[REG_EIP] = (intptr_t) asm_handle_exception;
+ }
}