Authors: Andreas Krall
Christian Thalinger
-
- Changes: Joseph Wenninger
+ Joseph Wenninger
Christian Ullrich
- Edwin Steiner
+ Edwin Steiner
- $Id: codegen.c 5656 2006-10-03 20:57:15Z edwin $
+ $Id: codegen.c 6264 2007-01-02 19:40:18Z edwin $
*/
varinfo *var, *var1;
basicblock *bptr;
instruction *iptr;
- exceptiontable *ex;
+ exception_entry *ex;
u2 currentline;
methodinfo *lm; /* local methodinfo for ICMD_INVOKE* */
builtintable_entry *bte;
methoddesc *md;
- rplpoint *replacementpoint;
s4 fieldtype;
s4 varindex;
#if defined(ENABLE_SSA)
if (!jd->isleafmethod)
cd->stackframesize |= 0x3;
- (void) dseg_addaddress(cd, code); /* CodeinfoPointer */
- (void) dseg_adds4(cd, cd->stackframesize * 4); /* FrameSize */
+ (void) dseg_add_unique_address(cd, code); /* CodeinfoPointer */
+ (void) dseg_add_unique_s4(cd, cd->stackframesize * 4); /* FrameSize */
#if defined(ENABLE_THREADS)
/* IsSync contains the offset relative to the stack pointer for the
*/
if (checksync && (m->flags & ACC_SYNCHRONIZED))
- (void) dseg_adds4(cd, (rd->memuse + 1) * 4); /* IsSync */
+ (void) dseg_add_unique_s4(cd, (rd->memuse + 1) * 4); /* IsSync */
else
#endif
- (void) dseg_adds4(cd, 0); /* IsSync */
+ (void) dseg_add_unique_s4(cd, 0); /* IsSync */
- (void) dseg_adds4(cd, jd->isleafmethod); /* IsLeaf */
- (void) dseg_adds4(cd, INT_SAV_CNT - rd->savintreguse); /* IntSave */
- (void) dseg_adds4(cd, FLT_SAV_CNT - rd->savfltreguse); /* FltSave */
+ (void) dseg_add_unique_s4(cd, jd->isleafmethod); /* IsLeaf */
+ (void) dseg_add_unique_s4(cd, INT_SAV_CNT - rd->savintreguse); /* IntSave */
+ (void) dseg_add_unique_s4(cd, FLT_SAV_CNT - rd->savfltreguse); /* FltSave */
/* adds a reference for the length of the line number counter. We don't
know the size yet, since we evaluate the information during code
to the information gotten from the class file */
(void) dseg_addlinenumbertablesize(cd);
- (void) dseg_adds4(cd, cd->exceptiontablelength); /* ExTableSize */
+ (void) dseg_add_unique_s4(cd, jd->exceptiontablelength); /* ExTableSize */
/* create exception table */
- for (ex = cd->exceptiontable; ex != NULL; ex = ex->down) {
- dseg_addtarget(cd, ex->start);
- dseg_addtarget(cd, ex->end);
- dseg_addtarget(cd, ex->handler);
- (void) dseg_addaddress(cd, ex->catchtype.any);
+ for (ex = jd->exceptiontable; ex != NULL; ex = ex->down) {
+ dseg_add_target(cd, ex->start);
+ dseg_add_target(cd, ex->end);
+ dseg_add_target(cd, ex->handler);
+ (void) dseg_add_unique_address(cd, ex->catchtype.any);
}
/* generate method profiling code */
#endif
#if !defined(NDEBUG)
- if (JITDATA_HAS_FLAG_VERBOSECALL(jd))
- emit_verbosecall_enter(jd);
+ emit_verbosecall_enter(jd);
#endif
}
/* end of header generation */
- replacementpoint = jd->code->rplpoints;
+ /* create replacement points */
+
+ REPLACEMENT_POINTS_INIT(cd, jd);
/* walk through all basic blocks */
+
for (bptr = jd->basicblocks; bptr != NULL; bptr = bptr->next) {
bptr->mpc = (s4) (cd->mcodeptr - cd->mcodebase);
if (bptr->flags >= BBREACHED) {
-
/* branch resolving */
- branchref *brefs;
- for (brefs = bptr->branchrefs; brefs != NULL; brefs = brefs->next) {
- gen_resolvebranch(cd->mcodebase + brefs->branchpos,
- brefs->branchpos,
- bptr->mpc);
- }
+ codegen_resolve_branchrefs(cd, bptr);
-#if 0
/* handle replacement points */
- if (bptr->bitflags & BBFLAG_REPLACEMENT) {
- replacementpoint->pc = (u1*)bptr->mpc; /* will be resolved later */
-
- replacementpoint++;
-
- assert(cd->lastmcodeptr <= cd->mcodeptr);
- cd->lastmcodeptr = cd->mcodeptr + 5; /* 5 byte jmp patch */
- }
-#endif
+ REPLACEMENT_POINT_BLOCK_START(cd, bptr);
/* copy interface registers to their destination */
MCODECHECK(1024); /* 1kB should be enough */
switch (iptr->opc) {
- case ICMD_INLINE_START:
-#if 0
- {
- insinfo_inline *insinfo = (insinfo_inline *) iptr->target;
-#if defined(ENABLE_THREADS)
- if (insinfo->synchronize) {
- /* add monitor enter code */
- if (insinfo->method->flags & ACC_STATIC) {
- M_MOV_IMM(&insinfo->method->class->object.header, REG_ITMP1);
- M_AST(REG_ITMP1, REG_SP, 0 * 4);
- }
- else {
- /* nullpointer check must have been performed before */
- /* (XXX not done, yet) */
- var = &(rd->locals[insinfo->synclocal][TYPE_ADR]);
- if (var->flags & INMEMORY) {
- emit_mov_membase_reg(cd, REG_SP, var->vv.regoff * 4, REG_ITMP1);
- M_AST(REG_ITMP1, REG_SP, 0 * 4);
- }
- else {
- M_AST(var->vv.regoff, REG_SP, 0 * 4);
- }
- }
-
- M_MOV_IMM(LOCK_monitor_enter, REG_ITMP3);
- M_CALL(REG_ITMP3);
- }
-#endif
- dseg_addlinenumber_inline_start(cd, iptr);
- }
-#endif
+ case ICMD_NOP: /* ... ==> ... */
+ case ICMD_POP: /* ..., value ==> ... */
+ case ICMD_POP2: /* ..., value, value ==> ... */
break;
- case ICMD_INLINE_END:
-#if 0
- {
- insinfo_inline *insinfo = (insinfo_inline *) iptr->target;
+ case ICMD_INLINE_START:
- dseg_addlinenumber_inline_end(cd, iptr);
- dseg_addlinenumber(cd, iptr->line);
+ REPLACEMENT_POINT_INLINE_START(cd, iptr);
+ break;
-#if defined(ENABLE_THREADS)
- if (insinfo->synchronize) {
- /* add monitor exit code */
- if (insinfo->method->flags & ACC_STATIC) {
- M_MOV_IMM(&insinfo->method->class->object.header, REG_ITMP1);
- M_AST(REG_ITMP1, REG_SP, 0 * 4);
- }
- else {
- var = &(rd->locals[insinfo->synclocal][TYPE_ADR]);
- if (var->flags & INMEMORY) {
- M_ALD(REG_ITMP1, REG_SP, var->vv.regoff * 4);
- M_AST(REG_ITMP1, REG_SP, 0 * 4);
- }
- else {
- M_AST(var->vv.regoff, REG_SP, 0 * 4);
- }
- }
+ case ICMD_INLINE_BODY:
- M_MOV_IMM(LOCK_monitor_exit, REG_ITMP3);
- M_CALL(REG_ITMP3);
- }
-#endif
- }
-#endif
+ REPLACEMENT_POINT_INLINE_BODY(cd, iptr);
+ dseg_addlinenumber_inline_start(cd, iptr);
+ dseg_addlinenumber(cd, iptr->line);
break;
- case ICMD_NOP: /* ... ==> ... */
+ case ICMD_INLINE_END:
+
+ dseg_addlinenumber_inline_end(cd, iptr);
+ dseg_addlinenumber(cd, iptr->line);
break;
case ICMD_CHECKNULL: /* ..., objectref ==> ..., objectref */
s1 = emit_load_s1(jd, iptr, REG_ITMP1);
- M_TEST(s1);
- M_BEQ(0);
- codegen_add_nullpointerexception_ref(cd);
+ emit_nullpointer_check(cd, iptr, s1);
break;
/* constant operations ************************************************/
emit_faddp(cd);
} else {
- disp = dseg_addfloat(cd, iptr->sx.val.f);
+ disp = dseg_add_float(cd, iptr->sx.val.f);
emit_mov_imm_reg(cd, 0, REG_ITMP1);
dseg_adddata(cd);
emit_flds_membase(cd, REG_ITMP1, disp);
emit_faddp(cd);
} else {
- disp = dseg_adddouble(cd, iptr->sx.val.d);
+ disp = dseg_add_double(cd, iptr->sx.val.d);
emit_mov_imm_reg(cd, 0, REG_ITMP1);
dseg_adddata(cd);
emit_fldl_membase(cd, REG_ITMP1, disp);
case ICMD_FLOAD:
case ICMD_DLOAD:
case ICMD_ISTORE:
- case ICMD_ASTORE:
case ICMD_LSTORE:
case ICMD_FSTORE:
case ICMD_DSTORE:
emit_copy(jd, iptr, VAROP(iptr->s1), VAROP(iptr->dst));
break;
-
- /* pop operations *****************************************************/
-
- /* attention: double and longs are only one entry in CACAO ICMDs */
-
- case ICMD_POP: /* ..., value ==> ... */
- case ICMD_POP2: /* ..., value, value ==> ... */
-
+ case ICMD_ASTORE:
+ if (!(iptr->flags.bits & INS_FLAG_RETADDR))
+ emit_copy(jd, iptr, VAROP(iptr->s1), VAROP(iptr->dst));
break;
s1 = emit_load_s1(jd, iptr, EAX);
s2 = emit_load_s2(jd, iptr, REG_ITMP2);
d = codegen_reg_of_dst(jd, iptr, EAX);
-
- if (checknull) {
- M_TEST(s2);
- M_BEQ(0);
- codegen_add_arithmeticexception_ref(cd);
- }
+ emit_arithmetic_check(cd, iptr, s2);
M_INTMOVE(s1, EAX); /* we need the first operand in EAX */
s1 = emit_load_s1(jd, iptr, EAX);
s2 = emit_load_s2(jd, iptr, REG_ITMP2);
d = codegen_reg_of_dst(jd, iptr, EDX);
-
- if (checknull) {
- M_TEST(s2);
- M_BEQ(0);
- codegen_add_arithmeticexception_ref(cd);
- }
+ emit_arithmetic_check(cd, iptr, s2);
M_INTMOVE(s1, EAX); /* we need the first operand in EAX */
M_INTMOVE(GET_LOW_REG(s2), REG_ITMP3);
M_OR(GET_HIGH_REG(s2), REG_ITMP3);
- M_BEQ(0);
- codegen_add_arithmeticexception_ref(cd);
+ /* XXX could be optimized */
+ emit_arithmetic_check(cd, iptr, REG_ITMP3);
bte = iptr->sx.s23.s3.bte;
md = bte->md;
if (var->flags & INMEMORY) {
emit_fildl_membase(cd, REG_SP, var->vv.regoff * 4);
} else {
- disp = dseg_adds4(cd, 0);
+ /* XXX not thread safe! */
+ disp = dseg_add_unique_s4(cd, 0);
emit_mov_imm_reg(cd, 0, REG_ITMP1);
dseg_adddata(cd);
emit_mov_reg_membase(cd, var->vv.regoff, REG_ITMP1, disp);
dseg_adddata(cd);
/* Round to zero, 53-bit mode, exception masked */
- disp = dseg_adds4(cd, 0x0e7f);
+ disp = dseg_add_s4(cd, 0x0e7f);
emit_fldcw_membase(cd, REG_ITMP1, disp);
var = VAROP(iptr->dst);
emit_fistpl_membase(cd, REG_SP, var->vv.regoff * 4);
/* Round to nearest, 53-bit mode, exceptions masked */
- disp = dseg_adds4(cd, 0x027f);
+ disp = dseg_add_s4(cd, 0x027f);
emit_fldcw_membase(cd, REG_ITMP1, disp);
emit_alu_imm_membase(cd, ALU_CMP, 0x80000000,
CALCOFFSETBYTES(disp, REG_SP, var->vv.regoff * 4);
} else {
- disp = dseg_adds4(cd, 0);
+ /* XXX not thread safe! */
+ disp = dseg_add_unique_s4(cd, 0);
emit_fistpl_membase(cd, REG_ITMP1, disp);
emit_mov_membase_reg(cd, REG_ITMP1, disp, var->vv.regoff);
/* Round to nearest, 53-bit mode, exceptions masked */
- disp = dseg_adds4(cd, 0x027f);
+ disp = dseg_add_s4(cd, 0x027f);
emit_fldcw_membase(cd, REG_ITMP1, disp);
emit_alu_imm_reg(cd, ALU_CMP, 0x80000000, var->vv.regoff);
dseg_adddata(cd);
/* Round to zero, 53-bit mode, exception masked */
- disp = dseg_adds4(cd, 0x0e7f);
+ disp = dseg_add_s4(cd, 0x0e7f);
emit_fldcw_membase(cd, REG_ITMP1, disp);
var = VAROP(iptr->dst);
emit_fistpl_membase(cd, REG_SP, var->vv.regoff * 4);
/* Round to nearest, 53-bit mode, exceptions masked */
- disp = dseg_adds4(cd, 0x027f);
+ disp = dseg_add_s4(cd, 0x027f);
emit_fldcw_membase(cd, REG_ITMP1, disp);
emit_alu_imm_membase(cd, ALU_CMP, 0x80000000,
CALCOFFSETBYTES(disp, REG_SP, var->vv.regoff * 4);
} else {
- disp = dseg_adds4(cd, 0);
+ /* XXX not thread safe! */
+ disp = dseg_add_unique_s4(cd, 0);
emit_fistpl_membase(cd, REG_ITMP1, disp);
emit_mov_membase_reg(cd, REG_ITMP1, disp, var->vv.regoff);
/* Round to nearest, 53-bit mode, exceptions masked */
- disp = dseg_adds4(cd, 0x027f);
+ disp = dseg_add_s4(cd, 0x027f);
emit_fldcw_membase(cd, REG_ITMP1, disp);
emit_alu_imm_reg(cd, ALU_CMP, 0x80000000, var->vv.regoff);
dseg_adddata(cd);
/* Round to zero, 53-bit mode, exception masked */
- disp = dseg_adds4(cd, 0x0e7f);
+ disp = dseg_add_s4(cd, 0x0e7f);
emit_fldcw_membase(cd, REG_ITMP1, disp);
var = VAROP(iptr->dst);
emit_fistpll_membase(cd, REG_SP, var->vv.regoff * 4);
/* Round to nearest, 53-bit mode, exceptions masked */
- disp = dseg_adds4(cd, 0x027f);
+ disp = dseg_add_s4(cd, 0x027f);
emit_fldcw_membase(cd, REG_ITMP1, disp);
emit_alu_imm_membase(cd, ALU_CMP, 0x80000000,
dseg_adddata(cd);
/* Round to zero, 53-bit mode, exception masked */
- disp = dseg_adds4(cd, 0x0e7f);
+ disp = dseg_add_s4(cd, 0x0e7f);
emit_fldcw_membase(cd, REG_ITMP1, disp);
var = VAROP(iptr->dst);
emit_fistpll_membase(cd, REG_SP, var->vv.regoff * 4);
/* Round to nearest, 53-bit mode, exceptions masked */
- disp = dseg_adds4(cd, 0x027f);
+ disp = dseg_add_s4(cd, 0x027f);
emit_fldcw_membase(cd, REG_ITMP1, disp);
emit_alu_imm_membase(cd, ALU_CMP, 0x80000000,
s1 = emit_load_s1(jd, iptr, REG_ITMP1);
d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
- gen_nullptr_check(s1);
+ emit_nullpointer_check(cd, iptr, s1);
M_ILD(d, s1, OFFSET(java_arrayheader, size));
emit_store_dst(jd, iptr, d);
break;
s1 = emit_load_s1(jd, iptr, REG_ITMP1);
s2 = emit_load_s2(jd, iptr, REG_ITMP2);
d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
- if (INSTRUCTION_MUST_CHECK(iptr)) {
- gen_nullptr_check(s1);
- gen_bound_check;
- }
+ emit_array_checks(cd, iptr, s1, s2);
emit_movsbl_memindex_reg(cd, OFFSET(java_bytearray, data[0]),
s1, s2, 0, d);
emit_store_dst(jd, iptr, d);
s1 = emit_load_s1(jd, iptr, REG_ITMP1);
s2 = emit_load_s2(jd, iptr, REG_ITMP2);
d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
- if (INSTRUCTION_MUST_CHECK(iptr)) {
- gen_nullptr_check(s1);
- gen_bound_check;
- }
+ emit_array_checks(cd, iptr, s1, s2);
emit_movzwl_memindex_reg(cd, OFFSET(java_chararray, data[0]),
s1, s2, 1, d);
emit_store_dst(jd, iptr, d);
s1 = emit_load_s1(jd, iptr, REG_ITMP1);
s2 = emit_load_s2(jd, iptr, REG_ITMP2);
d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
- if (INSTRUCTION_MUST_CHECK(iptr)) {
- gen_nullptr_check(s1);
- gen_bound_check;
- }
+ emit_array_checks(cd, iptr, s1, s2);
emit_movswl_memindex_reg(cd, OFFSET(java_shortarray, data[0]),
s1, s2, 1, d);
emit_store_dst(jd, iptr, d);
s1 = emit_load_s1(jd, iptr, REG_ITMP1);
s2 = emit_load_s2(jd, iptr, REG_ITMP2);
d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
- if (INSTRUCTION_MUST_CHECK(iptr)) {
- gen_nullptr_check(s1);
- gen_bound_check;
- }
+ emit_array_checks(cd, iptr, s1, s2);
emit_mov_memindex_reg(cd, OFFSET(java_intarray, data[0]),
s1, s2, 2, d);
emit_store_dst(jd, iptr, d);
s1 = emit_load_s1(jd, iptr, REG_ITMP1);
s2 = emit_load_s2(jd, iptr, REG_ITMP2);
d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
- if (INSTRUCTION_MUST_CHECK(iptr)) {
- gen_nullptr_check(s1);
- gen_bound_check;
- }
+ emit_array_checks(cd, iptr, s1, s2);
- var = VAROP(iptr->dst);
+ var = VAROP(iptr->dst);
assert(var->flags & INMEMORY);
emit_mov_memindex_reg(cd, OFFSET(java_longarray, data[0]),
s1 = emit_load_s1(jd, iptr, REG_ITMP1);
s2 = emit_load_s2(jd, iptr, REG_ITMP2);
d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
- if (INSTRUCTION_MUST_CHECK(iptr)) {
- gen_nullptr_check(s1);
- gen_bound_check;
- }
+ emit_array_checks(cd, iptr, s1, s2);
emit_flds_memindex(cd, OFFSET(java_floatarray, data[0]), s1, s2, 2);
emit_store_dst(jd, iptr, d);
break;
s1 = emit_load_s1(jd, iptr, REG_ITMP1);
s2 = emit_load_s2(jd, iptr, REG_ITMP2);
d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
- if (INSTRUCTION_MUST_CHECK(iptr)) {
- gen_nullptr_check(s1);
- gen_bound_check;
- }
+ emit_array_checks(cd, iptr, s1, s2);
emit_fldl_memindex(cd, OFFSET(java_doublearray, data[0]), s1, s2,3);
emit_store_dst(jd, iptr, d);
break;
s1 = emit_load_s1(jd, iptr, REG_ITMP1);
s2 = emit_load_s2(jd, iptr, REG_ITMP2);
d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
- if (INSTRUCTION_MUST_CHECK(iptr)) {
- gen_nullptr_check(s1);
- gen_bound_check;
- }
+ emit_array_checks(cd, iptr, s1, s2);
emit_mov_memindex_reg(cd, OFFSET(java_objectarray, data[0]),
s1, s2, 2, d);
emit_store_dst(jd, iptr, d);
s1 = emit_load_s1(jd, iptr, REG_ITMP1);
s2 = emit_load_s2(jd, iptr, REG_ITMP2);
- if (INSTRUCTION_MUST_CHECK(iptr)) {
- gen_nullptr_check(s1);
- gen_bound_check;
- }
+ emit_array_checks(cd, iptr, s1, s2);
s3 = emit_load_s3(jd, iptr, REG_ITMP3);
if (s3 >= EBP) {
/* because EBP, ESI, EDI have no xH and xL nibbles */
s1 = emit_load_s1(jd, iptr, REG_ITMP1);
s2 = emit_load_s2(jd, iptr, REG_ITMP2);
- if (INSTRUCTION_MUST_CHECK(iptr)) {
- gen_nullptr_check(s1);
- gen_bound_check;
- }
+ emit_array_checks(cd, iptr, s1, s2);
s3 = emit_load_s3(jd, iptr, REG_ITMP3);
emit_movw_reg_memindex(cd, s3, OFFSET(java_chararray, data[0]),
s1, s2, 1);
s1 = emit_load_s1(jd, iptr, REG_ITMP1);
s2 = emit_load_s2(jd, iptr, REG_ITMP2);
- if (INSTRUCTION_MUST_CHECK(iptr)) {
- gen_nullptr_check(s1);
- gen_bound_check;
- }
+ emit_array_checks(cd, iptr, s1, s2);
s3 = emit_load_s3(jd, iptr, REG_ITMP3);
emit_movw_reg_memindex(cd, s3, OFFSET(java_shortarray, data[0]),
s1, s2, 1);
s1 = emit_load_s1(jd, iptr, REG_ITMP1);
s2 = emit_load_s2(jd, iptr, REG_ITMP2);
- if (INSTRUCTION_MUST_CHECK(iptr)) {
- gen_nullptr_check(s1);
- gen_bound_check;
- }
+ emit_array_checks(cd, iptr, s1, s2);
s3 = emit_load_s3(jd, iptr, REG_ITMP3);
emit_mov_reg_memindex(cd, s3, OFFSET(java_intarray, data[0]),
s1, s2, 2);
s1 = emit_load_s1(jd, iptr, REG_ITMP1);
s2 = emit_load_s2(jd, iptr, REG_ITMP2);
- if (INSTRUCTION_MUST_CHECK(iptr)) {
- gen_nullptr_check(s1);
- gen_bound_check;
- }
+ emit_array_checks(cd, iptr, s1, s2);
- var = VAROP(iptr->sx.s23.s3);
+ var = VAROP(iptr->sx.s23.s3);
assert(var->flags & INMEMORY);
emit_mov_membase_reg(cd, REG_SP, var->vv.regoff * 4, REG_ITMP3);
s1 = emit_load_s1(jd, iptr, REG_ITMP1);
s2 = emit_load_s2(jd, iptr, REG_ITMP2);
- if (INSTRUCTION_MUST_CHECK(iptr)) {
- gen_nullptr_check(s1);
- gen_bound_check;
- }
+ emit_array_checks(cd, iptr, s1, s2);
s3 = emit_load_s3(jd, iptr, REG_FTMP1);
emit_fstps_memindex(cd, OFFSET(java_floatarray, data[0]), s1, s2,2);
break;
s1 = emit_load_s1(jd, iptr, REG_ITMP1);
s2 = emit_load_s2(jd, iptr, REG_ITMP2);
- if (INSTRUCTION_MUST_CHECK(iptr)) {
- gen_nullptr_check(s1);
- gen_bound_check;
- }
+ emit_array_checks(cd, iptr, s1, s2);
s3 = emit_load_s3(jd, iptr, REG_FTMP1);
emit_fstpl_memindex(cd, OFFSET(java_doublearray, data[0]),
s1, s2, 3);
s1 = emit_load_s1(jd, iptr, REG_ITMP1);
s2 = emit_load_s2(jd, iptr, REG_ITMP2);
- if (INSTRUCTION_MUST_CHECK(iptr)) {
- gen_nullptr_check(s1);
- gen_bound_check;
- }
+ emit_array_checks(cd, iptr, s1, s2);
s3 = emit_load_s3(jd, iptr, REG_ITMP3);
M_AST(s1, REG_SP, 0 * 4);
s1 = emit_load_s1(jd, iptr, REG_ITMP1);
s2 = emit_load_s2(jd, iptr, REG_ITMP2);
- if (INSTRUCTION_MUST_CHECK(iptr)) {
- gen_nullptr_check(s1);
- gen_bound_check;
- }
+ emit_array_checks(cd, iptr, s1, s2);
emit_movb_imm_memindex(cd, iptr->sx.s23.s3.constval,
OFFSET(java_bytearray, data[0]), s1, s2, 0);
break;
s1 = emit_load_s1(jd, iptr, REG_ITMP1);
s2 = emit_load_s2(jd, iptr, REG_ITMP2);
- if (INSTRUCTION_MUST_CHECK(iptr)) {
- gen_nullptr_check(s1);
- gen_bound_check;
- }
+ emit_array_checks(cd, iptr, s1, s2);
emit_movw_imm_memindex(cd, iptr->sx.s23.s3.constval,
OFFSET(java_chararray, data[0]), s1, s2, 1);
break;
s1 = emit_load_s1(jd, iptr, REG_ITMP1);
s2 = emit_load_s2(jd, iptr, REG_ITMP2);
- if (INSTRUCTION_MUST_CHECK(iptr)) {
- gen_nullptr_check(s1);
- gen_bound_check;
- }
+ emit_array_checks(cd, iptr, s1, s2);
emit_movw_imm_memindex(cd, iptr->sx.s23.s3.constval,
OFFSET(java_shortarray, data[0]), s1, s2, 1);
break;
s1 = emit_load_s1(jd, iptr, REG_ITMP1);
s2 = emit_load_s2(jd, iptr, REG_ITMP2);
- if (INSTRUCTION_MUST_CHECK(iptr)) {
- gen_nullptr_check(s1);
- gen_bound_check;
- }
+ emit_array_checks(cd, iptr, s1, s2);
emit_mov_imm_memindex(cd, iptr->sx.s23.s3.constval,
OFFSET(java_intarray, data[0]), s1, s2, 2);
break;
s1 = emit_load_s1(jd, iptr, REG_ITMP1);
s2 = emit_load_s2(jd, iptr, REG_ITMP2);
- if (INSTRUCTION_MUST_CHECK(iptr)) {
- gen_nullptr_check(s1);
- gen_bound_check;
- }
+ emit_array_checks(cd, iptr, s1, s2);
emit_mov_imm_memindex(cd,
(u4) (iptr->sx.s23.s3.constval & 0x00000000ffffffff),
OFFSET(java_longarray, data[0]), s1, s2, 3);
s1 = emit_load_s1(jd, iptr, REG_ITMP1);
s2 = emit_load_s2(jd, iptr, REG_ITMP2);
- if (INSTRUCTION_MUST_CHECK(iptr)) {
- gen_nullptr_check(s1);
- gen_bound_check;
- }
+ emit_array_checks(cd, iptr, s1, s2);
emit_mov_imm_memindex(cd, 0,
OFFSET(java_objectarray, data[0]), s1, s2, 2);
break;
case ICMD_GETFIELD: /* .., objectref. ==> ..., value */
s1 = emit_load_s1(jd, iptr, REG_ITMP1);
- gen_nullptr_check(s1);
+ emit_nullpointer_check(cd, iptr, s1);
if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
unresolved_field *uf = iptr->sx.s23.s3.uf;
case ICMD_PUTFIELD: /* ..., objectref, value ==> ... */
s1 = emit_load_s1(jd, iptr, REG_ITMP1);
- gen_nullptr_check(s1);
+ emit_nullpointer_check(cd, iptr, s1);
/* must be done here because of code patching */
/* following NOP) */
s1 = emit_load_s1(jd, iptr, REG_ITMP1);
- gen_nullptr_check(s1);
+ emit_nullpointer_check(cd, iptr, s1);
if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
unresolved_field *uf = iptr->sx.s23.s3.uf;
M_JMP(REG_ITMP3);
break;
- case ICMD_INLINE_GOTO:
-#if 0
- M_COPY(src, iptr->dst.var);
-#endif
- /* FALLTHROUGH! */
-
case ICMD_GOTO: /* ... ==> ... */
case ICMD_RET: /* ... ==> ... */
case ICMD_IRETURN: /* ..., retvalue ==> ... */
+ REPLACEMENT_POINT_RETURN(cd, iptr);
s1 = emit_load_s1(jd, iptr, REG_RESULT);
M_INTMOVE(s1, REG_RESULT);
goto nowperformreturn;
case ICMD_LRETURN: /* ..., retvalue ==> ... */
+ REPLACEMENT_POINT_RETURN(cd, iptr);
s1 = emit_load_s1(jd, iptr, REG_RESULT_PACKED);
M_LNGMOVE(s1, REG_RESULT_PACKED);
goto nowperformreturn;
case ICMD_ARETURN: /* ..., retvalue ==> ... */
+ REPLACEMENT_POINT_RETURN(cd, iptr);
s1 = emit_load_s1(jd, iptr, REG_RESULT);
M_INTMOVE(s1, REG_RESULT);
case ICMD_FRETURN: /* ..., retvalue ==> ... */
case ICMD_DRETURN:
+ REPLACEMENT_POINT_RETURN(cd, iptr);
s1 = emit_load_s1(jd, iptr, REG_FRESULT);
goto nowperformreturn;
case ICMD_RETURN: /* ... ==> ... */
+ REPLACEMENT_POINT_RETURN(cd, iptr);
+
nowperformreturn:
{
s4 i, p;
p = cd->stackframesize;
#if !defined(NDEBUG)
- if (JITDATA_HAS_FLAG_VERBOSECALL(jd))
- emit_verbosecall_exit(jd);
+ emit_verbosecall_exit(jd);
#endif
#if defined(ENABLE_THREADS)
table += i;
while (--i >= 0) {
- dseg_addtarget(cd, table->block);
+ dseg_add_target(cd, table->block);
--table;
}
case ICMD_INVOKEVIRTUAL:/* op1 = arg count, val.a = method pointer */
case ICMD_INVOKEINTERFACE:
+ REPLACEMENT_POINT_INVOKE(cd, iptr);
+
if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
md = iptr->sx.s23.s3.um->methodref->parseddesc.md;
lm = NULL;
case ICMD_INVOKEVIRTUAL:
M_ALD(REG_ITMP1, REG_SP, 0 * 4);
- gen_nullptr_check(REG_ITMP1);
+ emit_nullpointer_check(cd, iptr, s1);
if (lm == NULL) {
unresolved_method *um = iptr->sx.s23.s3.um;
case ICMD_INVOKEINTERFACE:
M_ALD(REG_ITMP1, REG_SP, 0 * 4);
- gen_nullptr_check(REG_ITMP1);
+ emit_nullpointer_check(cd, iptr, s1);
if (lm == NULL) {
unresolved_method *um = iptr->sx.s23.s3.um;
break;
}
+ /* store size of call code in replacement point */
+
+ REPLACEMENT_POINT_INVOKE_RETURN(cd, iptr);
+
/* d contains return type */
if (d != TYPE_VOID) {
emit_exception_stubs(jd);
emit_patcher_stubs(jd);
-#if 0
- emit_replacement_stubs(jd);
-#endif
+ REPLACEMENT_EMIT_STUBS(jd);
codegen_finish(jd);
{
u1 *s; /* memory to hold the stub */
ptrint *d;
- codeinfo *code;
codegendata *cd;
s4 dumpsize;
cd = DNEW(codegendata);
cd->mcodeptr = s;
- /* Store the codeinfo pointer in the same place as in the
- methodheader for compiled methods. */
-
- code = code_codeinfo_new(m);
+ /* The codeinfo pointer is actually a pointer to the
+ methodinfo. This fakes a codeinfo structure. */
d[0] = (ptrint) asm_call_jit_compiler;
d[1] = (ptrint) m;
- d[2] = (ptrint) code;
+ d[2] = (ptrint) &d[1]; /* fake code->m */
/* code for the stub */
/* create method header */
- (void) dseg_addaddress(cd, code); /* CodeinfoPointer */
- (void) dseg_adds4(cd, cd->stackframesize * 4); /* FrameSize */
- (void) dseg_adds4(cd, 0); /* IsSync */
- (void) dseg_adds4(cd, 0); /* IsLeaf */
- (void) dseg_adds4(cd, 0); /* IntSave */
- (void) dseg_adds4(cd, 0); /* FltSave */
+ (void) dseg_add_unique_address(cd, code); /* CodeinfoPointer */
+ (void) dseg_add_unique_s4(cd, cd->stackframesize * 4); /* FrameSize */
+ (void) dseg_add_unique_s4(cd, 0); /* IsSync */
+ (void) dseg_add_unique_s4(cd, 0); /* IsLeaf */
+ (void) dseg_add_unique_s4(cd, 0); /* IntSave */
+ (void) dseg_add_unique_s4(cd, 0); /* FltSave */
(void) dseg_addlinenumbertablesize(cd);
- (void) dseg_adds4(cd, 0); /* ExTableSize */
+ (void) dseg_add_unique_s4(cd, 0); /* ExTableSize */
/* generate native method profiling code */
M_ASUB_IMM(cd->stackframesize * 4, REG_SP);
#if !defined(NDEBUG)
- if (JITDATA_HAS_FLAG_VERBOSECALL(jd))
- emit_verbosecall_enter(jd);
+ emit_verbosecall_enter(jd);
#endif
/* get function address (this must happen before the stackframeinfo) */
}
#if !defined(NDEBUG)
- if (JITDATA_HAS_FLAG_VERBOSECALL(jd))
- emit_verbosecall_exit(jd);
+ emit_verbosecall_exit(jd);
#endif
/* remove native stackframe info */