Mercurial > hg > truffle
comparison src/share/vm/runtime/deoptimization.cpp @ 1206:87684f1a88b5
6614597: Performance variability in jvm2008 xml.validation
Summary: Fix incorrect marking of methods as not compilable.
Reviewed-by: never
author | kvn |
---|---|
date | Mon, 01 Feb 2010 16:49:49 -0800 |
parents | 18a389214829 |
children | f70b0d9ab095 |
comparison
equal
deleted
inserted
replaced
1205:5fcfaa1ad96f | 1206:87684f1a88b5 |
---|---|
1336 // recompile relies on a methodDataOop to record heroic opt failures. | 1336 // recompile relies on a methodDataOop to record heroic opt failures. |
1337 | 1337 |
1338 // Whether the interpreter is producing MDO data or not, we also need | 1338 // Whether the interpreter is producing MDO data or not, we also need |
1339 // to use the MDO to detect hot deoptimization points and control | 1339 // to use the MDO to detect hot deoptimization points and control |
1340 // aggressive optimization. | 1340 // aggressive optimization. |
1341 bool inc_recompile_count = false; | |
1342 ProfileData* pdata = NULL; | |
1341 if (ProfileTraps && update_trap_state && trap_mdo.not_null()) { | 1343 if (ProfileTraps && update_trap_state && trap_mdo.not_null()) { |
1342 assert(trap_mdo() == get_method_data(thread, trap_method, false), "sanity"); | 1344 assert(trap_mdo() == get_method_data(thread, trap_method, false), "sanity"); |
1343 uint this_trap_count = 0; | 1345 uint this_trap_count = 0; |
1344 bool maybe_prior_trap = false; | 1346 bool maybe_prior_trap = false; |
1345 bool maybe_prior_recompile = false; | 1347 bool maybe_prior_recompile = false; |
1346 ProfileData* pdata | 1348 pdata = query_update_method_data(trap_mdo, trap_bci, reason, |
1347 = query_update_method_data(trap_mdo, trap_bci, reason, | |
1348 //outputs: | 1349 //outputs: |
1349 this_trap_count, | 1350 this_trap_count, |
1350 maybe_prior_trap, | 1351 maybe_prior_trap, |
1351 maybe_prior_recompile); | 1352 maybe_prior_recompile); |
1352 // Because the interpreter also counts null, div0, range, and class | 1353 // Because the interpreter also counts null, div0, range, and class |
1378 } | 1379 } |
1379 | 1380 |
1380 // Detect repeated recompilation at the same BCI, and enforce a limit. | 1381 // Detect repeated recompilation at the same BCI, and enforce a limit. |
1381 if (make_not_entrant && maybe_prior_recompile) { | 1382 if (make_not_entrant && maybe_prior_recompile) { |
1382 // More than one recompile at this point. | 1383 // More than one recompile at this point. |
1383 trap_mdo->inc_overflow_recompile_count(); | 1384 inc_recompile_count = maybe_prior_trap; |
1384 if (maybe_prior_trap | |
1385 && ((uint)trap_mdo->overflow_recompile_count() | |
1386 > (uint)PerBytecodeRecompilationCutoff)) { | |
1387 // Give up on the method containing the bad BCI. | |
1388 if (trap_method() == nm->method()) { | |
1389 make_not_compilable = true; | |
1390 } else { | |
1391 trap_method->set_not_compilable(); | |
1392 // But give grace to the enclosing nm->method(). | |
1393 } | |
1394 } | |
1395 } | 1385 } |
1396 } else { | 1386 } else { |
1397 // For reasons which are not recorded per-bytecode, we simply | 1387 // For reasons which are not recorded per-bytecode, we simply |
1398 // force recompiles unconditionally. | 1388 // force recompiles unconditionally. |
1399 // (Note that PerMethodRecompilationCutoff is enforced elsewhere.) | 1389 // (Note that PerMethodRecompilationCutoff is enforced elsewhere.) |
1416 // for a while to exercise it more thoroughly. | 1406 // for a while to exercise it more thoroughly. |
1417 if (make_not_entrant && maybe_prior_recompile && maybe_prior_trap) { | 1407 if (make_not_entrant && maybe_prior_recompile && maybe_prior_trap) { |
1418 reset_counters = true; | 1408 reset_counters = true; |
1419 } | 1409 } |
1420 | 1410 |
1421 if (make_not_entrant && pdata != NULL) { | 1411 } |
1412 | |
1413 // Take requested actions on the method: | |
1414 | |
1415 // Recompile | |
1416 if (make_not_entrant) { | |
1417 if (!nm->make_not_entrant()) { | |
1418 return; // the call did not change nmethod's state | |
1419 } | |
1420 | |
1421 if (pdata != NULL) { | |
1422 // Record the recompilation event, if any. | 1422 // Record the recompilation event, if any. |
1423 int tstate0 = pdata->trap_state(); | 1423 int tstate0 = pdata->trap_state(); |
1424 int tstate1 = trap_state_set_recompiled(tstate0, true); | 1424 int tstate1 = trap_state_set_recompiled(tstate0, true); |
1425 if (tstate1 != tstate0) | 1425 if (tstate1 != tstate0) |
1426 pdata->set_trap_state(tstate1); | 1426 pdata->set_trap_state(tstate1); |
1427 } | 1427 } |
1428 } | 1428 } |
1429 | 1429 |
1430 // Take requested actions on the method: | 1430 if (inc_recompile_count) { |
1431 trap_mdo->inc_overflow_recompile_count(); | |
1432 if ((uint)trap_mdo->overflow_recompile_count() > | |
1433 (uint)PerBytecodeRecompilationCutoff) { | |
1434 // Give up on the method containing the bad BCI. | |
1435 if (trap_method() == nm->method()) { | |
1436 make_not_compilable = true; | |
1437 } else { | |
1438 trap_method->set_not_compilable(); | |
1439 // But give grace to the enclosing nm->method(). | |
1440 } | |
1441 } | |
1442 } | |
1431 | 1443 |
1432 // Reset invocation counters | 1444 // Reset invocation counters |
1433 if (reset_counters) { | 1445 if (reset_counters) { |
1434 if (nm->is_osr_method()) | 1446 if (nm->is_osr_method()) |
1435 reset_invocation_counter(trap_scope, CompileThreshold); | 1447 reset_invocation_counter(trap_scope, CompileThreshold); |
1436 else | 1448 else |
1437 reset_invocation_counter(trap_scope); | 1449 reset_invocation_counter(trap_scope); |
1438 } | 1450 } |
1439 | 1451 |
1440 // Recompile | |
1441 if (make_not_entrant) { | |
1442 nm->make_not_entrant(); | |
1443 } | |
1444 | |
1445 // Give up compiling | 1452 // Give up compiling |
1446 if (make_not_compilable) { | 1453 if (make_not_compilable && !nm->method()->is_not_compilable()) { |
1447 assert(make_not_entrant, "consistent"); | 1454 assert(make_not_entrant, "consistent"); |
1448 nm->method()->set_not_compilable(); | 1455 nm->method()->set_not_compilable(); |
1449 } | 1456 } |
1450 | 1457 |
1451 } // Free marked resources | 1458 } // Free marked resources |
1514 tstate1 = trap_state_add_reason(tstate1, per_bc_reason); | 1521 tstate1 = trap_state_add_reason(tstate1, per_bc_reason); |
1515 // Store the updated state on the MDO, for next time. | 1522 // Store the updated state on the MDO, for next time. |
1516 if (tstate1 != tstate0) | 1523 if (tstate1 != tstate0) |
1517 pdata->set_trap_state(tstate1); | 1524 pdata->set_trap_state(tstate1); |
1518 } else { | 1525 } else { |
1519 if (LogCompilation && xtty != NULL) | 1526 if (LogCompilation && xtty != NULL) { |
1527 ttyLocker ttyl; | |
1520 // Missing MDP? Leave a small complaint in the log. | 1528 // Missing MDP? Leave a small complaint in the log. |
1521 xtty->elem("missing_mdp bci='%d'", trap_bci); | 1529 xtty->elem("missing_mdp bci='%d'", trap_bci); |
1530 } | |
1522 } | 1531 } |
1523 } | 1532 } |
1524 | 1533 |
1525 // Return results: | 1534 // Return results: |
1526 ret_this_trap_count = this_trap_count; | 1535 ret_this_trap_count = this_trap_count; |
1670 "null_assert", | 1679 "null_assert", |
1671 "range_check", | 1680 "range_check", |
1672 "class_check", | 1681 "class_check", |
1673 "array_check", | 1682 "array_check", |
1674 "intrinsic", | 1683 "intrinsic", |
1684 "bimorphic", | |
1675 "unloaded", | 1685 "unloaded", |
1676 "uninitialized", | 1686 "uninitialized", |
1677 "unreached", | 1687 "unreached", |
1678 "unhandled", | 1688 "unhandled", |
1679 "constraint", | 1689 "constraint", |