src/share/vm/runtime/deoptimization.cpp
Index
Unified diffs
Context diffs
Sdiffs
Wdiffs
Patch
New
Old
Previous File
Next File
*** old/src/share/vm/runtime/deoptimization.cpp Thu Jan 21 15:37:34 2010
--- new/src/share/vm/runtime/deoptimization.cpp Thu Jan 21 15:37:34 2010
*** 1330,1339 ****
--- 1330,1340 ----
// recompile relies on a methodDataOop to record heroic opt failures.
// Whether the interpreter is producing MDO data or not, we also need
// to use the MDO to detect hot deoptimization points and control
// aggressive optimization.
+ bool inc_recompile_count = false;
if (ProfileTraps && update_trap_state && trap_mdo.not_null()) {
assert(trap_mdo() == get_method_data(thread, trap_method, false), "sanity");
uint this_trap_count = 0;
bool maybe_prior_trap = false;
bool maybe_prior_recompile = false;
*** 1372,1400 ****
--- 1373,1400 ----
}
// Detect repeated recompilation at the same BCI, and enforce a limit.
if (make_not_entrant && maybe_prior_recompile) {
// More than one recompile at this point.
! trap_mdo->inc_overflow_recompile_count();
if (maybe_prior_trap
&& ((uint)trap_mdo->overflow_recompile_count()
> (uint)PerBytecodeRecompilationCutoff)) {
// Give up on the method containing the bad BCI.
if (trap_method() == nm->method()) {
make_not_compilable = true;
! inc_recompile_count = maybe_prior_trap;
+ }
} else {
trap_method->set_not_compilable();
// But give grace to the enclosing nm->method().
+ if (reason == Reason_bimorphic) {
+ // This isn't recorded per bci because of MDO limitations
+ // but lets piggy back the invalidation on the
+ // Reason_class_check count.
+ uint prior_trap_count = trap_mdo->trap_count(Reason_bimorphic);
+ if (prior_trap_count >= (uint)PerBytecodeTrapLimit) {
+ make_not_entrant = true;
}
}
}
} else {
// For reasons which are not recorded per-bytecode, we simply
// force recompiles unconditionally.
// (Note that PerMethodRecompilationCutoff is enforced elsewhere.)
make_not_entrant = true;
}
+ }
// Go back to the compiler if there are too many traps in this method.
if (this_trap_count >= (uint)PerMethodTrapLimit) {
// If there are too many traps in this method, force a recompile.
// This will allow the compiler to see the limit overflow, and
*** 1406,1416 ****
--- 1406,1421 ----
}
// Here's more hysteresis: If there has been a recompile at
// this trap point already, run the method in the interpreter
// for a while to exercise it more thoroughly.
if (make_not_entrant && maybe_prior_recompile && maybe_prior_trap) {
+ // Also do this to collect more data for transition from monomorphic
+ // case to bimorphic. But recompile method immediately if it is already
+ // compiled with bimorphic code.
+ if (make_not_entrant && maybe_prior_trap &&
+ ((maybe_prior_recompile && reason != Reason_bimorphic) ||
+ (UseBimorphicInlining && reason == Reason_class_check))) {
reset_counters = true;
}
if (make_not_entrant && pdata != NULL) {
// Record the recompilation event, if any.
*** 1421,1445 ****
--- 1426,1466 ----
}
}
// Take requested actions on the method:
+ // Recompile
+ if (make_not_entrant) {
+ if (!nm->make_not_entrant()) {
+ return; // the call did not change nmethod's state
+ }
+ }
+
+ if (inc_recompile_count) {
+ trap_mdo->inc_overflow_recompile_count();
+ if ((uint)trap_mdo->overflow_recompile_count() >
+ (uint)PerBytecodeRecompilationCutoff) {
+ // Give up on the method containing the bad BCI.
+ if (trap_method() == nm->method()) {
+ make_not_compilable = true;
+ } else {
+ trap_method->set_not_compilable();
+ // But give grace to the enclosing nm->method().
+ }
+ }
+ }
+
// Reset invocation counters
if (reset_counters) {
if (nm->is_osr_method())
reset_invocation_counter(trap_scope, CompileThreshold);
else
reset_invocation_counter(trap_scope);
}
// Recompile
if (make_not_entrant) {
nm->make_not_entrant();
}
// Give up compiling
! if (make_not_compilable && !nm->method()->is_not_compilable()) {
assert(make_not_entrant, "consistent");
nm->method()->set_not_compilable();
}
} // Free marked resources
*** 1508,1522 ****
--- 1529,1545 ----
tstate1 = trap_state_add_reason(tstate1, per_bc_reason);
// Store the updated state on the MDO, for next time.
if (tstate1 != tstate0)
pdata->set_trap_state(tstate1);
} else {
! if (LogCompilation && xtty != NULL) {
+ ttyLocker ttyl;
// Missing MDP? Leave a small complaint in the log.
xtty->elem("missing_mdp bci='%d'", trap_bci);
}
}
+ }
// Return results:
ret_this_trap_count = this_trap_count;
ret_maybe_prior_trap = maybe_prior_trap;
ret_maybe_prior_recompile = maybe_prior_recompile;
*** 1671,1681 ****
--- 1694,1705 ----
"unreached",
"unhandled",
"constraint",
"div0_check",
"age",
! "predicate",
+ "bimorphic"
};
const char* Deoptimization::_trap_action_name[Action_LIMIT] = {
// Note: Keep this in sync. with enum DeoptAction.
"none",
"maybe_recompile",
src/share/vm/runtime/deoptimization.cpp
Index
Unified diffs
Context diffs
Sdiffs
Wdiffs
Patch
New
Old
Previous File
Next File