Mercurial > hg > truffle
comparison src/share/vm/oops/methodData.hpp @ 17728:b8413a9cbb84
8031752: Failed speculative optimizations should be reattempted when root of compilation is different
Summary: support for speculative traps that keep track of the root of the compilation in which a trap occurs.
Reviewed-by: kvn, twisti
author | roland |
---|---|
date | Tue, 25 Feb 2014 18:16:24 +0100 |
parents | 6e1826d5c23e |
children | 1a43981d86ea |
comparison
equal
deleted
inserted
replaced
17727:cfd4aac53239 | 17728:b8413a9cbb84 |
---|---|
118 branch_data_tag, | 118 branch_data_tag, |
119 multi_branch_data_tag, | 119 multi_branch_data_tag, |
120 arg_info_data_tag, | 120 arg_info_data_tag, |
121 call_type_data_tag, | 121 call_type_data_tag, |
122 virtual_call_type_data_tag, | 122 virtual_call_type_data_tag, |
123 parameters_type_data_tag | 123 parameters_type_data_tag, |
124 speculative_trap_data_tag | |
124 }; | 125 }; |
125 | 126 |
126 enum { | 127 enum { |
127 // The _struct._flags word is formatted as [trap_state:4 | flags:4]. | 128 // The _struct._flags word is formatted as [trap_state:4 | flags:4]. |
128 // The trap state breaks down further as [recompile:1 | reason:3]. | 129 // The trap state breaks down further as [recompile:1 | reason:3]. |
187 } | 188 } |
188 | 189 |
189 void set_header(intptr_t value) { | 190 void set_header(intptr_t value) { |
190 _header._bits = value; | 191 _header._bits = value; |
191 } | 192 } |
192 void release_set_header(intptr_t value) { | 193 bool atomic_set_header(intptr_t value) { |
193 OrderAccess::release_store_ptr(&_header._bits, value); | 194 if (Atomic::cmpxchg_ptr(value, (volatile intptr_t*)&_header._bits, 0) == 0) { |
195 return true; | |
196 } | |
197 return false; | |
194 } | 198 } |
195 intptr_t header() { | 199 intptr_t header() { |
196 return _header._bits; | 200 return _header._bits; |
197 } | 201 } |
198 void set_cell_at(int index, intptr_t value) { | 202 void set_cell_at(int index, intptr_t value) { |
264 class BranchData; | 268 class BranchData; |
265 class ArrayData; | 269 class ArrayData; |
266 class MultiBranchData; | 270 class MultiBranchData; |
267 class ArgInfoData; | 271 class ArgInfoData; |
268 class ParametersTypeData; | 272 class ParametersTypeData; |
273 class SpeculativeTrapData; | |
269 | 274 |
270 // ProfileData | 275 // ProfileData |
271 // | 276 // |
272 // A ProfileData object is created to refer to a section of profiling | 277 // A ProfileData object is created to refer to a section of profiling |
273 // data in a structured way. | 278 // data in a structured way. |
283 }; | 288 }; |
284 #endif // !PRODUCT | 289 #endif // !PRODUCT |
285 | 290 |
286 // This is a pointer to a section of profiling data. | 291 // This is a pointer to a section of profiling data. |
287 DataLayout* _data; | 292 DataLayout* _data; |
293 | |
294 char* print_data_on_helper(const MethodData* md) const; | |
288 | 295 |
289 protected: | 296 protected: |
290 DataLayout* data() { return _data; } | 297 DataLayout* data() { return _data; } |
291 const DataLayout* data() const { return _data; } | 298 const DataLayout* data() const { return _data; } |
292 | 299 |
398 virtual bool is_MultiBranchData() const { return false; } | 405 virtual bool is_MultiBranchData() const { return false; } |
399 virtual bool is_ArgInfoData() const { return false; } | 406 virtual bool is_ArgInfoData() const { return false; } |
400 virtual bool is_CallTypeData() const { return false; } | 407 virtual bool is_CallTypeData() const { return false; } |
401 virtual bool is_VirtualCallTypeData()const { return false; } | 408 virtual bool is_VirtualCallTypeData()const { return false; } |
402 virtual bool is_ParametersTypeData() const { return false; } | 409 virtual bool is_ParametersTypeData() const { return false; } |
410 virtual bool is_SpeculativeTrapData()const { return false; } | |
403 | 411 |
404 | 412 |
405 BitData* as_BitData() const { | 413 BitData* as_BitData() const { |
406 assert(is_BitData(), "wrong type"); | 414 assert(is_BitData(), "wrong type"); |
407 return is_BitData() ? (BitData*) this : NULL; | 415 return is_BitData() ? (BitData*) this : NULL; |
451 return is_VirtualCallTypeData() ? (VirtualCallTypeData*)this : NULL; | 459 return is_VirtualCallTypeData() ? (VirtualCallTypeData*)this : NULL; |
452 } | 460 } |
453 ParametersTypeData* as_ParametersTypeData() const { | 461 ParametersTypeData* as_ParametersTypeData() const { |
454 assert(is_ParametersTypeData(), "wrong type"); | 462 assert(is_ParametersTypeData(), "wrong type"); |
455 return is_ParametersTypeData() ? (ParametersTypeData*)this : NULL; | 463 return is_ParametersTypeData() ? (ParametersTypeData*)this : NULL; |
464 } | |
465 SpeculativeTrapData* as_SpeculativeTrapData() const { | |
466 assert(is_SpeculativeTrapData(), "wrong type"); | |
467 return is_SpeculativeTrapData() ? (SpeculativeTrapData*)this : NULL; | |
456 } | 468 } |
457 | 469 |
458 | 470 |
459 // Subclass specific initialization | 471 // Subclass specific initialization |
460 virtual void post_initialize(BytecodeStream* stream, MethodData* mdo) {} | 472 virtual void post_initialize(BytecodeStream* stream, MethodData* mdo) {} |
467 // an oop in a ProfileData to the ci equivalent. Generally speaking, | 479 // an oop in a ProfileData to the ci equivalent. Generally speaking, |
468 // most ProfileData don't require any translation, so we provide the null | 480 // most ProfileData don't require any translation, so we provide the null |
469 // translation here, and the required translators are in the ci subclasses. | 481 // translation here, and the required translators are in the ci subclasses. |
470 virtual void translate_from(const ProfileData* data) {} | 482 virtual void translate_from(const ProfileData* data) {} |
471 | 483 |
472 virtual void print_data_on(outputStream* st) const { | 484 virtual void print_data_on(outputStream* st, const char* extra = NULL) const { |
473 ShouldNotReachHere(); | 485 ShouldNotReachHere(); |
474 } | 486 } |
475 | 487 |
488 void print_data_on(outputStream* st, const MethodData* md) const; | |
489 | |
476 #ifndef PRODUCT | 490 #ifndef PRODUCT |
477 void print_shared(outputStream* st, const char* name) const; | 491 void print_shared(outputStream* st, const char* name, const char* extra) const; |
478 void tab(outputStream* st, bool first = false) const; | 492 void tab(outputStream* st, bool first = false) const; |
479 #endif | 493 #endif |
480 }; | 494 }; |
481 | 495 |
482 // BitData | 496 // BitData |
520 static ByteSize bit_data_size() { | 534 static ByteSize bit_data_size() { |
521 return cell_offset(bit_cell_count); | 535 return cell_offset(bit_cell_count); |
522 } | 536 } |
523 | 537 |
524 #ifndef PRODUCT | 538 #ifndef PRODUCT |
525 void print_data_on(outputStream* st) const; | 539 void print_data_on(outputStream* st, const char* extra = NULL) const; |
526 #endif | 540 #endif |
527 }; | 541 }; |
528 | 542 |
529 // CounterData | 543 // CounterData |
530 // | 544 // |
564 void set_count(uint count) { | 578 void set_count(uint count) { |
565 set_uint_at(count_off, count); | 579 set_uint_at(count_off, count); |
566 } | 580 } |
567 | 581 |
568 #ifndef PRODUCT | 582 #ifndef PRODUCT |
569 void print_data_on(outputStream* st) const; | 583 void print_data_on(outputStream* st, const char* extra = NULL) const; |
570 #endif | 584 #endif |
571 }; | 585 }; |
572 | 586 |
573 // JumpData | 587 // JumpData |
574 // | 588 // |
637 | 651 |
638 // Specific initialization. | 652 // Specific initialization. |
639 void post_initialize(BytecodeStream* stream, MethodData* mdo); | 653 void post_initialize(BytecodeStream* stream, MethodData* mdo); |
640 | 654 |
641 #ifndef PRODUCT | 655 #ifndef PRODUCT |
642 void print_data_on(outputStream* st) const; | 656 void print_data_on(outputStream* st, const char* extra = NULL) const; |
643 #endif | 657 #endif |
644 }; | 658 }; |
645 | 659 |
646 // Entries in a ProfileData object to record types: it can either be | 660 // Entries in a ProfileData object to record types: it can either be |
647 // none (no profile), unknown (conflicting profile data) or a klass if | 661 // none (no profile), unknown (conflicting profile data) or a klass if |
1048 _ret.clean_weak_klass_links(is_alive_closure); | 1062 _ret.clean_weak_klass_links(is_alive_closure); |
1049 } | 1063 } |
1050 } | 1064 } |
1051 | 1065 |
1052 #ifndef PRODUCT | 1066 #ifndef PRODUCT |
1053 virtual void print_data_on(outputStream* st) const; | 1067 virtual void print_data_on(outputStream* st, const char* extra = NULL) const; |
1054 #endif | 1068 #endif |
1055 }; | 1069 }; |
1056 | 1070 |
1057 // ReceiverTypeData | 1071 // ReceiverTypeData |
1058 // | 1072 // |
1156 // GC support | 1170 // GC support |
1157 virtual void clean_weak_klass_links(BoolObjectClosure* is_alive_closure); | 1171 virtual void clean_weak_klass_links(BoolObjectClosure* is_alive_closure); |
1158 | 1172 |
1159 #ifndef PRODUCT | 1173 #ifndef PRODUCT |
1160 void print_receiver_data_on(outputStream* st) const; | 1174 void print_receiver_data_on(outputStream* st) const; |
1161 void print_data_on(outputStream* st) const; | 1175 void print_data_on(outputStream* st, const char* extra = NULL) const; |
1162 #endif | 1176 #endif |
1163 }; | 1177 }; |
1164 | 1178 |
1165 // VirtualCallData | 1179 // VirtualCallData |
1166 // | 1180 // |
1189 static ByteSize virtual_call_data_size() { | 1203 static ByteSize virtual_call_data_size() { |
1190 return cell_offset(static_cell_count()); | 1204 return cell_offset(static_cell_count()); |
1191 } | 1205 } |
1192 | 1206 |
1193 #ifndef PRODUCT | 1207 #ifndef PRODUCT |
1194 void print_data_on(outputStream* st) const; | 1208 void print_data_on(outputStream* st, const char* extra = NULL) const; |
1195 #endif | 1209 #endif |
1196 }; | 1210 }; |
1197 | 1211 |
1198 // VirtualCallTypeData | 1212 // VirtualCallTypeData |
1199 // | 1213 // |
1315 _ret.clean_weak_klass_links(is_alive_closure); | 1329 _ret.clean_weak_klass_links(is_alive_closure); |
1316 } | 1330 } |
1317 } | 1331 } |
1318 | 1332 |
1319 #ifndef PRODUCT | 1333 #ifndef PRODUCT |
1320 virtual void print_data_on(outputStream* st) const; | 1334 virtual void print_data_on(outputStream* st, const char* extra = NULL) const; |
1321 #endif | 1335 #endif |
1322 }; | 1336 }; |
1323 | 1337 |
1324 // RetData | 1338 // RetData |
1325 // | 1339 // |
1414 | 1428 |
1415 // Specific initialization. | 1429 // Specific initialization. |
1416 void post_initialize(BytecodeStream* stream, MethodData* mdo); | 1430 void post_initialize(BytecodeStream* stream, MethodData* mdo); |
1417 | 1431 |
1418 #ifndef PRODUCT | 1432 #ifndef PRODUCT |
1419 void print_data_on(outputStream* st) const; | 1433 void print_data_on(outputStream* st, const char* extra = NULL) const; |
1420 #endif | 1434 #endif |
1421 }; | 1435 }; |
1422 | 1436 |
1423 // BranchData | 1437 // BranchData |
1424 // | 1438 // |
1478 | 1492 |
1479 // Specific initialization. | 1493 // Specific initialization. |
1480 void post_initialize(BytecodeStream* stream, MethodData* mdo); | 1494 void post_initialize(BytecodeStream* stream, MethodData* mdo); |
1481 | 1495 |
1482 #ifndef PRODUCT | 1496 #ifndef PRODUCT |
1483 void print_data_on(outputStream* st) const; | 1497 void print_data_on(outputStream* st, const char* extra = NULL) const; |
1484 #endif | 1498 #endif |
1485 }; | 1499 }; |
1486 | 1500 |
1487 // ArrayData | 1501 // ArrayData |
1488 // | 1502 // |
1635 | 1649 |
1636 // Specific initialization. | 1650 // Specific initialization. |
1637 void post_initialize(BytecodeStream* stream, MethodData* mdo); | 1651 void post_initialize(BytecodeStream* stream, MethodData* mdo); |
1638 | 1652 |
1639 #ifndef PRODUCT | 1653 #ifndef PRODUCT |
1640 void print_data_on(outputStream* st) const; | 1654 void print_data_on(outputStream* st, const char* extra = NULL) const; |
1641 #endif | 1655 #endif |
1642 }; | 1656 }; |
1643 | 1657 |
1644 class ArgInfoData : public ArrayData { | 1658 class ArgInfoData : public ArrayData { |
1645 | 1659 |
1662 void set_arg_modified(int arg, uint val) { | 1676 void set_arg_modified(int arg, uint val) { |
1663 array_set_int_at(arg, val); | 1677 array_set_int_at(arg, val); |
1664 } | 1678 } |
1665 | 1679 |
1666 #ifndef PRODUCT | 1680 #ifndef PRODUCT |
1667 void print_data_on(outputStream* st) const; | 1681 void print_data_on(outputStream* st, const char* extra = NULL) const; |
1668 #endif | 1682 #endif |
1669 }; | 1683 }; |
1670 | 1684 |
1671 // ParametersTypeData | 1685 // ParametersTypeData |
1672 // | 1686 // |
1723 virtual void clean_weak_klass_links(BoolObjectClosure* is_alive_closure) { | 1737 virtual void clean_weak_klass_links(BoolObjectClosure* is_alive_closure) { |
1724 _parameters.clean_weak_klass_links(is_alive_closure); | 1738 _parameters.clean_weak_klass_links(is_alive_closure); |
1725 } | 1739 } |
1726 | 1740 |
1727 #ifndef PRODUCT | 1741 #ifndef PRODUCT |
1728 virtual void print_data_on(outputStream* st) const; | 1742 virtual void print_data_on(outputStream* st, const char* extra = NULL) const; |
1729 #endif | 1743 #endif |
1730 | 1744 |
1731 static ByteSize stack_slot_offset(int i) { | 1745 static ByteSize stack_slot_offset(int i) { |
1732 return cell_offset(stack_slot_local_offset(i)); | 1746 return cell_offset(stack_slot_local_offset(i)); |
1733 } | 1747 } |
1734 | 1748 |
1735 static ByteSize type_offset(int i) { | 1749 static ByteSize type_offset(int i) { |
1736 return cell_offset(type_local_offset(i)); | 1750 return cell_offset(type_local_offset(i)); |
1737 } | 1751 } |
1752 }; | |
1753 | |
1754 // SpeculativeTrapData | |
1755 // | |
1756 // A SpeculativeTrapData is used to record traps due to type | |
1757 // speculation. It records the root of the compilation: that type | |
1758 // speculation is wrong in the context of one compilation (for | |
1759 // method1) doesn't mean it's wrong in the context of another one (for | |
1760 // method2). Type speculation could have more/different data in the | |
1761 // context of the compilation of method2 and it's worthwhile to try an | |
1762 // optimization that failed for compilation of method1 in the context | |
1763 // of compilation of method2. | |
1764 // Space for SpeculativeTrapData entries is allocated from the extra | |
1765 // data space in the MDO. If we run out of space, the trap data for | |
1766 // the ProfileData at that bci is updated. | |
1767 class SpeculativeTrapData : public ProfileData { | |
1768 protected: | |
1769 enum { | |
1770 method_offset, | |
1771 speculative_trap_cell_count | |
1772 }; | |
1773 public: | |
1774 SpeculativeTrapData(DataLayout* layout) : ProfileData(layout) { | |
1775 assert(layout->tag() == DataLayout::speculative_trap_data_tag, "wrong type"); | |
1776 } | |
1777 | |
1778 virtual bool is_SpeculativeTrapData() const { return true; } | |
1779 | |
1780 static int static_cell_count() { | |
1781 return speculative_trap_cell_count; | |
1782 } | |
1783 | |
1784 virtual int cell_count() const { | |
1785 return static_cell_count(); | |
1786 } | |
1787 | |
1788 // Direct accessor | |
1789 Method* method() const { | |
1790 return (Method*)intptr_at(method_offset); | |
1791 } | |
1792 | |
1793 void set_method(Method* m) { | |
1794 set_intptr_at(method_offset, (intptr_t)m); | |
1795 } | |
1796 | |
1797 #ifndef PRODUCT | |
1798 virtual void print_data_on(outputStream* st, const char* extra = NULL) const; | |
1799 #endif | |
1738 }; | 1800 }; |
1739 | 1801 |
1740 // MethodData* | 1802 // MethodData* |
1741 // | 1803 // |
1742 // A MethodData* holds information which has been collected about | 1804 // A MethodData* holds information which has been collected about |
1801 | 1863 |
1802 bool is_methodData() const volatile { return true; } | 1864 bool is_methodData() const volatile { return true; } |
1803 | 1865 |
1804 // Whole-method sticky bits and flags | 1866 // Whole-method sticky bits and flags |
1805 enum { | 1867 enum { |
1806 _trap_hist_limit = 17, // decoupled from Deoptimization::Reason_LIMIT | 1868 _trap_hist_limit = 18, // decoupled from Deoptimization::Reason_LIMIT |
1807 _trap_hist_mask = max_jubyte, | 1869 _trap_hist_mask = max_jubyte, |
1808 _extra_data_count = 4 // extra DataLayout headers, for trap history | 1870 _extra_data_count = 4 // extra DataLayout headers, for trap history |
1809 }; // Public flag values | 1871 }; // Public flag values |
1810 private: | 1872 private: |
1811 uint _nof_decompiles; // count of all nmethod removals | 1873 uint _nof_decompiles; // count of all nmethod removals |
1856 intptr_t _data[1]; | 1918 intptr_t _data[1]; |
1857 | 1919 |
1858 // Helper for size computation | 1920 // Helper for size computation |
1859 static int compute_data_size(BytecodeStream* stream); | 1921 static int compute_data_size(BytecodeStream* stream); |
1860 static int bytecode_cell_count(Bytecodes::Code code); | 1922 static int bytecode_cell_count(Bytecodes::Code code); |
1923 static bool is_speculative_trap_bytecode(Bytecodes::Code code); | |
1861 enum { no_profile_data = -1, variable_cell_count = -2 }; | 1924 enum { no_profile_data = -1, variable_cell_count = -2 }; |
1862 | 1925 |
1863 // Helper for initialization | 1926 // Helper for initialization |
1864 DataLayout* data_layout_at(int data_index) const { | 1927 DataLayout* data_layout_at(int data_index) const { |
1865 assert(data_index % sizeof(intptr_t) == 0, "unaligned"); | 1928 assert(data_index % sizeof(intptr_t) == 0, "unaligned"); |
1899 } | 1962 } |
1900 | 1963 |
1901 // What is the index of the first data entry? | 1964 // What is the index of the first data entry? |
1902 int first_di() const { return 0; } | 1965 int first_di() const { return 0; } |
1903 | 1966 |
1967 ProfileData* bci_to_extra_data_helper(int bci, Method* m, DataLayout*& dp); | |
1904 // Find or create an extra ProfileData: | 1968 // Find or create an extra ProfileData: |
1905 ProfileData* bci_to_extra_data(int bci, bool create_if_missing); | 1969 ProfileData* bci_to_extra_data(int bci, Method* m, bool create_if_missing); |
1906 | 1970 |
1907 // return the argument info cell | 1971 // return the argument info cell |
1908 ArgInfoData *arg_info(); | 1972 ArgInfoData *arg_info(); |
1909 | 1973 |
1910 enum { | 1974 enum { |
1923 static bool profile_return_for_invoke(methodHandle m, int bci); | 1987 static bool profile_return_for_invoke(methodHandle m, int bci); |
1924 static int profile_parameters_flag(); | 1988 static int profile_parameters_flag(); |
1925 static bool profile_parameters_jsr292_only(); | 1989 static bool profile_parameters_jsr292_only(); |
1926 static bool profile_all_parameters(); | 1990 static bool profile_all_parameters(); |
1927 | 1991 |
1992 void clean_extra_data(BoolObjectClosure* is_alive); | |
1993 void clean_extra_data_helper(DataLayout* dp, int shift, bool reset = false); | |
1994 void verify_extra_data_clean(BoolObjectClosure* is_alive); | |
1995 | |
1928 public: | 1996 public: |
1929 static int header_size() { | 1997 static int header_size() { |
1930 return sizeof(MethodData)/wordSize; | 1998 return sizeof(MethodData)/wordSize; |
1931 } | 1999 } |
1932 | 2000 |
1933 // Compute the size of a MethodData* before it is created. | 2001 // Compute the size of a MethodData* before it is created. |
1934 static int compute_allocation_size_in_bytes(methodHandle method); | 2002 static int compute_allocation_size_in_bytes(methodHandle method); |
1935 static int compute_allocation_size_in_words(methodHandle method); | 2003 static int compute_allocation_size_in_words(methodHandle method); |
1936 static int compute_extra_data_count(int data_size, int empty_bc_count); | 2004 static int compute_extra_data_count(int data_size, int empty_bc_count, bool needs_speculative_traps); |
1937 | 2005 |
1938 // Determine if a given bytecode can have profile information. | 2006 // Determine if a given bytecode can have profile information. |
1939 static bool bytecode_has_profile(Bytecodes::Code code) { | 2007 static bool bytecode_has_profile(Bytecodes::Code code) { |
1940 return bytecode_cell_count(code) != no_profile_data; | 2008 return bytecode_cell_count(code) != no_profile_data; |
1941 } | 2009 } |
2072 | 2140 |
2073 // Get the data at an arbitrary bci, or NULL if there is none. | 2141 // Get the data at an arbitrary bci, or NULL if there is none. |
2074 ProfileData* bci_to_data(int bci); | 2142 ProfileData* bci_to_data(int bci); |
2075 | 2143 |
2076 // Same, but try to create an extra_data record if one is needed: | 2144 // Same, but try to create an extra_data record if one is needed: |
2077 ProfileData* allocate_bci_to_data(int bci) { | 2145 ProfileData* allocate_bci_to_data(int bci, Method* m) { |
2078 ProfileData* data = bci_to_data(bci); | 2146 ProfileData* data = NULL; |
2079 return (data != NULL) ? data : bci_to_extra_data(bci, true); | 2147 // If m not NULL, try to allocate a SpeculativeTrapData entry |
2148 if (m == NULL) { | |
2149 data = bci_to_data(bci); | |
2150 } | |
2151 if (data != NULL) { | |
2152 return data; | |
2153 } | |
2154 data = bci_to_extra_data(bci, m, true); | |
2155 if (data != NULL) { | |
2156 return data; | |
2157 } | |
2158 // If SpeculativeTrapData allocation fails try to allocate a | |
2159 // regular entry | |
2160 data = bci_to_data(bci); | |
2161 if (data != NULL) { | |
2162 return data; | |
2163 } | |
2164 return bci_to_extra_data(bci, NULL, true); | |
2080 } | 2165 } |
2081 | 2166 |
2082 // Add a handful of extra data records, for trap tracking. | 2167 // Add a handful of extra data records, for trap tracking. |
2083 DataLayout* extra_data_base() const { return limit_data_position(); } | 2168 DataLayout* extra_data_base() const { return limit_data_position(); } |
2084 DataLayout* extra_data_limit() const { return (DataLayout*)((address)this + size_in_bytes()); } | 2169 DataLayout* extra_data_limit() const { return (DataLayout*)((address)this + size_in_bytes()); } |
2085 int extra_data_size() const { return (address)extra_data_limit() | 2170 int extra_data_size() const { return (address)extra_data_limit() |
2086 - (address)extra_data_base(); } | 2171 - (address)extra_data_base(); } |
2087 static DataLayout* next_extra(DataLayout* dp) { return (DataLayout*)((address)dp + in_bytes(DataLayout::cell_offset(0))); } | 2172 static DataLayout* next_extra(DataLayout* dp); |
2088 | 2173 |
2089 // Return (uint)-1 for overflow. | 2174 // Return (uint)-1 for overflow. |
2090 uint trap_count(int reason) const { | 2175 uint trap_count(int reason) const { |
2091 assert((uint)reason < _trap_hist_limit, "oob"); | 2176 assert((uint)reason < _trap_hist_limit, "oob"); |
2092 return (int)((_trap_hist._array[reason]+1) & _trap_hist_mask) - 1; | 2177 return (int)((_trap_hist._array[reason]+1) & _trap_hist_mask) - 1; |
2182 static bool profile_parameters_for_method(methodHandle m); | 2267 static bool profile_parameters_for_method(methodHandle m); |
2183 static bool profile_arguments(); | 2268 static bool profile_arguments(); |
2184 static bool profile_return(); | 2269 static bool profile_return(); |
2185 static bool profile_parameters(); | 2270 static bool profile_parameters(); |
2186 static bool profile_return_jsr292_only(); | 2271 static bool profile_return_jsr292_only(); |
2272 | |
2273 void clean_method_data(BoolObjectClosure* is_alive); | |
2187 }; | 2274 }; |
2188 | 2275 |
2189 #endif // SHARE_VM_OOPS_METHODDATAOOP_HPP | 2276 #endif // SHARE_VM_OOPS_METHODDATAOOP_HPP |