Changes: Christian Ullrich
- $Id: codegen.c 4388 2006-01-30 15:44:52Z twisti $
+ $Id: codegen.c 4398 2006-01-31 23:43:08Z twisti $
*/
cd->lastmcodeptr = cd->mcodeptr;
- /* generate profiling code */
+ /* generate method profiling code */
if (opt_prof) {
- M_MOV_IMM((ptrint) m, REG_ITMP1);
- M_IINC_MEMBASE(REG_ITMP1, OFFSET(methodinfo, executioncount));
+ /* count frequency */
+
+ M_MOV_IMM((ptrint) m, REG_ITMP3);
+ M_IINC_MEMBASE(REG_ITMP3, OFFSET(methodinfo, frequency));
+
+ PROFILE_CYCLE_START;
}
/* create stack frame (if necessary) */
x86_64_call_reg(cd, REG_ITMP1);
}
-#if defined(ENABLE_STATISTICS)
- M_MOV_IMM((ptrint) compiledinvokation, REG_ITMP1);
- M_CALL(REG_ITMP1);
-#endif
-
/* restore integer argument registers */
for (p = 0; p < INT_ARG_CNT; p++)
len = bptr->indepth;
MCODECHECK(512);
+ /* generate basicblock profiling code */
+
+ if (opt_prof_bb) {
+ /* count frequency */
+
+ M_MOV_IMM((ptrint) m->bbfrequency, REG_ITMP2);
+ M_IINC_MEMBASE(REG_ITMP2, bptr->debug_nr * 4);
+
+ /* if this is an exception handler, start profiling again */
+
+ if (bptr->type == BBTYPE_EXH)
+ PROFILE_CYCLE_START;
+ }
+
#if defined(ENABLE_LSRA)
if (opt_lsra) {
while (src != NULL) {
} else {
#endif
- while (src != NULL) {
+ while (src != NULL) {
len--;
if ((len == 0) && (bptr->type != BBTYPE_STD)) {
if (bptr->type == BBTYPE_SBR) {
d = reg_of_var(rd, src, REG_ITMP1);
- x86_64_pop_reg(cd, d);
+ M_POP(d);
store_reg_to_var_int(src, d);
} else if (bptr->type == BBTYPE_EXH) {
s2 = src->type;
if (IS_FLT_DBL_TYPE(s2)) {
s1 = rd->interfaces[len][s2].regoff;
- if (!(rd->interfaces[len][s2].flags & INMEMORY)) {
+
+ if (!(rd->interfaces[len][s2].flags & INMEMORY))
M_FLTMOVE(s1, d);
+ else
+ M_DLD(d, REG_SP, s1 * 8);
- } else {
- x86_64_movq_membase_reg(cd, REG_SP, s1 * 8, d);
- }
store_reg_to_var_flt(src, d);
} else {
s1 = rd->interfaces[len][s2].regoff;
- if (!(rd->interfaces[len][s2].flags & INMEMORY)) {
+
+ if (!(rd->interfaces[len][s2].flags & INMEMORY))
M_INTMOVE(s1, d);
+ else
+ M_LLD(d, REG_SP, s1 * 8);
- } else {
- x86_64_mov_membase_reg(cd, REG_SP, s1 * 8, d);
- }
store_reg_to_var_int(src, d);
}
}
src = bptr->instack;
len = bptr->icount;
- currentline=0;
+ currentline = 0;
for (iptr = bptr->iinstr; len > 0; src = iptr->dst, len--, iptr++) {
if (iptr->line != currentline) {
break;
case ICMD_CHECKNULL: /* ..., objectref ==> ..., objectref */
- if (src->flags & INMEMORY) {
- x86_64_alu_imm_membase(cd, X86_64_CMP, 0, REG_SP, src->regoff * 8);
- } else {
- x86_64_test_reg_reg(cd, src->regoff, src->regoff);
- }
- x86_64_jcc(cd, X86_64_CC_Z, 0);
+ if (src->flags & INMEMORY)
+ M_CMP_IMM_MEMBASE(0, REG_SP, src->regoff * 8);
+ else
+ M_TEST(src->regoff);
+ M_BEQ(0);
codegen_addxnullrefs(cd, cd->mcodeptr);
break;
d = reg_of_var(rd, iptr->dst, REG_ITMP1);
if (iptr->val.i == 0)
- M_XOR(d, d);
+ M_CLR(d);
else
M_IMOV_IMM(iptr->val.i, d);
store_reg_to_var_int(iptr->dst, d);
d = reg_of_var(rd, iptr->dst, REG_ITMP1);
if (iptr->val.l == 0)
- M_XOR(d, d);
+ M_CLR(d);
else
M_MOV_IMM(iptr->val.l, d);
store_reg_to_var_int(iptr->dst, d);
d = reg_of_var(rd, iptr->dst, REG_ITMP1);
if ((iptr->target != NULL) && (iptr->val.a == NULL)) {
+/* PROFILE_CYCLE_STOP; */
+
codegen_addpatchref(cd, cd->mcodeptr,
PATCHER_aconst,
(unresolved_class *) iptr->target, 0);
M_NOP; M_NOP; M_NOP; M_NOP; M_NOP;
}
+/* PROFILE_CYCLE_START; */
+
M_MOV_IMM((ptrint) iptr->val.a, d);
} else {
- if (iptr->val.a == 0) {
- M_XOR(d, d);
- } else {
+ if (iptr->val.a == 0)
+ M_CLR(d);
+ else
M_MOV_IMM((ptrint) iptr->val.a, d);
- }
}
store_reg_to_var_int(iptr->dst, d);
break;
if (iptr->val.a == NULL) {
disp = dseg_addaddress(cd, NULL);
+/* PROFILE_CYCLE_STOP; */
+
codegen_addpatchref(cd, cd->mcodeptr,
PATCHER_get_putstatic,
(unresolved_field *) iptr->target, disp);
M_NOP; M_NOP; M_NOP; M_NOP; M_NOP;
}
+/* PROFILE_CYCLE_START; */
+
} else {
fieldinfo *fi = iptr->val.a;
disp = dseg_addaddress(cd, &(fi->value));
- if (!(fi->class->state & CLASS_INITIALIZED)) {
+ if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->class)) {
+ PROFILE_CYCLE_STOP;
+
codegen_addpatchref(cd, cd->mcodeptr,
PATCHER_clinit, fi->class, 0);
if (opt_showdisassemble) {
M_NOP; M_NOP; M_NOP; M_NOP; M_NOP;
}
+
+ PROFILE_CYCLE_START;
}
}
/* This approach is much faster than moving the field
address inline into a register. */
- x86_64_mov_membase_reg(cd, RIP, -(((ptrint) cd->mcodeptr + 7) - (ptrint) cd->mcodebase) + disp, REG_ITMP2);
+
+ M_ALD(REG_ITMP2, RIP, -(((ptrint) cd->mcodeptr + 7) -
+ (ptrint) cd->mcodebase) + disp);
+
switch (iptr->op1) {
case TYPE_INT:
d = reg_of_var(rd, iptr->dst, REG_ITMP1);
if (iptr->val.a == NULL) {
disp = dseg_addaddress(cd, NULL);
+/* PROFILE_CYCLE_STOP; */
+
codegen_addpatchref(cd, cd->mcodeptr,
PATCHER_get_putstatic,
(unresolved_field *) iptr->target, disp);
M_NOP; M_NOP; M_NOP; M_NOP; M_NOP;
}
+/* PROFILE_CYCLE_START; */
+
} else {
fieldinfo *fi = iptr->val.a;
disp = dseg_addaddress(cd, &(fi->value));
- if (!(fi->class->state & CLASS_INITIALIZED)) {
+ if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->class)) {
+ PROFILE_CYCLE_STOP;
+
codegen_addpatchref(cd, cd->mcodeptr,
PATCHER_clinit, fi->class, 0);
if (opt_showdisassemble) {
M_NOP; M_NOP; M_NOP; M_NOP; M_NOP;
}
+
+ PROFILE_CYCLE_START;
}
}
/* This approach is much faster than moving the field
address inline into a register. */
- x86_64_mov_membase_reg(cd, RIP, -(((ptrint) cd->mcodeptr + 7) - (ptrint) cd->mcodebase) + disp, REG_ITMP2);
+
+ M_ALD(REG_ITMP2, RIP, -(((ptrint) cd->mcodeptr + 7) -
+ (ptrint) cd->mcodebase) + disp);
+
switch (iptr->op1) {
case TYPE_INT:
var_to_reg_int(s2, src, REG_ITMP1);
if (iptr[1].val.a == NULL) {
disp = dseg_addaddress(cd, NULL);
+/* PROFILE_CYCLE_STOP; */
+
codegen_addpatchref(cd, cd->mcodeptr,
PATCHER_get_putstatic,
(unresolved_field *) iptr[1].target, disp);
M_NOP; M_NOP; M_NOP; M_NOP; M_NOP;
}
+/* PROFILE_CYCLE_START; */
+
} else {
fieldinfo *fi = iptr[1].val.a;
disp = dseg_addaddress(cd, &(fi->value));
- if (!(fi->class->state & CLASS_INITIALIZED)) {
+ if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->class)) {
+ PROFILE_CYCLE_STOP;
+
codegen_addpatchref(cd, cd->mcodeptr,
PATCHER_clinit, fi->class, 0);
if (opt_showdisassemble) {
M_NOP; M_NOP; M_NOP; M_NOP; M_NOP;
}
+
+ PROFILE_CYCLE_START;
}
}
/* This approach is much faster than moving the field
address inline into a register. */
- x86_64_mov_membase_reg(cd, RIP, -(((ptrint) cd->mcodeptr + 7) - (ptrint) cd->mcodebase) + disp, REG_ITMP1);
+
+ M_ALD(REG_ITMP1, RIP, -(((ptrint) cd->mcodeptr + 7) -
+ (ptrint) cd->mcodebase) + disp);
+
switch (iptr->op1) {
case TYPE_INT:
case TYPE_FLT:
gen_nullptr_check(s1);
if (iptr->val.a == NULL) {
+/* PROFILE_CYCLE_STOP; */
+
codegen_addpatchref(cd, cd->mcodeptr,
PATCHER_get_putfield,
(unresolved_field *) iptr->target, 0);
M_NOP; M_NOP; M_NOP; M_NOP; M_NOP;
}
+/* PROFILE_CYCLE_START; */
+
disp = 0;
} else {
}
if (iptr->val.a == NULL) {
+/* PROFILE_CYCLE_STOP; */
+
codegen_addpatchref(cd, cd->mcodeptr,
PATCHER_get_putfield,
(unresolved_field *) iptr->target, 0);
M_NOP; M_NOP; M_NOP; M_NOP; M_NOP;
}
+/* PROFILE_CYCLE_START; */
+
disp = 0;
} else {
gen_nullptr_check(s1);
if (iptr[1].val.a == NULL) {
+/* PROFILE_CYCLE_STOP; */
+
codegen_addpatchref(cd, cd->mcodeptr,
PATCHER_putfieldconst,
(unresolved_field *) iptr[1].target, 0);
M_NOP; M_NOP; M_NOP; M_NOP; M_NOP;
}
+/* PROFILE_CYCLE_START; */
+
disp = 0;
} else {
var_to_reg_int(s1, src, REG_ITMP1);
M_INTMOVE(s1, REG_ITMP1_XPTR);
+ PROFILE_CYCLE_STOP;
+
#ifdef ENABLE_VERIFIER
if (iptr->val.a) {
codegen_addpatchref(cd, cd->mcodeptr,
#ifdef ENABLE_VERIFIER
if (iptr->val.a) {
+ PROFILE_CYCLE_STOP;
+
codegen_addpatchref(cd, cd->mcodeptr,
PATCHER_athrow_areturn,
(unresolved_class *) iptr->val.a, 0);
if (opt_showdisassemble) {
M_NOP; M_NOP; M_NOP; M_NOP; M_NOP;
}
+
+ PROFILE_CYCLE_START;
}
#endif /* ENABLE_VERIFIER */
goto nowperformreturn;
if (parentargs_base)
M_AADD_IMM(parentargs_base * 8, REG_SP);
+ /* generate method profiling code */
+
+ PROFILE_CYCLE_STOP;
+
M_RET;
}
break;
}
}
+ /* generate method profiling code */
+
+ PROFILE_CYCLE_STOP;
+
switch (iptr->opc) {
case ICMD_BUILTIN:
a = (ptrint) bte->fp;
break;
}
+ /* generate method profiling code */
+
+ PROFILE_CYCLE_START;
+
/* d contains return type */
if (d != TYPE_VOID) {
cd->mcodeptr = (u1 *) cd->mcodebase;
cd->mcodeend = (s4 *) (cd->mcodebase + cd->mcodesize);
- /* generate profiling code */
+ /* generate native method profiling code */
if (opt_prof) {
- M_MOV_IMM((ptrint) m, REG_ITMP1);
- M_IINC_MEMBASE(REG_ITMP1, OFFSET(methodinfo, executioncount));
+ /* count frequency */
+
+ M_MOV_IMM((ptrint) m, REG_ITMP2);
+ M_IINC_MEMBASE(REG_ITMP2, OFFSET(methodinfo, frequency));
}
/* generate stub code */
M_MOV_IMM((ptrint) codegen_start_native_call, REG_ITMP1);
M_CALL(REG_ITMP1);
-#if defined(ENABLE_STATISTICS)
- if (opt_stat) {
- M_MOV_IMM((ptrint) nativeinvokation, REG_ITMP1);
- M_CALL(REG_ITMP1);
- }
-#endif
-
/* restore integer and float argument registers */
for (i = 0, j = 0; i < md->paramcount && j < INT_ARG_CNT; i++)