117 ret_data_tag, |
117 ret_data_tag, |
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 }; |
124 }; |
124 |
125 |
125 enum { |
126 enum { |
126 // The _struct._flags word is formatted as [trap_state:4 | flags:4]. |
127 // The _struct._flags word is formatted as [trap_state:4 | flags:4]. |
127 // The trap state breaks down further as [recompile:1 | reason:3]. |
128 // The trap state breaks down further as [recompile:1 | reason:3]. |
395 virtual bool is_ArrayData() const { return false; } |
397 virtual bool is_ArrayData() const { return false; } |
396 virtual bool is_MultiBranchData() const { return false; } |
398 virtual bool is_MultiBranchData() const { return false; } |
397 virtual bool is_ArgInfoData() const { return false; } |
399 virtual bool is_ArgInfoData() const { return false; } |
398 virtual bool is_CallTypeData() const { return false; } |
400 virtual bool is_CallTypeData() const { return false; } |
399 virtual bool is_VirtualCallTypeData()const { return false; } |
401 virtual bool is_VirtualCallTypeData()const { return false; } |
|
402 virtual bool is_ParametersTypeData() const { return false; } |
400 |
403 |
401 |
404 |
402 BitData* as_BitData() const { |
405 BitData* as_BitData() const { |
403 assert(is_BitData(), "wrong type"); |
406 assert(is_BitData(), "wrong type"); |
404 return is_BitData() ? (BitData*) this : NULL; |
407 return is_BitData() ? (BitData*) this : NULL; |
444 return is_CallTypeData() ? (CallTypeData*)this : NULL; |
447 return is_CallTypeData() ? (CallTypeData*)this : NULL; |
445 } |
448 } |
446 VirtualCallTypeData* as_VirtualCallTypeData() const { |
449 VirtualCallTypeData* as_VirtualCallTypeData() const { |
447 assert(is_VirtualCallTypeData(), "wrong type"); |
450 assert(is_VirtualCallTypeData(), "wrong type"); |
448 return is_VirtualCallTypeData() ? (VirtualCallTypeData*)this : NULL; |
451 return is_VirtualCallTypeData() ? (VirtualCallTypeData*)this : NULL; |
|
452 } |
|
453 ParametersTypeData* as_ParametersTypeData() const { |
|
454 assert(is_ParametersTypeData(), "wrong type"); |
|
455 return is_ParametersTypeData() ? (ParametersTypeData*)this : NULL; |
449 } |
456 } |
450 |
457 |
451 |
458 |
452 // Subclass specific initialization |
459 // Subclass specific initialization |
453 virtual void post_initialize(BytecodeStream* stream, MethodData* mdo) {} |
460 virtual void post_initialize(BytecodeStream* stream, MethodData* mdo) {} |
765 public: |
772 public: |
766 |
773 |
767 TypeStackSlotEntries(int base_off, int nb_entries) |
774 TypeStackSlotEntries(int base_off, int nb_entries) |
768 : TypeEntries(base_off), _number_of_entries(nb_entries) {} |
775 : TypeEntries(base_off), _number_of_entries(nb_entries) {} |
769 |
776 |
770 static int compute_cell_count(Symbol* signature, int max); |
777 static int compute_cell_count(Symbol* signature, bool include_receiver, int max); |
771 |
778 |
772 void post_initialize(Symbol* signature, bool has_receiver); |
779 void post_initialize(Symbol* signature, bool has_receiver, bool include_receiver); |
773 |
780 |
774 // offset of cell for stack slot for entry i within this block of cells for a TypeStackSlotEntries |
781 // offset of cell for stack slot for entry i within this block of cells for a TypeStackSlotEntries |
775 static int stack_slot_local_offset(int i) { |
782 static int stack_slot_local_offset(int i) { |
776 return i * per_arg_cell_count + stack_slot_entry; |
783 return i * per_arg_cell_count + stack_slot_entry; |
777 } |
784 } |
944 |
951 |
945 void check_number_of_arguments(int total) { |
952 void check_number_of_arguments(int total) { |
946 assert(number_of_arguments() == total, "should be set in DataLayout::initialize"); |
953 assert(number_of_arguments() == total, "should be set in DataLayout::initialize"); |
947 } |
954 } |
948 |
955 |
949 protected: |
|
950 // An entry for a return value takes less space than an entry for an |
|
951 // argument so if the number of cells exceeds the number of cells |
|
952 // needed for an argument, this object contains type information for |
|
953 // at least one argument. |
|
954 bool has_arguments() const { |
|
955 bool res = cell_count_no_header() >= TypeStackSlotEntries::per_arg_count(); |
|
956 assert (!res || TypeEntriesAtCall::arguments_profiling_enabled(), "no profiling of arguments"); |
|
957 return res; |
|
958 } |
|
959 |
|
960 public: |
956 public: |
961 CallTypeData(DataLayout* layout) : |
957 CallTypeData(DataLayout* layout) : |
962 CounterData(layout), |
958 CounterData(layout), |
963 _args(CounterData::static_cell_count()+TypeEntriesAtCall::header_cell_count(), number_of_arguments()), |
959 _args(CounterData::static_cell_count()+TypeEntriesAtCall::header_cell_count(), number_of_arguments()), |
964 _ret(cell_count() - ReturnTypeEntry::static_cell_count()) |
960 _ret(cell_count() - ReturnTypeEntry::static_cell_count()) |
1013 |
1009 |
1014 void set_return_type(Klass* k) { |
1010 void set_return_type(Klass* k) { |
1015 assert(has_return(), "no return!"); |
1011 assert(has_return(), "no return!"); |
1016 intptr_t current = _ret.type(); |
1012 intptr_t current = _ret.type(); |
1017 _ret.set_type(TypeEntries::with_status(k, current)); |
1013 _ret.set_type(TypeEntries::with_status(k, current)); |
|
1014 } |
|
1015 |
|
1016 // An entry for a return value takes less space than an entry for an |
|
1017 // argument so if the number of cells exceeds the number of cells |
|
1018 // needed for an argument, this object contains type information for |
|
1019 // at least one argument. |
|
1020 bool has_arguments() const { |
|
1021 bool res = cell_count_no_header() >= TypeStackSlotEntries::per_arg_count(); |
|
1022 assert (!res || TypeEntriesAtCall::arguments_profiling_enabled(), "no profiling of arguments"); |
|
1023 return res; |
1018 } |
1024 } |
1019 |
1025 |
1020 // An entry for a return value takes less space than an entry for an |
1026 // An entry for a return value takes less space than an entry for an |
1021 // argument, so if the remainder of the number of cells divided by |
1027 // argument, so if the remainder of the number of cells divided by |
1022 // the number of cells for an argument is not null, a return value |
1028 // the number of cells for an argument is not null, a return value |
1211 |
1217 |
1212 void check_number_of_arguments(int total) { |
1218 void check_number_of_arguments(int total) { |
1213 assert(number_of_arguments() == total, "should be set in DataLayout::initialize"); |
1219 assert(number_of_arguments() == total, "should be set in DataLayout::initialize"); |
1214 } |
1220 } |
1215 |
1221 |
1216 protected: |
|
1217 // An entry for a return value takes less space than an entry for an |
|
1218 // argument so if the number of cells exceeds the number of cells |
|
1219 // needed for an argument, this object contains type information for |
|
1220 // at least one argument. |
|
1221 bool has_arguments() const { |
|
1222 bool res = cell_count_no_header() >= TypeStackSlotEntries::per_arg_count(); |
|
1223 assert (!res || TypeEntriesAtCall::arguments_profiling_enabled(), "no profiling of arguments"); |
|
1224 return res; |
|
1225 } |
|
1226 |
|
1227 public: |
1222 public: |
1228 VirtualCallTypeData(DataLayout* layout) : |
1223 VirtualCallTypeData(DataLayout* layout) : |
1229 VirtualCallData(layout), |
1224 VirtualCallData(layout), |
1230 _args(VirtualCallData::static_cell_count()+TypeEntriesAtCall::header_cell_count(), number_of_arguments()), |
1225 _args(VirtualCallData::static_cell_count()+TypeEntriesAtCall::header_cell_count(), number_of_arguments()), |
1231 _ret(cell_count() - ReturnTypeEntry::static_cell_count()) |
1226 _ret(cell_count() - ReturnTypeEntry::static_cell_count()) |
1289 // the number of cells for an argument is not null, a return value |
1284 // the number of cells for an argument is not null, a return value |
1290 // is profiled in this object. |
1285 // is profiled in this object. |
1291 bool has_return() const { |
1286 bool has_return() const { |
1292 bool res = (cell_count_no_header() % TypeStackSlotEntries::per_arg_count()) != 0; |
1287 bool res = (cell_count_no_header() % TypeStackSlotEntries::per_arg_count()) != 0; |
1293 assert (!res || TypeEntriesAtCall::return_profiling_enabled(), "no profiling of return values"); |
1288 assert (!res || TypeEntriesAtCall::return_profiling_enabled(), "no profiling of return values"); |
|
1289 return res; |
|
1290 } |
|
1291 |
|
1292 // An entry for a return value takes less space than an entry for an |
|
1293 // argument so if the number of cells exceeds the number of cells |
|
1294 // needed for an argument, this object contains type information for |
|
1295 // at least one argument. |
|
1296 bool has_arguments() const { |
|
1297 bool res = cell_count_no_header() >= TypeStackSlotEntries::per_arg_count(); |
|
1298 assert (!res || TypeEntriesAtCall::arguments_profiling_enabled(), "no profiling of arguments"); |
1294 return res; |
1299 return res; |
1295 } |
1300 } |
1296 |
1301 |
1297 // Code generation support |
1302 // Code generation support |
1298 static ByteSize args_data_offset() { |
1303 static ByteSize args_data_offset() { |
1658 } |
1663 } |
1659 |
1664 |
1660 #ifndef PRODUCT |
1665 #ifndef PRODUCT |
1661 void print_data_on(outputStream* st) const; |
1666 void print_data_on(outputStream* st) const; |
1662 #endif |
1667 #endif |
|
1668 }; |
|
1669 |
|
1670 // ParametersTypeData |
|
1671 // |
|
1672 // A ParametersTypeData is used to access profiling information about |
|
1673 // types of parameters to a method |
|
1674 class ParametersTypeData : public ArrayData { |
|
1675 |
|
1676 private: |
|
1677 TypeStackSlotEntries _parameters; |
|
1678 |
|
1679 static int stack_slot_local_offset(int i) { |
|
1680 assert_profiling_enabled(); |
|
1681 return array_start_off_set + TypeStackSlotEntries::stack_slot_local_offset(i); |
|
1682 } |
|
1683 |
|
1684 static int type_local_offset(int i) { |
|
1685 assert_profiling_enabled(); |
|
1686 return array_start_off_set + TypeStackSlotEntries::type_local_offset(i); |
|
1687 } |
|
1688 |
|
1689 static bool profiling_enabled(); |
|
1690 static void assert_profiling_enabled() { |
|
1691 assert(profiling_enabled(), "method parameters profiling should be on"); |
|
1692 } |
|
1693 |
|
1694 public: |
|
1695 ParametersTypeData(DataLayout* layout) : ArrayData(layout), _parameters(1, number_of_parameters()) { |
|
1696 assert(layout->tag() == DataLayout::parameters_type_data_tag, "wrong type"); |
|
1697 // Some compilers (VC++) don't want this passed in member initialization list |
|
1698 _parameters.set_profile_data(this); |
|
1699 } |
|
1700 |
|
1701 static int compute_cell_count(Method* m); |
|
1702 |
|
1703 virtual bool is_ParametersTypeData() const { return true; } |
|
1704 |
|
1705 virtual void post_initialize(BytecodeStream* stream, MethodData* mdo); |
|
1706 |
|
1707 int number_of_parameters() const { |
|
1708 return array_len() / TypeStackSlotEntries::per_arg_count(); |
|
1709 } |
|
1710 |
|
1711 const TypeStackSlotEntries* parameters() const { return &_parameters; } |
|
1712 |
|
1713 uint stack_slot(int i) const { |
|
1714 return _parameters.stack_slot(i); |
|
1715 } |
|
1716 |
|
1717 void set_type(int i, Klass* k) { |
|
1718 intptr_t current = _parameters.type(i); |
|
1719 _parameters.set_type(i, TypeEntries::with_status((intptr_t)k, current)); |
|
1720 } |
|
1721 |
|
1722 virtual void clean_weak_klass_links(BoolObjectClosure* is_alive_closure) { |
|
1723 _parameters.clean_weak_klass_links(is_alive_closure); |
|
1724 } |
|
1725 |
|
1726 #ifndef PRODUCT |
|
1727 virtual void print_data_on(outputStream* st) const; |
|
1728 #endif |
|
1729 |
|
1730 static ByteSize stack_slot_offset(int i) { |
|
1731 return cell_offset(stack_slot_local_offset(i)); |
|
1732 } |
|
1733 |
|
1734 static ByteSize type_offset(int i) { |
|
1735 return cell_offset(type_local_offset(i)); |
|
1736 } |
1663 }; |
1737 }; |
1664 |
1738 |
1665 // MethodData* |
1739 // MethodData* |
1666 // |
1740 // |
1667 // A MethodData* holds information which has been collected about |
1741 // A MethodData* holds information which has been collected about |
1771 bool _would_profile; |
1845 bool _would_profile; |
1772 |
1846 |
1773 // Size of _data array in bytes. (Excludes header and extra_data fields.) |
1847 // Size of _data array in bytes. (Excludes header and extra_data fields.) |
1774 int _data_size; |
1848 int _data_size; |
1775 |
1849 |
|
1850 // data index for the area dedicated to parameters. -1 if no |
|
1851 // parameter profiling. |
|
1852 int _parameters_type_data_di; |
|
1853 |
1776 // Beginning of the data entries |
1854 // Beginning of the data entries |
1777 intptr_t _data[1]; |
1855 intptr_t _data[1]; |
1778 |
1856 |
1779 // Helper for size computation |
1857 // Helper for size computation |
1780 static int compute_data_size(BytecodeStream* stream); |
1858 static int compute_data_size(BytecodeStream* stream); |
1840 static bool profile_all_arguments(); |
1918 static bool profile_all_arguments(); |
1841 static bool profile_arguments_for_invoke(methodHandle m, int bci); |
1919 static bool profile_arguments_for_invoke(methodHandle m, int bci); |
1842 static int profile_return_flag(); |
1920 static int profile_return_flag(); |
1843 static bool profile_all_return(); |
1921 static bool profile_all_return(); |
1844 static bool profile_return_for_invoke(methodHandle m, int bci); |
1922 static bool profile_return_for_invoke(methodHandle m, int bci); |
|
1923 static int profile_parameters_flag(); |
|
1924 static bool profile_parameters_jsr292_only(); |
|
1925 static bool profile_all_parameters(); |
1845 |
1926 |
1846 public: |
1927 public: |
1847 static int header_size() { |
1928 static int header_size() { |
1848 return sizeof(MethodData)/wordSize; |
1929 return sizeof(MethodData)/wordSize; |
1849 } |
1930 } |
2046 if (decompile_count() > (uint)PerMethodRecompilationCutoff) { |
2127 if (decompile_count() > (uint)PerMethodRecompilationCutoff) { |
2047 method()->set_not_compilable(CompLevel_full_optimization, true, "decompile_count > PerMethodRecompilationCutoff"); |
2128 method()->set_not_compilable(CompLevel_full_optimization, true, "decompile_count > PerMethodRecompilationCutoff"); |
2048 } |
2129 } |
2049 } |
2130 } |
2050 |
2131 |
|
2132 // Return pointer to area dedicated to parameters in MDO |
|
2133 ParametersTypeData* parameters_type_data() const { |
|
2134 return _parameters_type_data_di != -1 ? data_layout_at(_parameters_type_data_di)->data_in()->as_ParametersTypeData() : NULL; |
|
2135 } |
|
2136 |
|
2137 int parameters_type_data_di() const { |
|
2138 assert(_parameters_type_data_di != -1, "no args type data"); |
|
2139 return _parameters_type_data_di; |
|
2140 } |
|
2141 |
2051 // Support for code generation |
2142 // Support for code generation |
2052 static ByteSize data_offset() { |
2143 static ByteSize data_offset() { |
2053 return byte_offset_of(MethodData, _data[0]); |
2144 return byte_offset_of(MethodData, _data[0]); |
2054 } |
2145 } |
2055 |
2146 |
2056 static ByteSize invocation_counter_offset() { |
2147 static ByteSize invocation_counter_offset() { |
2057 return byte_offset_of(MethodData, _invocation_counter); |
2148 return byte_offset_of(MethodData, _invocation_counter); |
2058 } |
2149 } |
2059 static ByteSize backedge_counter_offset() { |
2150 static ByteSize backedge_counter_offset() { |
2060 return byte_offset_of(MethodData, _backedge_counter); |
2151 return byte_offset_of(MethodData, _backedge_counter); |
|
2152 } |
|
2153 |
|
2154 static ByteSize parameters_type_data_di_offset() { |
|
2155 return byte_offset_of(MethodData, _parameters_type_data_di); |
2061 } |
2156 } |
2062 |
2157 |
2063 // Deallocation support - no pointer fields to deallocate |
2158 // Deallocation support - no pointer fields to deallocate |
2064 void deallocate_contents(ClassLoaderData* loader_data) {} |
2159 void deallocate_contents(ClassLoaderData* loader_data) {} |
2065 |
2160 |
2081 |
2176 |
2082 // verification |
2177 // verification |
2083 void verify_on(outputStream* st); |
2178 void verify_on(outputStream* st); |
2084 void verify_data_on(outputStream* st); |
2179 void verify_data_on(outputStream* st); |
2085 |
2180 |
|
2181 static bool profile_parameters_for_method(methodHandle m); |
2086 static bool profile_arguments(); |
2182 static bool profile_arguments(); |
2087 static bool profile_return(); |
2183 static bool profile_return(); |
|
2184 static bool profile_parameters(); |
2088 static bool profile_return_jsr292_only(); |
2185 static bool profile_return_jsr292_only(); |
2089 }; |
2186 }; |
2090 |
2187 |
2091 #endif // SHARE_VM_OOPS_METHODDATAOOP_HPP |
2188 #endif // SHARE_VM_OOPS_METHODDATAOOP_HPP |