/* prepare data structures for native function call */
- M_LDA(REG_A0, REG_SP, cd->stackframesize * 8 - SIZEOF_VOID_P);
+ M_MOV(REG_SP, REG_A0);
M_MOV(REG_PV, REG_A1);
- M_LDA(REG_A2, REG_SP, cd->stackframesize * 8);
- M_ALD(REG_A3, REG_SP, cd->stackframesize * 8 - SIZEOF_VOID_P);
disp = dseg_add_functionptr(cd, codegen_start_native_call);
M_ALD(REG_PV, REG_PV, disp);
M_JSR(REG_RA, REG_PV);
/* create native stackframe info */
- assert(IS_IMM(4*4 + cd->stackframesize));
- M_ADD_IMM(REG_A0, REG_SP, 4*4 + cd->stackframesize - SIZEOF_VOID_P);
+ M_ADD_IMM(REG_A0, REG_SP, 4*4);
M_MOV(REG_A1, REG_PV);
- M_ADD_IMM(REG_A2, REG_SP, 4*4 + cd->stackframesize);
- M_LDR_INTERN(REG_A3, REG_SP, 4*4 + cd->stackframesize - SIZEOF_VOID_P);
disp = dseg_add_functionptr(cd, codegen_start_native_call);
M_DSEG_BRANCH(disp);
# include "codegen.h"
#endif
+#include "md-abi.h"
+
#include "mm/memory.h"
#include "toolbox/avl.h"
#include "vm/jit/emit-common.h"
#include "vm/jit/jit.h"
#include "vm/jit/md.h"
+#include "vm/jit/methodheader.h"
#include "vm/jit/patcher-common.h"
#include "vm/jit/replace.h"
#if defined(ENABLE_SSA)
# include "vm/jit/optimizing/ssa.h"
#endif
#include "vm/jit/stacktrace.h"
+#include "vm/jit/trace.h"
#if defined(ENABLE_INTRP)
#include "vm/jit/intrp/intrp.h"
The layout of the native stub stackframe should look like this:
- +---------------------------+ <- SP (of parent Java function)
+ +---------------------------+ <- java SP (of parent Java function)
| return address |
- +---------------------------+
+ +---------------------------+ <- data SP
| |
| stackframe info structure |
| |
| |
+---------------------------+
| |
+ | saved registers (if any) |
+ | |
+ +---------------------------+
+ | |
| arguments (if any) |
| |
- +---------------------------+ <- SP (native stub)
+ +---------------------------+ <- current SP (native stub)
*******************************************************************************/
-void codegen_start_native_call(u1 *datasp, u1 *pv, u1 *sp, u1 *ra)
+void codegen_start_native_call(u1 *currentsp, u1 *pv)
{
stackframeinfo *sfi;
localref_table *lrt;
+ codeinfo *code;
+ methodinfo *m;
+ int32_t framesize;
+
+ uint8_t *datasp;
+ uint8_t *javasp;
+ uint8_t *javara;
+#if !defined(NDEBUG)
+ uint64_t *args_regs;
+ uint64_t *args_stack;
+#endif
STATISTICS(count_calls_java_to_native++);
+ /* get information from method header */
+
+ code = *((codeinfo **) (pv + CodeinfoPointer));
+ framesize = *((int32_t *) (pv + FrameSize));
+
+ assert(code);
+ assert(framesize > sizeof(stackframeinfo) + sizeof(localref_table));
+
+ /* get the methodinfo */
+
+ m = code->m;
+
+ assert(m);
+
+ /* calculate needed values */
+
+#if defined(__ALPHA__) || defined(__ARM__)
+ datasp = currentsp + framesize - SIZEOF_VOID_P;
+ javasp = currentsp + framesize;
+ javara = *((uint8_t **) datasp);
+#elif defined(__MIPS__) || defined(__S390__)
+ /* MIPS and S390 always uses 8 bytes to store the RA */
+ datasp = currentsp + framesize - 8;
+ javasp = currentsp + framesize;
+ javara = *((uint8_t **) datasp);
+#elif defined(__I386__) || defined (__M68K__) || defined (__X86_64__)
+ datasp = currentsp + framesize;
+ javasp = currentsp + framesize + SIZEOF_VOID_P;
+ javara = *((uint8_t **) datasp);
+#elif defined(__POWERPC__) || defined(__POWERPC64__)
+ datasp = currentsp + framesize;
+ javasp = currentsp + framesize;
+ javara = *((uint8_t **) (datasp + LA_LR_OFFSET));
+#else
+ /* XXX is was unable to do this port for SPARC64, sorry. (-michi) */
+ /* XXX maybe we need to pass the RA as argument there */
+ vm_abort("codegen_start_native_call: unsupported architecture");
+#endif
+
+#if 0
+ printf("NATIVE (framesize=%d): ", framesize);
+ method_print(m);
+ printf("\n");
+ fflush(stdout);
+#endif
+
+#if 0 && !defined(NDEBUG)
+ if (opt_TraceJavaCalls) {
+ args_regs = currentsp;
+ args_stack = javasp;
+ trace_java_call_enter(m, args_regs, args_stack);
+ }
+#endif
+
/* get data structures from stack */
sfi = (stackframeinfo *) (datasp - sizeof(stackframeinfo));
lrt = (localref_table *) (datasp - sizeof(stackframeinfo) -
sizeof(localref_table));
- /* add a stackframeinfo to the chain */
-
- stacktrace_create_native_stackframeinfo(sfi, pv, sp, ra);
-
#if defined(ENABLE_JNI)
/* add current JNI local references table to this thread */
localref_table_add(lrt);
#endif
+
+ /* XXX add references to lrt here!!! */
+
+ /* add a stackframeinfo to the chain */
+
+ stacktrace_create_native_stackframeinfo(sfi, pv, javasp, javara);
}
void codegen_stub_builtin_enter(u1 *datasp, u1 *pv, u1 *sp, u1 *ra);
void codegen_stub_builtin_exit(u1 *datasp);
-void codegen_start_native_call(u1 *datasp, u1 *pv, u1 *sp, u1 *ra);
+void codegen_start_native_call(u1 *currentsp, u1 *pv);
java_object_t *codegen_finish_native_call(u1 *datasp);
s4 codegen_reg_of_var(u2 opcode, varinfo *v, s4 tempregnum);
/* prepare data structures for native function call */
M_MOV(REG_SP, REG_ITMP1);
- M_AADD_IMM(cd->stackframesize * 8, REG_ITMP1);
-
M_AST(REG_ITMP1, REG_SP, 0 * 4);
M_IST_IMM(0, REG_SP, 1 * 4);
dseg_adddata(cd);
- M_MOV(REG_SP, REG_ITMP2);
- M_AADD_IMM(cd->stackframesize * 8 + SIZEOF_VOID_P, REG_ITMP2);
-
- M_AST(REG_ITMP2, REG_SP, 2 * 4);
- M_ALD(REG_ITMP3, REG_SP, cd->stackframesize * 8);
- M_AST(REG_ITMP3, REG_SP, 3 * 4);
M_MOV_IMM(codegen_start_native_call, REG_ITMP1);
M_CALL(REG_ITMP1);
/* void codegen_start_native_call(u1 *datasp, u1 *pv, u1 *sp, u1 *ra) */
M_AMOV(REG_SP, REG_ATMP1);
- M_AADD_IMM(cd->stackframesize * 4, REG_ATMP1);
-
- M_ALD(REG_ATMP3, REG_ATMP1, 0 * 4);
- M_AST(REG_ATMP3, REG_SP, 3 * 4); /* ra */
-
- M_AST(REG_ATMP1, REG_SP, 0 * 4); /* datasp */
-
- M_AADD_IMM(1 * 4 , REG_ATMP1);
- M_AST(REG_ATMP1, REG_SP, 2 * 4); /* sp */
+ M_AST(REG_ATMP1, REG_SP, 0 * 4); /* currentsp */
M_AMOV_IMM(0, REG_ATMP2); /* 0 needs to patched */
dseg_adddata(cd); /* this patches it */
/* prepare data structures for native function call */
- M_AADD_IMM(REG_SP, (cd->stackframesize - 1) * 8, REG_A0);
+ M_MOV(REG_SP, REG_A0);
M_MOV(REG_PV, REG_A1);
- M_AADD_IMM(REG_SP, cd->stackframesize * 8, REG_A2);
- M_ALD(REG_A3, REG_SP, (cd->stackframesize - 1) * 8);
disp = dseg_add_functionptr(cd, codegen_start_native_call);
M_ALD(REG_ITMP3, REG_PV, disp);
M_JSR(REG_RA, REG_ITMP3);
/* create native stack info */
- M_AADD_IMM(REG_SP, cd->stackframesize * 8, REG_A0);
+ M_MOV(REG_SP, REG_A0);
M_MOV(REG_PV, REG_A1);
- M_AADD_IMM(REG_SP, cd->stackframesize * 8, REG_A2);
- M_ALD(REG_A3, REG_SP, cd->stackframesize * 8 + LA_LR_OFFSET);
disp = dseg_add_functionptr(cd, codegen_start_native_call);
M_ALD(REG_ITMP1, REG_PV, disp);
M_MTCTR(REG_ITMP1);
/* create native stack info */
- M_AADD_IMM(REG_SP, cd->stackframesize * 8, REG_A0);
+ M_MOV(REG_SP, REG_A0);
M_MOV(REG_PV, REG_A1);
- M_AADD_IMM(REG_SP, cd->stackframesize * 8, REG_A2);
- M_ALD(REG_A3, REG_SP, cd->stackframesize * 8 + LA_LR_OFFSET);
disp = dseg_add_functionptr(cd, codegen_start_native_call);
M_ALD(REG_ITMP1, REG_PV, disp);
/* create dynamic stack info */
- N_LAE(REG_A0, (cd->stackframesize - 1) * 8 , RN, REG_SP); /* datasp */
+ N_MOV(REG_SP, REG_A0); /* currentsp */
N_LA(REG_A1, -N_PV_OFFSET, RN, REG_PV); /* pv */
- N_LAE(REG_A2, cd->stackframesize * 8, RN, REG_SP); /* old SP */
- N_L(REG_A3, (cd->stackframesize - 1) * 8, RN, REG_SP); /* return address */
disp = dseg_add_functionptr(cd, codegen_start_native_call);
M_ILD_DSEG(REG_ITMP1, disp);
/* create dynamic stack info */
- M_ALEA(REG_SP, cd->stackframesize * 8, REG_A0);
+ M_MOV(REG_SP, REG_A0);
emit_lea_membase_reg(cd, RIP, -((cd->mcodeptr + 7) - cd->mcodebase), REG_A1);
- M_ALEA(REG_SP, cd->stackframesize * 8 + SIZEOF_VOID_P, REG_A2);
- M_ALD(REG_A3, REG_SP, cd->stackframesize * 8);
M_MOV_IMM(codegen_start_native_call, REG_ITMP1);
M_CALL(REG_ITMP1);