(builtin_fast_canstore): Do not throw any exceptions.
* src/vm/builtin.h (BUILTIN_canstore): Removed.
* src/vm/builtintable.inc: Adapted entry for builtin_canstore.
* src/vm/exceptions.h (EXCEPTION_HARDWARE_ARRAYSTORE): Added.
* src/vm/signal.c (signal_handle): Added case for ArrayStoreException.
* src/vm/jit/emit-common.h (emit_arraystore_check): Added prototype.
* src/vm/jit/stack.c (stack_analyse): ICMD_AASTORE now uses fast canstore.
* src/vm/jit/alpha/codegen.c (codegen_emit): ICMD_AASTORE uses fast canstore.
* src/vm/jit/alpha/emit.c (emit_arraystore_check): Implemented.
* src/vm/jit/arm/codegen.c: Likewise.
* src/vm/jit/arm/emit.c: Likewise.
* src/vm/jit/i386/codegen.c: Likewise.
* src/vm/jit/i386/emit.c: Likewise.
* src/vm/jit/m68k/codegen.c: Likewise.
* src/vm/jit/m68k/emit.c: Likewise.
* src/vm/jit/mips/codegen.c: Likewise.
* src/vm/jit/mips/emit.c: Likewise.
* src/vm/jit/powerpc/codegen.c: Likewise.
* src/vm/jit/powerpc/emit.c: Likewise.
* src/vm/jit/powerpc64/codegen.c: Likewise.
* src/vm/jit/powerpc64/emit.c: Likewise.
* src/vm/jit/s390/codegen.c: Likewise.
* src/vm/jit/s390/emit.c: Likewise.
* src/vm/jit/sparc64/codegen.c: Likewise.
* src/vm/jit/sparc64/emit.c: Likewise.
* src/vm/jit/x86_64/codegen.c: Likewise.
* src/vm/jit/x86_64/emit.c: Likewise.
s4 builtin_canstore(java_handle_objectarray_t *oa, java_handle_t *o)
{
- s4 result;
+ int result;
LLNI_CRITICAL_START;
- result = builtin_fast_canstore(LLNI_UNWRAP(oa), LLNI_UNWRAP(o));
+ result = builtin_fast_canstore(LLNI_DIRECT(oa), LLNI_UNWRAP(o));
LLNI_CRITICAL_END;
+ /* if not possible, throw an exception */
+
+ if (result == 0)
+ exceptions_throw_arraystoreexception();
+
return result;
}
result = builtin_descriptorscompatible(valuedesc, componentvftbl->arraydesc);
}
- /* if not possible, throw an exception */
-
- if (result == 0)
- exceptions_throw_arraystoreexception();
-
/* return result */
return result;
s4 builtin_canstore(java_handle_objectarray_t *oa, java_handle_t *o);
/* NOT AN OP */
s4 builtin_fast_canstore(java_objectarray_t *oa, java_object_t *o);
-#define BUILTIN_FAST_canstore (functionptr) builtin_canstore
-#define BUILTIN_canstore BUILTIN_FAST_canstore /* XXX remove this "dont break trunk" macro */
+#define BUILTIN_FAST_canstore (functionptr) builtin_fast_canstore
#if defined(TRACE_ARGS_NUM)
void builtin_verbosecall_enter(s8 a0, s8 a1,
{
ICMD_AASTORE,
0,
- BUILTIN_canstore,
+ BUILTIN_FAST_canstore,
NULL,
NULL,
- "canstore",
+ "fast-canstore",
"([Ljava/lang/Object;Ljava/lang/Object;)I",
NULL,
NULL,
#define EXCEPTION_HARDWARE_NULLPOINTER 0
#define EXCEPTION_HARDWARE_ARITHMETIC 1
#define EXCEPTION_HARDWARE_ARRAYINDEXOUTOFBOUNDS 2
-#define EXCEPTION_HARDWARE_CLASSCAST 3
+#define EXCEPTION_HARDWARE_ARRAYSTORE 3
-#define EXCEPTION_HARDWARE_EXCEPTION 5
-#define EXCEPTION_HARDWARE_PATCHER 6
-#define EXCEPTION_HARDWARE_COMPILER 7
+#define EXCEPTION_HARDWARE_CLASSCAST 5
+#define EXCEPTION_HARDWARE_EXCEPTION 6
+#define EXCEPTION_HARDWARE_PATCHER 7
-#define EXCEPTION_HARDWARE_LARGEST 7
+#define EXCEPTION_HARDWARE_COMPILER 9
+
+#define EXCEPTION_HARDWARE_LARGEST 9
/* function prototypes ********************************************************/
M_INTMOVE(s1, REG_A0);
M_INTMOVE(s3, REG_A1);
- disp = dseg_add_functionptr(cd, BUILTIN_canstore);
+ disp = dseg_add_functionptr(cd, BUILTIN_FAST_canstore);
M_ALD(REG_PV, REG_PV, disp);
M_JSR(REG_RA, REG_PV);
disp = (s4) (cd->mcodeptr - cd->mcodebase);
M_LDA(REG_PV, REG_RA, -disp);
- emit_exception_check(cd, iptr);
+ emit_arraystore_check(cd, iptr);
s1 = emit_load_s1(jd, iptr, REG_ITMP1);
s2 = emit_load_s2(jd, iptr, REG_ITMP2);
}
+/* emit_arraystore_check *******************************************************
+
+ Emit an ArrayStoreException check.
+
+*******************************************************************************/
+
+void emit_arraystore_check(codegendata *cd, instruction *iptr)
+{
+ if (INSTRUCTION_MUST_CHECK(iptr)) {
+ M_BNEZ(REG_RESULT, 1);
+ /* Destination register must not be REG_ZERO, because then no
+ SIGSEGV is thrown. */
+ M_ALD_INTERN(REG_RESULT, REG_ZERO, EXCEPTION_HARDWARE_ARRAYSTORE);
+ }
+}
+
+
/* emit_classcast_check ********************************************************
Emit a ClassCastException check.
M_INTMOVE(s3, REG_A1);
/* call builtin function */
- disp = dseg_add_functionptr(cd, BUILTIN_canstore);
+ disp = dseg_add_functionptr(cd, BUILTIN_FAST_canstore);
M_DSEG_BRANCH(disp);
/* recompute pv */
M_RECOMPUTE_PV(s1);
/* check resturn value of builtin */
- emit_exception_check(cd, iptr);
+ emit_arraystore_check(cd, iptr);
/* finally store address into array */
s1 = emit_load_s1(jd, iptr, REG_ITMP1);
}
+/* emit_arraystore_check *******************************************************
+
+ Emit an ArrayStoreException check.
+
+*******************************************************************************/
+
+void emit_arraystore_check(codegendata *cd, instruction *iptr)
+{
+ if (INSTRUCTION_MUST_CHECK(iptr)) {
+ M_TST(REG_RESULT, REG_RESULT);
+ M_TRAPEQ(0, EXCEPTION_HARDWARE_ARRAYSTORE);
+ }
+}
+
+
/* emit_classcast_check ********************************************************
Emit a ClassCastException check.
void emit_arithmetic_check(codegendata *cd, instruction *iptr, s4 reg);
void emit_arrayindexoutofbounds_check(codegendata *cd, instruction *iptr, s4 s1, s4 s2);
+void emit_arraystore_check(codegendata *cd, instruction *iptr);
void emit_classcast_check(codegendata *cd, instruction *iptr, s4 condition, s4 reg, s4 s1);
void emit_nullpointer_check(codegendata *cd, instruction *iptr, s4 reg);
void emit_exception_check(codegendata *cd, instruction *iptr);
M_AST(s1, REG_SP, 0 * 4);
M_AST(s3, REG_SP, 1 * 4);
- M_MOV_IMM(BUILTIN_canstore, REG_ITMP1);
+ M_MOV_IMM(BUILTIN_FAST_canstore, REG_ITMP1);
M_CALL(REG_ITMP1);
- emit_exception_check(cd, iptr);
+ emit_arraystore_check(cd, iptr);
s1 = emit_load_s1(jd, iptr, REG_ITMP1);
s2 = emit_load_s2(jd, iptr, REG_ITMP2);
}
+/* emit_arraystore_check *******************************************************
+
+ Emit an ArrayStoreException check.
+
+*******************************************************************************/
+
+void emit_arraystore_check(codegendata *cd, instruction *iptr)
+{
+ if (INSTRUCTION_MUST_CHECK(iptr)) {
+ M_TEST(REG_RESULT);
+ M_BNE(6);
+ M_ALD_MEM(REG_RESULT, EXCEPTION_HARDWARE_ARRAYSTORE);
+ }
+}
+
+
/* emit_classcast_check ********************************************************
Emit a ClassCastException check.
s3 = emit_load_s3(jd, iptr, REG_ATMP2);
/* XXX what if array is NULL */
- disp = dseg_add_functionptr(cd, BUILTIN_canstore);
+ disp = dseg_add_functionptr(cd, BUILTIN_FAST_canstore);
M_AST(s1, REG_SP, 0*4);
M_AST(s3, REG_SP, 1*4);
- M_JSR_IMM(BUILTIN_canstore);
- emit_exception_check(cd, iptr);
+ M_JSR_IMM(BUILTIN_FAST_canstore);
+ emit_arraystore_check(cd, iptr);
s1 = emit_load_s1(jd, iptr, REG_ATMP1);
s2 = emit_load_s2(jd, iptr, REG_ITMP1);
}
}
+
+/* emit_arraystore_check *******************************************************
+
+ Emit an ArrayStoreException check.
+
+*******************************************************************************/
+
+void emit_arraystore_check(codegendata *cd, instruction *iptr)
+{
+ if (INSTRUCTION_MUST_CHECK(iptr)) {
+ M_ITST(REG_RESULT);
+ M_BNE(2);
+ /*M_ALD_INTERN(REG_ZERO, REG_ZERO, EXCEPTION_HARDWARE_ARRAYSTORE);*/
+ M_TRAP(EXCEPTION_HARDWARE_ARRAYSTORE);
+ }
+}
+
+
/* emit_nullpointer_check ******************************************************
Emit a NullPointerException check.
M_INTMOVE(s1, REG_A0);
M_INTMOVE(s3, REG_A1);
- disp = dseg_add_functionptr(cd, BUILTIN_canstore);
+ disp = dseg_add_functionptr(cd, BUILTIN_FAST_canstore);
M_ALD(REG_ITMP3, REG_PV, disp);
M_JSR(REG_RA, REG_ITMP3);
M_NOP;
- emit_exception_check(cd, iptr);
+ emit_arraystore_check(cd, iptr);
s1 = emit_load_s1(jd, iptr, REG_ITMP1);
s2 = emit_load_s2(jd, iptr, REG_ITMP2);
}
+/* emit_arraystore_check *******************************************************
+
+ Emit an ArrayStoreException check.
+
+*******************************************************************************/
+
+void emit_arraystore_check(codegendata *cd, instruction *iptr)
+{
+ if (INSTRUCTION_MUST_CHECK(iptr)) {
+ M_BNEZ(REG_RESULT, 2);
+ M_NOP;
+ M_ALD_INTERN(REG_RESULT, REG_ZERO, EXCEPTION_HARDWARE_ARRAYSTORE);
+ }
+}
+
+
/* emit_classcast_check ********************************************************
Emit a ClassCastException check.
s3 = emit_load_s3(jd, iptr, REG_A1);
/* XXX what if array is NULL */
- disp = dseg_add_functionptr(cd, BUILTIN_canstore);
+ disp = dseg_add_functionptr(cd, BUILTIN_FAST_canstore);
M_ALD(REG_ITMP3, REG_PV, disp);
M_MTCTR(REG_ITMP3);
M_INTMOVE(s3, REG_A1);
M_JSR;
- emit_exception_check(cd, iptr);
+ emit_arraystore_check(cd, iptr);
s1 = emit_load_s1(jd, iptr, REG_ITMP1);
s2 = emit_load_s2(jd, iptr, REG_ITMP2);
}
+/* emit_arraystore_check *******************************************************
+
+ Emit an ArrayStoreException check.
+
+*******************************************************************************/
+
+void emit_arraystore_check(codegendata *cd, instruction *iptr)
+{
+ if (INSTRUCTION_MUST_CHECK(iptr)) {
+ M_TST(REG_RESULT);
+ M_BNE(1);
+ M_ALD_INTERN(REG_ZERO, REG_ZERO, EXCEPTION_HARDWARE_ARRAYSTORE);
+ }
+}
+
+
/* emit_classcast_check ********************************************************
Emit a ClassCastException check.
emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
s3 = emit_load_s3(jd, iptr, REG_A1);
- disp = dseg_add_functionptr(cd, BUILTIN_canstore);
+ disp = dseg_add_functionptr(cd, BUILTIN_FAST_canstore);
M_ALD(REG_ITMP3, REG_PV, disp);
M_ALD(REG_ITMP3, REG_ITMP3, 0); /* TOC */
M_MTCTR(REG_ITMP3);
M_INTMOVE(s3, REG_A1);
M_JSR;
- emit_exception_check(cd, iptr);
+ emit_arraystore_check(cd, iptr);
s1 = emit_load_s1(jd, iptr, REG_ITMP1);
s2 = emit_load_s2(jd, iptr, REG_ITMP2);
}
+/* emit_arraystore_check *******************************************************
+
+ Emit an ArrayStoreException check.
+
+*******************************************************************************/
+
+void emit_arraystore_check(codegendata *cd, instruction *iptr)
+{
+ if (INSTRUCTION_MUST_CHECK(iptr)) {
+ M_TST(REG_RESULT);
+ M_BNE(1);
+ /* ALD is 4 byte aligned, ILD 2, onyl LWZ is byte aligned */
+ M_LWZ(REG_ZERO, REG_ZERO, EXCEPTION_HARDWARE_ARRAYSTORE);
+ }
+}
+
+
/* emit_arithmetic_check *******************************************************
Emit an ArithmeticException check.
M_INTMOVE(s1, REG_A0);
M_INTMOVE(s3, REG_A1);
- disp = dseg_add_functionptr(cd, BUILTIN_canstore);
+ disp = dseg_add_functionptr(cd, BUILTIN_FAST_canstore);
M_ALD_DSEG(REG_ITMP3, disp);
M_ASUB_IMM(96, REG_SP);
M_JSR(REG_RA, REG_ITMP3);
M_AADD_IMM(96, REG_SP);
- emit_exception_check(cd, iptr);
+ emit_arraystore_check(cd, iptr);
s1 = emit_load_s1(jd, iptr, REG_ITMP1);
s2 = emit_load_s2(jd, iptr, REG_ITMP2);
}
}
+
+/* emit_arraystore_check *******************************************************
+
+ Emit an ArrayStoreException check.
+
+*******************************************************************************/
+
+void emit_arraystore_check(codegendata *cd, instruction *iptr)
+{
+ if (INSTRUCTION_MUST_CHECK(iptr)) {
+ M_TEST(REG_RESULT);
+ M_BNE(SZ_BRC + SZ_ILL);
+ M_ILL(EXCEPTION_HARDWARE_ARRAYSTORE);
+ }
+}
+
+
void emit_classcast_check(codegendata *cd, instruction *iptr, s4 condition, s4 reg, s4 s1) {
if (INSTRUCTION_MUST_CHECK(iptr)) {
if (reg != RN) {
M_MOV(s1, REG_OUT0);
M_MOV(s3, REG_OUT1);
- disp = dseg_add_functionptr(cd, BUILTIN_canstore);
+ disp = dseg_add_functionptr(cd, BUILTIN_FAST_canstore);
M_ALD(REG_ITMP3, REG_PV, disp);
M_JMP(REG_RA_CALLER, REG_ITMP3, REG_ZERO);
M_NOP;
- emit_exception_check(cd, iptr);
+ emit_arraystore_check(cd, iptr);
s1 = emit_load_s1(jd, iptr, REG_ITMP1);
s2 = emit_load_s2(jd, iptr, REG_ITMP2);
}
+/* emit_arraystore_check *******************************************************
+
+ Emit an ArrayStoreException check.
+
+*******************************************************************************/
+
+void emit_arraystore_check(codegendata *cd, instruction *iptr)
+{
+ if (INSTRUCTION_MUST_CHECK(iptr)) {
+ M_BNEZ(REG_RESULT_CALLER, 3);
+ M_NOP;
+ M_ALD_INTERN(REG_RESULT_CALLER, REG_ZERO, EXCEPTION_HARDWARE_ARRAYSTORE);
+ }
+}
+
+
/* emit_classcast_check ********************************************************
Emit a ClassCastException check.
COUNT(count_check_bound);
COUNT(count_pcmd_mem);
- bte = builtintable_get_internal(BUILTIN_canstore);
+ bte = builtintable_get_internal(BUILTIN_FAST_canstore);
md = bte->md;
if (md->memuse > rd->memuse)
M_MOV(s1, REG_A0);
M_MOV(s3, REG_A1);
- M_MOV_IMM(BUILTIN_canstore, REG_ITMP1);
+ M_MOV_IMM(BUILTIN_FAST_canstore, REG_ITMP1);
M_CALL(REG_ITMP1);
- emit_exception_check(cd, iptr);
+ emit_arraystore_check(cd, iptr);
s1 = emit_load_s1(jd, iptr, REG_ITMP1);
s2 = emit_load_s2(jd, iptr, REG_ITMP2);
}
+/* emit_arraystore_check *******************************************************
+
+ Emit an ArrayStoreException check.
+
+*******************************************************************************/
+
+void emit_arraystore_check(codegendata *cd, instruction *iptr)
+{
+ if (INSTRUCTION_MUST_CHECK(iptr)) {
+ M_TEST(REG_RESULT);
+ M_BNE(8);
+ M_ALD_MEM(REG_RESULT, EXCEPTION_HARDWARE_ARRAYSTORE);
+ }
+}
+
+
/* emit_classcast_check ********************************************************
Emit a ClassCastException check.
p = exceptions_new_arrayindexoutofboundsexception(index);
break;
+ case EXCEPTION_HARDWARE_ARRAYSTORE:
+ p = exceptions_new_arraystoreexception();
+ break;
+
case EXCEPTION_HARDWARE_CLASSCAST:
o = (java_object_t *) val;
p = exceptions_new_classcastexception(o);