src/share/vm/runtime/deoptimization.cpp
Index Unified diffs Context diffs Sdiffs Wdiffs Patch New Old Previous File Next File 6614597 Cdiff src/share/vm/runtime/deoptimization.cpp

src/share/vm/runtime/deoptimization.cpp

Print this page

        

*** 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 **** } // 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; } else { ! trap_method->set_not_compilable(); ! // But give grace to the enclosing nm->method(). } - } - } } 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 --- 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. ! inc_recompile_count = maybe_prior_trap; ! } } else { ! 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 **** } // 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) { reset_counters = true; } if (make_not_entrant && pdata != NULL) { // Record the recompilation event, if any. --- 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. ! // 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 **** } } // Take requested actions on the 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) { assert(make_not_entrant, "consistent"); nm->method()->set_not_compilable(); } } // Free marked resources --- 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); } // 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 **** 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) // 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; --- 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 **** "unreached", "unhandled", "constraint", "div0_check", "age", ! "predicate" }; const char* Deoptimization::_trap_action_name[Action_LIMIT] = { // Note: Keep this in sync. with enum DeoptAction. "none", "maybe_recompile", --- 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