Mercurial > hg > truffle
comparison src/share/vm/runtime/deoptimization.cpp @ 5130:ab038e0d6b43
Merge
author | Lukas Stadler <lukas.stadler@jku.at> |
---|---|
date | Wed, 21 Mar 2012 11:28:22 +0100 |
parents | 51111665eda6 34518fd74518 |
children | 667c7bc2435b |
comparison
equal
deleted
inserted
replaced
5129:51111665eda6 | 5130:ab038e0d6b43 |
---|---|
1149 } | 1149 } |
1150 BiasedLocking::revoke_at_safepoint(objects_to_revoke); | 1150 BiasedLocking::revoke_at_safepoint(objects_to_revoke); |
1151 } | 1151 } |
1152 | 1152 |
1153 | 1153 |
1154 void Deoptimization::deoptimize_single_frame(JavaThread* thread, frame fr) { | 1154 void Deoptimization::deoptimize_single_frame(JavaThread* thread, frame fr, Deoptimization::DeoptReason reason) { |
1155 assert(fr.can_be_deoptimized(), "checking frame type"); | 1155 assert(fr.can_be_deoptimized(), "checking frame type"); |
1156 | 1156 |
1157 gather_statistics(Reason_constraint, Action_none, Bytecodes::_illegal); | 1157 gather_statistics(reason, Action_none, Bytecodes::_illegal); |
1158 | 1158 |
1159 // Patch the nmethod so that when execution returns to it we will | 1159 // Patch the nmethod so that when execution returns to it we will |
1160 // deopt the execution state and return to the interpreter. | 1160 // deopt the execution state and return to the interpreter. |
1161 fr.deoptimize(thread); | 1161 fr.deoptimize(thread); |
1162 } | 1162 } |
1163 | 1163 |
1164 void Deoptimization::deoptimize(JavaThread* thread, frame fr, RegisterMap *map) { | 1164 void Deoptimization::deoptimize(JavaThread* thread, frame fr, RegisterMap *map, DeoptReason reason) { |
1165 // Deoptimize only if the frame comes from compile code. | 1165 // Deoptimize only if the frame comes from compile code. |
1166 // Do not deoptimize the frame which is already patched | 1166 // Do not deoptimize the frame which is already patched |
1167 // during the execution of the loops below. | 1167 // during the execution of the loops below. |
1168 if (!fr.is_compiled_frame() || fr.is_deoptimized_frame()) { | 1168 if (!fr.is_compiled_frame() || fr.is_deoptimized_frame()) { |
1169 return; | 1169 return; |
1171 ResourceMark rm; | 1171 ResourceMark rm; |
1172 DeoptimizationMarker dm; | 1172 DeoptimizationMarker dm; |
1173 if (UseBiasedLocking) { | 1173 if (UseBiasedLocking) { |
1174 revoke_biases_of_monitors(thread, fr, map); | 1174 revoke_biases_of_monitors(thread, fr, map); |
1175 } | 1175 } |
1176 deoptimize_single_frame(thread, fr); | 1176 deoptimize_single_frame(thread, fr, reason); |
1177 | 1177 |
1178 } | 1178 } |
1179 | 1179 |
1180 | 1180 |
1181 void Deoptimization::deoptimize_frame_internal(JavaThread* thread, intptr_t* id) { | 1181 void Deoptimization::deoptimize_frame_internal(JavaThread* thread, intptr_t* id, DeoptReason reason) { |
1182 assert(thread == Thread::current() || SafepointSynchronize::is_at_safepoint(), | 1182 assert(thread == Thread::current() || SafepointSynchronize::is_at_safepoint(), |
1183 "can only deoptimize other thread at a safepoint"); | 1183 "can only deoptimize other thread at a safepoint"); |
1184 // Compute frame and register map based on thread and sp. | 1184 // Compute frame and register map based on thread and sp. |
1185 RegisterMap reg_map(thread, UseBiasedLocking); | 1185 RegisterMap reg_map(thread, UseBiasedLocking); |
1186 frame fr = thread->last_frame(); | 1186 frame fr = thread->last_frame(); |
1187 while (fr.id() != id) { | 1187 while (fr.id() != id) { |
1188 fr = fr.sender(®_map); | 1188 fr = fr.sender(®_map); |
1189 } | 1189 } |
1190 deoptimize(thread, fr, ®_map); | 1190 deoptimize(thread, fr, ®_map, reason); |
1191 } | 1191 } |
1192 | 1192 |
1193 | 1193 |
1194 void Deoptimization::deoptimize_frame(JavaThread* thread, intptr_t* id) { | 1194 void Deoptimization::deoptimize_frame(JavaThread* thread, intptr_t* id, DeoptReason reason) { |
1195 if (thread == Thread::current()) { | 1195 if (thread == Thread::current()) { |
1196 Deoptimization::deoptimize_frame_internal(thread, id); | 1196 Deoptimization::deoptimize_frame_internal(thread, id, reason); |
1197 } else { | 1197 } else { |
1198 VM_DeoptimizeFrame deopt(thread, id); | 1198 VM_DeoptimizeFrame deopt(thread, id, reason); |
1199 VMThread::execute(&deopt); | 1199 VMThread::execute(&deopt); |
1200 } | 1200 } |
1201 } | 1201 } |
1202 | 1202 |
1203 | 1203 |
1518 if (ProfileTraps && update_trap_state && trap_mdo.not_null()) { | 1518 if (ProfileTraps && update_trap_state && trap_mdo.not_null()) { |
1519 assert(trap_mdo() == get_method_data(thread, trap_method, false), "sanity"); | 1519 assert(trap_mdo() == get_method_data(thread, trap_method, false), "sanity"); |
1520 uint this_trap_count = 0; | 1520 uint this_trap_count = 0; |
1521 bool maybe_prior_trap = false; | 1521 bool maybe_prior_trap = false; |
1522 bool maybe_prior_recompile = false; | 1522 bool maybe_prior_recompile = false; |
1523 pdata = query_update_method_data(trap_mdo, trap_bci, reason, | 1523 pdata = query_update_method_data(trap_mdo, trap_bci, reason, true, |
1524 //outputs: | 1524 //outputs: |
1525 this_trap_count, | 1525 this_trap_count, |
1526 maybe_prior_trap, | 1526 maybe_prior_trap, |
1527 maybe_prior_recompile); | 1527 maybe_prior_recompile); |
1528 // Because the interpreter also counts null, div0, range, and class | 1528 // Because the interpreter also counts null, div0, range, and class |
1652 | 1652 |
1653 ProfileData* | 1653 ProfileData* |
1654 Deoptimization::query_update_method_data(methodDataHandle trap_mdo, | 1654 Deoptimization::query_update_method_data(methodDataHandle trap_mdo, |
1655 int trap_bci, | 1655 int trap_bci, |
1656 Deoptimization::DeoptReason reason, | 1656 Deoptimization::DeoptReason reason, |
1657 bool update_total_trap_count, | |
1657 //outputs: | 1658 //outputs: |
1658 uint& ret_this_trap_count, | 1659 uint& ret_this_trap_count, |
1659 bool& ret_maybe_prior_trap, | 1660 bool& ret_maybe_prior_trap, |
1660 bool& ret_maybe_prior_recompile) { | 1661 bool& ret_maybe_prior_recompile) { |
1661 uint prior_trap_count = trap_mdo->trap_count(reason); | 1662 bool maybe_prior_trap = false; |
1662 uint this_trap_count = trap_mdo->inc_trap_count(reason); | 1663 bool maybe_prior_recompile = false; |
1663 | 1664 uint this_trap_count = 0; |
1664 // If the runtime cannot find a place to store trap history, | 1665 if (update_total_trap_count) { |
1665 // it is estimated based on the general condition of the method. | 1666 uint prior_trap_count = trap_mdo->trap_count(reason); |
1666 // If the method has ever been recompiled, or has ever incurred | 1667 this_trap_count = trap_mdo->inc_trap_count(reason); |
1667 // a trap with the present reason , then this BCI is assumed | 1668 |
1668 // (pessimistically) to be the culprit. | 1669 // If the runtime cannot find a place to store trap history, |
1669 bool maybe_prior_trap = (prior_trap_count != 0); | 1670 // it is estimated based on the general condition of the method. |
1670 bool maybe_prior_recompile = (trap_mdo->decompile_count() != 0); | 1671 // If the method has ever been recompiled, or has ever incurred |
1672 // a trap with the present reason , then this BCI is assumed | |
1673 // (pessimistically) to be the culprit. | |
1674 maybe_prior_trap = (prior_trap_count != 0); | |
1675 maybe_prior_recompile = (trap_mdo->decompile_count() != 0); | |
1676 } | |
1677 | |
1678 // For reasons which are recorded per bytecode, we check per-BCI data. | |
1671 ProfileData* pdata = NULL; | 1679 ProfileData* pdata = NULL; |
1672 | |
1673 | |
1674 // For reasons which are recorded per bytecode, we check per-BCI data. | |
1675 DeoptReason per_bc_reason = reason_recorded_per_bytecode_if_any(reason); | 1680 DeoptReason per_bc_reason = reason_recorded_per_bytecode_if_any(reason); |
1681 assert(per_bc_reason != Reason_none || update_total_trap_count, "must be"); | |
1676 if (per_bc_reason != Reason_none) { | 1682 if (per_bc_reason != Reason_none) { |
1677 // Find the profile data for this BCI. If there isn't one, | 1683 // Find the profile data for this BCI. If there isn't one, |
1678 // try to allocate one from the MDO's set of spares. | 1684 // try to allocate one from the MDO's set of spares. |
1679 // This will let us detect a repeated trap at this point. | 1685 // This will let us detect a repeated trap at this point. |
1680 pdata = trap_mdo->allocate_bci_to_data(trap_bci); | 1686 pdata = trap_mdo->allocate_bci_to_data(trap_bci); |
1715 ResourceMark rm; | 1721 ResourceMark rm; |
1716 // Ignored outputs: | 1722 // Ignored outputs: |
1717 uint ignore_this_trap_count; | 1723 uint ignore_this_trap_count; |
1718 bool ignore_maybe_prior_trap; | 1724 bool ignore_maybe_prior_trap; |
1719 bool ignore_maybe_prior_recompile; | 1725 bool ignore_maybe_prior_recompile; |
1726 // Graal uses the total counts to determine if deoptimizations are happening too frequently -> do not adjust total counts | |
1727 bool update_total_counts = GRAAL_ONLY(false) NOT_GRAAL(true); | |
1720 query_update_method_data(trap_mdo, trap_bci, | 1728 query_update_method_data(trap_mdo, trap_bci, |
1721 (DeoptReason)reason, | 1729 (DeoptReason)reason, |
1730 update_total_counts, | |
1722 ignore_this_trap_count, | 1731 ignore_this_trap_count, |
1723 ignore_maybe_prior_trap, | 1732 ignore_maybe_prior_trap, |
1724 ignore_maybe_prior_recompile); | 1733 ignore_maybe_prior_recompile); |
1725 } | 1734 } |
1726 | 1735 |
1829 | 1838 |
1830 //--------------------------------statics-------------------------------------- | 1839 //--------------------------------statics-------------------------------------- |
1831 Deoptimization::DeoptAction Deoptimization::_unloaded_action | 1840 Deoptimization::DeoptAction Deoptimization::_unloaded_action |
1832 = Deoptimization::Action_reinterpret; | 1841 = Deoptimization::Action_reinterpret; |
1833 const char* Deoptimization::_trap_reason_name[Reason_LIMIT] = { | 1842 const char* Deoptimization::_trap_reason_name[Reason_LIMIT] = { |
1843 #ifdef GRAAL | |
1844 "none", | |
1845 "null_check", | |
1846 "range_check", | |
1847 "class_check", | |
1848 "array_check", | |
1849 "unreached", | |
1850 "type_checked_inlining", | |
1851 "optimized_type_check", | |
1852 "not_compiled_exception_handler", | |
1853 "unresolved", | |
1854 "jsr_mismatch", | |
1855 "div0_check", | |
1856 "constraint" | |
1857 #else | |
1834 // Note: Keep this in sync. with enum DeoptReason. | 1858 // Note: Keep this in sync. with enum DeoptReason. |
1835 "none", | 1859 "none", |
1836 "null_check", | 1860 "null_check", |
1837 "null_assert", | 1861 "null_assert", |
1838 "range_check", | 1862 "range_check", |
1847 "constraint", | 1871 "constraint", |
1848 "div0_check", | 1872 "div0_check", |
1849 "age", | 1873 "age", |
1850 "predicate", | 1874 "predicate", |
1851 "loop_limit_check" | 1875 "loop_limit_check" |
1876 #endif | |
1852 }; | 1877 }; |
1853 const char* Deoptimization::_trap_action_name[Action_LIMIT] = { | 1878 const char* Deoptimization::_trap_action_name[Action_LIMIT] = { |
1854 // Note: Keep this in sync. with enum DeoptAction. | 1879 // Note: Keep this in sync. with enum DeoptAction. |
1855 "none", | 1880 "none", |
1856 "maybe_recompile", | 1881 "maybe_recompile", |