Mercurial > hg > truffle
comparison src/share/vm/oops/methodData.hpp @ 12882:ce0cc25bc5e2
8026054: New type profiling points: type of return values at calls
Summary: x86 interpreter and c1 type profiling for return values at calls
Reviewed-by: kvn, twisti
author | roland |
---|---|
date | Sat, 12 Oct 2013 12:12:59 +0200 |
parents | d13d7aba8c12 |
children | 5ccbab1c69f3 |
comparison
equal
deleted
inserted
replaced
12881:ed2c74787eb5 | 12882:ce0cc25bc5e2 |
---|---|
269 // | 269 // |
270 // A ProfileData object is created to refer to a section of profiling | 270 // A ProfileData object is created to refer to a section of profiling |
271 // data in a structured way. | 271 // data in a structured way. |
272 class ProfileData : public ResourceObj { | 272 class ProfileData : public ResourceObj { |
273 friend class TypeEntries; | 273 friend class TypeEntries; |
274 friend class ReturnTypeEntry; | |
274 friend class TypeStackSlotEntries; | 275 friend class TypeStackSlotEntries; |
275 private: | 276 private: |
276 #ifndef PRODUCT | 277 #ifndef PRODUCT |
277 enum { | 278 enum { |
278 tab_width_one = 16, | 279 tab_width_one = 16, |
746 stack_slot_entry, | 747 stack_slot_entry, |
747 type_entry, | 748 type_entry, |
748 per_arg_cell_count | 749 per_arg_cell_count |
749 }; | 750 }; |
750 | 751 |
751 // Start with a header if needed. It stores the number of cells used | |
752 // for this call type information. Unless we collect only profiling | |
753 // for a single argument the number of cells is unknown statically. | |
754 static int header_cell_count() { | |
755 return (TypeProfileArgsLimit > 1) ? 1 : 0; | |
756 } | |
757 | |
758 static int cell_count_local_offset() { | |
759 assert(arguments_profiling_enabled() && TypeProfileArgsLimit > 1, "no cell count"); | |
760 return 0; | |
761 } | |
762 | |
763 int cell_count_global_offset() const { | |
764 return _base_off + cell_count_local_offset(); | |
765 } | |
766 | |
767 // offset of cell for stack slot for entry i within ProfileData object | 752 // offset of cell for stack slot for entry i within ProfileData object |
768 int stack_slot_global_offset(int i) const { | 753 int stack_slot_offset(int i) const { |
769 return _base_off + stack_slot_local_offset(i); | 754 return _base_off + stack_slot_local_offset(i); |
770 } | 755 } |
771 | 756 |
772 void check_number_of_arguments(int total) { | |
773 assert(number_of_arguments() == total, "should be set in DataLayout::initialize"); | |
774 } | |
775 | |
776 // number of cells not counting the header | |
777 int cell_count_no_header() const { | |
778 return _pd->uint_at(cell_count_global_offset()); | |
779 } | |
780 | |
781 static bool arguments_profiling_enabled(); | |
782 static void assert_arguments_profiling_enabled() { | |
783 assert(arguments_profiling_enabled(), "args profiling should be on"); | |
784 } | |
785 | |
786 protected: | 757 protected: |
758 const int _number_of_entries; | |
787 | 759 |
788 // offset of cell for type for entry i within ProfileData object | 760 // offset of cell for type for entry i within ProfileData object |
789 int type_global_offset(int i) const { | 761 int type_offset(int i) const { |
790 return _base_off + type_local_offset(i); | 762 return _base_off + type_local_offset(i); |
791 } | 763 } |
792 | 764 |
793 public: | 765 public: |
794 | 766 |
795 TypeStackSlotEntries(int base_off) | 767 TypeStackSlotEntries(int base_off, int nb_entries) |
796 : TypeEntries(base_off) {} | 768 : TypeEntries(base_off), _number_of_entries(nb_entries) {} |
797 | 769 |
798 static int compute_cell_count(BytecodeStream* stream); | 770 static int compute_cell_count(Symbol* signature, int max); |
799 | 771 |
800 static void initialize(DataLayout* dl, int base, int cell_count) { | 772 void post_initialize(Symbol* signature, bool has_receiver); |
801 if (TypeProfileArgsLimit > 1) { | |
802 int off = base + cell_count_local_offset(); | |
803 dl->set_cell_at(off, cell_count - base - header_cell_count()); | |
804 } | |
805 } | |
806 | |
807 void post_initialize(BytecodeStream* stream); | |
808 | |
809 int number_of_arguments() const { | |
810 assert_arguments_profiling_enabled(); | |
811 if (TypeProfileArgsLimit > 1) { | |
812 int cell_count = cell_count_no_header(); | |
813 int nb = cell_count / TypeStackSlotEntries::per_arg_count(); | |
814 assert(nb > 0 && nb <= TypeProfileArgsLimit , "only when we profile args"); | |
815 return nb; | |
816 } else { | |
817 assert(TypeProfileArgsLimit == 1, "at least one arg"); | |
818 return 1; | |
819 } | |
820 } | |
821 | |
822 int cell_count() const { | |
823 assert_arguments_profiling_enabled(); | |
824 if (TypeProfileArgsLimit > 1) { | |
825 return _base_off + header_cell_count() + _pd->int_at_unchecked(cell_count_global_offset()); | |
826 } else { | |
827 return _base_off + TypeStackSlotEntries::per_arg_count(); | |
828 } | |
829 } | |
830 | 773 |
831 // offset of cell for stack slot for entry i within this block of cells for a TypeStackSlotEntries | 774 // offset of cell for stack slot for entry i within this block of cells for a TypeStackSlotEntries |
832 static int stack_slot_local_offset(int i) { | 775 static int stack_slot_local_offset(int i) { |
833 assert_arguments_profiling_enabled(); | 776 return i * per_arg_cell_count + stack_slot_entry; |
834 return header_cell_count() + i * per_arg_cell_count + stack_slot_entry; | |
835 } | 777 } |
836 | 778 |
837 // offset of cell for type for entry i within this block of cells for a TypeStackSlotEntries | 779 // offset of cell for type for entry i within this block of cells for a TypeStackSlotEntries |
838 static int type_local_offset(int i) { | 780 static int type_local_offset(int i) { |
839 return header_cell_count() + i * per_arg_cell_count + type_entry; | 781 return i * per_arg_cell_count + type_entry; |
840 } | 782 } |
841 | 783 |
842 // stack slot for entry i | 784 // stack slot for entry i |
843 uint stack_slot(int i) const { | 785 uint stack_slot(int i) const { |
844 assert(i >= 0 && i < number_of_arguments(), "oob"); | 786 assert(i >= 0 && i < _number_of_entries, "oob"); |
845 return _pd->uint_at(stack_slot_global_offset(i)); | 787 return _pd->uint_at(stack_slot_offset(i)); |
846 } | 788 } |
847 | 789 |
848 // set stack slot for entry i | 790 // set stack slot for entry i |
849 void set_stack_slot(int i, uint num) { | 791 void set_stack_slot(int i, uint num) { |
850 assert(i >= 0 && i < number_of_arguments(), "oob"); | 792 assert(i >= 0 && i < _number_of_entries, "oob"); |
851 _pd->set_uint_at(stack_slot_global_offset(i), num); | 793 _pd->set_uint_at(stack_slot_offset(i), num); |
852 } | 794 } |
853 | 795 |
854 // type for entry i | 796 // type for entry i |
855 intptr_t type(int i) const { | 797 intptr_t type(int i) const { |
856 assert(i >= 0 && i < number_of_arguments(), "oob"); | 798 assert(i >= 0 && i < _number_of_entries, "oob"); |
857 return _pd->intptr_at(type_global_offset(i)); | 799 return _pd->intptr_at(type_offset(i)); |
858 } | 800 } |
859 | 801 |
860 // set type for entry i | 802 // set type for entry i |
861 void set_type(int i, intptr_t k) { | 803 void set_type(int i, intptr_t k) { |
862 assert(i >= 0 && i < number_of_arguments(), "oob"); | 804 assert(i >= 0 && i < _number_of_entries, "oob"); |
863 _pd->set_intptr_at(type_global_offset(i), k); | 805 _pd->set_intptr_at(type_offset(i), k); |
864 } | 806 } |
865 | 807 |
866 static ByteSize per_arg_size() { | 808 static ByteSize per_arg_size() { |
867 return in_ByteSize(per_arg_cell_count * DataLayout::cell_size); | 809 return in_ByteSize(per_arg_cell_count * DataLayout::cell_size); |
868 } | 810 } |
869 | 811 |
870 static int per_arg_count() { | 812 static int per_arg_count() { |
871 return per_arg_cell_count ; | 813 return per_arg_cell_count ; |
872 } | 814 } |
873 | |
874 // Code generation support | |
875 static ByteSize cell_count_offset() { | |
876 return in_ByteSize(cell_count_local_offset() * DataLayout::cell_size); | |
877 } | |
878 | |
879 static ByteSize args_data_offset() { | |
880 return in_ByteSize(header_cell_count() * DataLayout::cell_size); | |
881 } | |
882 | |
883 static ByteSize stack_slot_offset(int i) { | |
884 return in_ByteSize(stack_slot_local_offset(i) * DataLayout::cell_size); | |
885 } | |
886 | |
887 static ByteSize type_offset(int i) { | |
888 return in_ByteSize(type_local_offset(i) * DataLayout::cell_size); | |
889 } | |
890 | 815 |
891 // GC support | 816 // GC support |
892 void clean_weak_klass_links(BoolObjectClosure* is_alive_closure); | 817 void clean_weak_klass_links(BoolObjectClosure* is_alive_closure); |
893 | 818 |
894 #ifndef PRODUCT | 819 #ifndef PRODUCT |
895 void print_data_on(outputStream* st) const; | 820 void print_data_on(outputStream* st) const; |
896 #endif | 821 #endif |
897 }; | 822 }; |
898 | 823 |
824 // Type entry used for return from a call. A single cell to record the | |
825 // type. | |
826 class ReturnTypeEntry : public TypeEntries { | |
827 | |
828 private: | |
829 enum { | |
830 cell_count = 1 | |
831 }; | |
832 | |
833 public: | |
834 ReturnTypeEntry(int base_off) | |
835 : TypeEntries(base_off) {} | |
836 | |
837 void post_initialize() { | |
838 set_type(type_none()); | |
839 } | |
840 | |
841 intptr_t type() const { | |
842 return _pd->intptr_at(_base_off); | |
843 } | |
844 | |
845 void set_type(intptr_t k) { | |
846 _pd->set_intptr_at(_base_off, k); | |
847 } | |
848 | |
849 static int static_cell_count() { | |
850 return cell_count; | |
851 } | |
852 | |
853 static ByteSize size() { | |
854 return in_ByteSize(cell_count * DataLayout::cell_size); | |
855 } | |
856 | |
857 ByteSize type_offset() { | |
858 return DataLayout::cell_offset(_base_off); | |
859 } | |
860 | |
861 // GC support | |
862 void clean_weak_klass_links(BoolObjectClosure* is_alive_closure); | |
863 | |
864 #ifndef PRODUCT | |
865 void print_data_on(outputStream* st) const; | |
866 #endif | |
867 }; | |
868 | |
869 // Entries to collect type information at a call: contains arguments | |
870 // (TypeStackSlotEntries), a return type (ReturnTypeEntry) and a | |
871 // number of cells. Because the number of cells for the return type is | |
872 // smaller than the number of cells for the type of an arguments, the | |
873 // number of cells is used to tell how many arguments are profiled and | |
874 // whether a return value is profiled. See has_arguments() and | |
875 // has_return(). | |
876 class TypeEntriesAtCall { | |
877 private: | |
878 static int stack_slot_local_offset(int i) { | |
879 return header_cell_count() + TypeStackSlotEntries::stack_slot_local_offset(i); | |
880 } | |
881 | |
882 static int argument_type_local_offset(int i) { | |
883 return header_cell_count() + TypeStackSlotEntries::type_local_offset(i);; | |
884 } | |
885 | |
886 public: | |
887 | |
888 static int header_cell_count() { | |
889 return 1; | |
890 } | |
891 | |
892 static int cell_count_local_offset() { | |
893 return 0; | |
894 } | |
895 | |
896 static int compute_cell_count(BytecodeStream* stream); | |
897 | |
898 static void initialize(DataLayout* dl, int base, int cell_count) { | |
899 int off = base + cell_count_local_offset(); | |
900 dl->set_cell_at(off, cell_count - base - header_cell_count()); | |
901 } | |
902 | |
903 static bool arguments_profiling_enabled(); | |
904 static bool return_profiling_enabled(); | |
905 | |
906 // Code generation support | |
907 static ByteSize cell_count_offset() { | |
908 return in_ByteSize(cell_count_local_offset() * DataLayout::cell_size); | |
909 } | |
910 | |
911 static ByteSize args_data_offset() { | |
912 return in_ByteSize(header_cell_count() * DataLayout::cell_size); | |
913 } | |
914 | |
915 static ByteSize stack_slot_offset(int i) { | |
916 return in_ByteSize(stack_slot_local_offset(i) * DataLayout::cell_size); | |
917 } | |
918 | |
919 static ByteSize argument_type_offset(int i) { | |
920 return in_ByteSize(argument_type_local_offset(i) * DataLayout::cell_size); | |
921 } | |
922 }; | |
923 | |
899 // CallTypeData | 924 // CallTypeData |
900 // | 925 // |
901 // A CallTypeData is used to access profiling information about a non | 926 // A CallTypeData is used to access profiling information about a non |
902 // virtual call for which we collect type information about arguments. | 927 // virtual call for which we collect type information about arguments |
928 // and return value. | |
903 class CallTypeData : public CounterData { | 929 class CallTypeData : public CounterData { |
904 private: | 930 private: |
931 // entries for arguments if any | |
905 TypeStackSlotEntries _args; | 932 TypeStackSlotEntries _args; |
933 // entry for return type if any | |
934 ReturnTypeEntry _ret; | |
935 | |
936 int cell_count_global_offset() const { | |
937 return CounterData::static_cell_count() + TypeEntriesAtCall::cell_count_local_offset(); | |
938 } | |
939 | |
940 // number of cells not counting the header | |
941 int cell_count_no_header() const { | |
942 return uint_at(cell_count_global_offset()); | |
943 } | |
944 | |
945 void check_number_of_arguments(int total) { | |
946 assert(number_of_arguments() == total, "should be set in DataLayout::initialize"); | |
947 } | |
948 | |
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 } | |
906 | 959 |
907 public: | 960 public: |
908 CallTypeData(DataLayout* layout) : | 961 CallTypeData(DataLayout* layout) : |
909 CounterData(layout), _args(CounterData::static_cell_count()) { | 962 CounterData(layout), |
963 _args(CounterData::static_cell_count()+TypeEntriesAtCall::header_cell_count(), number_of_arguments()), | |
964 _ret(cell_count() - ReturnTypeEntry::static_cell_count()) | |
965 { | |
910 assert(layout->tag() == DataLayout::call_type_data_tag, "wrong type"); | 966 assert(layout->tag() == DataLayout::call_type_data_tag, "wrong type"); |
911 // Some compilers (VC++) don't want this passed in member initialization list | 967 // Some compilers (VC++) don't want this passed in member initialization list |
912 _args.set_profile_data(this); | 968 _args.set_profile_data(this); |
913 } | 969 _ret.set_profile_data(this); |
914 | 970 } |
915 const TypeStackSlotEntries* args() const { return &_args; } | 971 |
972 const TypeStackSlotEntries* args() const { | |
973 assert(has_arguments(), "no profiling of arguments"); | |
974 return &_args; | |
975 } | |
976 | |
977 const ReturnTypeEntry* ret() const { | |
978 assert(has_return(), "no profiling of return value"); | |
979 return &_ret; | |
980 } | |
916 | 981 |
917 virtual bool is_CallTypeData() const { return true; } | 982 virtual bool is_CallTypeData() const { return true; } |
918 | 983 |
919 static int static_cell_count() { | 984 static int static_cell_count() { |
920 return -1; | 985 return -1; |
921 } | 986 } |
922 | 987 |
923 static int compute_cell_count(BytecodeStream* stream) { | 988 static int compute_cell_count(BytecodeStream* stream) { |
924 return CounterData::static_cell_count() + TypeStackSlotEntries::compute_cell_count(stream); | 989 return CounterData::static_cell_count() + TypeEntriesAtCall::compute_cell_count(stream); |
925 } | 990 } |
926 | 991 |
927 static void initialize(DataLayout* dl, int cell_count) { | 992 static void initialize(DataLayout* dl, int cell_count) { |
928 TypeStackSlotEntries::initialize(dl, CounterData::static_cell_count(), cell_count); | 993 TypeEntriesAtCall::initialize(dl, CounterData::static_cell_count(), cell_count); |
929 } | 994 } |
930 | 995 |
931 virtual void post_initialize(BytecodeStream* stream, MethodData* mdo) { | 996 virtual void post_initialize(BytecodeStream* stream, MethodData* mdo); |
932 _args.post_initialize(stream); | |
933 } | |
934 | 997 |
935 virtual int cell_count() const { | 998 virtual int cell_count() const { |
936 return _args.cell_count(); | 999 return CounterData::static_cell_count() + |
937 } | 1000 TypeEntriesAtCall::header_cell_count() + |
938 | 1001 int_at_unchecked(cell_count_global_offset()); |
939 uint number_of_arguments() const { | 1002 } |
940 return args()->number_of_arguments(); | 1003 |
1004 int number_of_arguments() const { | |
1005 return cell_count_no_header() / TypeStackSlotEntries::per_arg_count(); | |
941 } | 1006 } |
942 | 1007 |
943 void set_argument_type(int i, Klass* k) { | 1008 void set_argument_type(int i, Klass* k) { |
1009 assert(has_arguments(), "no arguments!"); | |
944 intptr_t current = _args.type(i); | 1010 intptr_t current = _args.type(i); |
945 _args.set_type(i, TypeEntries::with_status(k, current)); | 1011 _args.set_type(i, TypeEntries::with_status(k, current)); |
946 } | 1012 } |
947 | 1013 |
1014 void set_return_type(Klass* k) { | |
1015 assert(has_return(), "no return!"); | |
1016 intptr_t current = _ret.type(); | |
1017 _ret.set_type(TypeEntries::with_status(k, current)); | |
1018 } | |
1019 | |
1020 // 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 | |
1022 // the number of cells for an argument is not null, a return value | |
1023 // is profiled in this object. | |
1024 bool has_return() const { | |
1025 bool res = (cell_count_no_header() % TypeStackSlotEntries::per_arg_count()) != 0; | |
1026 assert (!res || TypeEntriesAtCall::return_profiling_enabled(), "no profiling of return values"); | |
1027 return res; | |
1028 } | |
1029 | |
948 // Code generation support | 1030 // Code generation support |
949 static ByteSize args_data_offset() { | 1031 static ByteSize args_data_offset() { |
950 return cell_offset(CounterData::static_cell_count()) + TypeStackSlotEntries::args_data_offset(); | 1032 return cell_offset(CounterData::static_cell_count()) + TypeEntriesAtCall::args_data_offset(); |
951 } | 1033 } |
952 | 1034 |
953 // GC support | 1035 // GC support |
954 virtual void clean_weak_klass_links(BoolObjectClosure* is_alive_closure) { | 1036 virtual void clean_weak_klass_links(BoolObjectClosure* is_alive_closure) { |
955 _args.clean_weak_klass_links(is_alive_closure); | 1037 if (has_arguments()) { |
1038 _args.clean_weak_klass_links(is_alive_closure); | |
1039 } | |
1040 if (has_return()) { | |
1041 _ret.clean_weak_klass_links(is_alive_closure); | |
1042 } | |
956 } | 1043 } |
957 | 1044 |
958 #ifndef PRODUCT | 1045 #ifndef PRODUCT |
959 virtual void print_data_on(outputStream* st) const; | 1046 virtual void print_data_on(outputStream* st) const; |
960 #endif | 1047 #endif |
1103 | 1190 |
1104 // VirtualCallTypeData | 1191 // VirtualCallTypeData |
1105 // | 1192 // |
1106 // A VirtualCallTypeData is used to access profiling information about | 1193 // A VirtualCallTypeData is used to access profiling information about |
1107 // a virtual call for which we collect type information about | 1194 // a virtual call for which we collect type information about |
1108 // arguments. | 1195 // arguments and return value. |
1109 class VirtualCallTypeData : public VirtualCallData { | 1196 class VirtualCallTypeData : public VirtualCallData { |
1110 private: | 1197 private: |
1198 // entries for arguments if any | |
1111 TypeStackSlotEntries _args; | 1199 TypeStackSlotEntries _args; |
1200 // entry for return type if any | |
1201 ReturnTypeEntry _ret; | |
1202 | |
1203 int cell_count_global_offset() const { | |
1204 return VirtualCallData::static_cell_count() + TypeEntriesAtCall::cell_count_local_offset(); | |
1205 } | |
1206 | |
1207 // number of cells not counting the header | |
1208 int cell_count_no_header() const { | |
1209 return uint_at(cell_count_global_offset()); | |
1210 } | |
1211 | |
1212 void check_number_of_arguments(int total) { | |
1213 assert(number_of_arguments() == total, "should be set in DataLayout::initialize"); | |
1214 } | |
1215 | |
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 } | |
1112 | 1226 |
1113 public: | 1227 public: |
1114 VirtualCallTypeData(DataLayout* layout) : | 1228 VirtualCallTypeData(DataLayout* layout) : |
1115 VirtualCallData(layout), _args(VirtualCallData::static_cell_count()) { | 1229 VirtualCallData(layout), |
1230 _args(VirtualCallData::static_cell_count()+TypeEntriesAtCall::header_cell_count(), number_of_arguments()), | |
1231 _ret(cell_count() - ReturnTypeEntry::static_cell_count()) | |
1232 { | |
1116 assert(layout->tag() == DataLayout::virtual_call_type_data_tag, "wrong type"); | 1233 assert(layout->tag() == DataLayout::virtual_call_type_data_tag, "wrong type"); |
1117 // Some compilers (VC++) don't want this passed in member initialization list | 1234 // Some compilers (VC++) don't want this passed in member initialization list |
1118 _args.set_profile_data(this); | 1235 _args.set_profile_data(this); |
1119 } | 1236 _ret.set_profile_data(this); |
1120 | 1237 } |
1121 const TypeStackSlotEntries* args() const { return &_args; } | 1238 |
1239 const TypeStackSlotEntries* args() const { | |
1240 assert(has_arguments(), "no profiling of arguments"); | |
1241 return &_args; | |
1242 } | |
1243 | |
1244 const ReturnTypeEntry* ret() const { | |
1245 assert(has_return(), "no profiling of return value"); | |
1246 return &_ret; | |
1247 } | |
1122 | 1248 |
1123 virtual bool is_VirtualCallTypeData() const { return true; } | 1249 virtual bool is_VirtualCallTypeData() const { return true; } |
1124 | 1250 |
1125 static int static_cell_count() { | 1251 static int static_cell_count() { |
1126 return -1; | 1252 return -1; |
1127 } | 1253 } |
1128 | 1254 |
1129 static int compute_cell_count(BytecodeStream* stream) { | 1255 static int compute_cell_count(BytecodeStream* stream) { |
1130 return VirtualCallData::static_cell_count() + TypeStackSlotEntries::compute_cell_count(stream); | 1256 return VirtualCallData::static_cell_count() + TypeEntriesAtCall::compute_cell_count(stream); |
1131 } | 1257 } |
1132 | 1258 |
1133 static void initialize(DataLayout* dl, int cell_count) { | 1259 static void initialize(DataLayout* dl, int cell_count) { |
1134 TypeStackSlotEntries::initialize(dl, VirtualCallData::static_cell_count(), cell_count); | 1260 TypeEntriesAtCall::initialize(dl, VirtualCallData::static_cell_count(), cell_count); |
1135 } | 1261 } |
1136 | 1262 |
1137 virtual void post_initialize(BytecodeStream* stream, MethodData* mdo) { | 1263 virtual void post_initialize(BytecodeStream* stream, MethodData* mdo); |
1138 _args.post_initialize(stream); | |
1139 } | |
1140 | 1264 |
1141 virtual int cell_count() const { | 1265 virtual int cell_count() const { |
1142 return _args.cell_count(); | 1266 return VirtualCallData::static_cell_count() + |
1143 } | 1267 TypeEntriesAtCall::header_cell_count() + |
1144 | 1268 int_at_unchecked(cell_count_global_offset()); |
1145 uint number_of_arguments() const { | 1269 } |
1146 return args()->number_of_arguments(); | 1270 |
1271 int number_of_arguments() const { | |
1272 return cell_count_no_header() / TypeStackSlotEntries::per_arg_count(); | |
1147 } | 1273 } |
1148 | 1274 |
1149 void set_argument_type(int i, Klass* k) { | 1275 void set_argument_type(int i, Klass* k) { |
1276 assert(has_arguments(), "no arguments!"); | |
1150 intptr_t current = _args.type(i); | 1277 intptr_t current = _args.type(i); |
1151 _args.set_type(i, TypeEntries::with_status(k, current)); | 1278 _args.set_type(i, TypeEntries::with_status(k, current)); |
1152 } | 1279 } |
1153 | 1280 |
1281 void set_return_type(Klass* k) { | |
1282 assert(has_return(), "no return!"); | |
1283 intptr_t current = _ret.type(); | |
1284 _ret.set_type(TypeEntries::with_status(k, current)); | |
1285 } | |
1286 | |
1287 // An entry for a return value takes less space than an entry for an | |
1288 // argument, so if the remainder of the number of cells divided by | |
1289 // the number of cells for an argument is not null, a return value | |
1290 // is profiled in this object. | |
1291 bool has_return() const { | |
1292 bool res = (cell_count_no_header() % TypeStackSlotEntries::per_arg_count()) != 0; | |
1293 assert (!res || TypeEntriesAtCall::return_profiling_enabled(), "no profiling of return values"); | |
1294 return res; | |
1295 } | |
1296 | |
1154 // Code generation support | 1297 // Code generation support |
1155 static ByteSize args_data_offset() { | 1298 static ByteSize args_data_offset() { |
1156 return cell_offset(VirtualCallData::static_cell_count()) + TypeStackSlotEntries::args_data_offset(); | 1299 return cell_offset(VirtualCallData::static_cell_count()) + TypeEntriesAtCall::args_data_offset(); |
1157 } | 1300 } |
1158 | 1301 |
1159 // GC support | 1302 // GC support |
1160 virtual void clean_weak_klass_links(BoolObjectClosure* is_alive_closure) { | 1303 virtual void clean_weak_klass_links(BoolObjectClosure* is_alive_closure) { |
1161 ReceiverTypeData::clean_weak_klass_links(is_alive_closure); | 1304 ReceiverTypeData::clean_weak_klass_links(is_alive_closure); |
1162 _args.clean_weak_klass_links(is_alive_closure); | 1305 if (has_arguments()) { |
1306 _args.clean_weak_klass_links(is_alive_closure); | |
1307 } | |
1308 if (has_return()) { | |
1309 _ret.clean_weak_klass_links(is_alive_closure); | |
1310 } | |
1163 } | 1311 } |
1164 | 1312 |
1165 #ifndef PRODUCT | 1313 #ifndef PRODUCT |
1166 virtual void print_data_on(outputStream* st) const; | 1314 virtual void print_data_on(outputStream* st) const; |
1167 #endif | 1315 #endif |
1689 static bool profile_jsr292(methodHandle m, int bci); | 1837 static bool profile_jsr292(methodHandle m, int bci); |
1690 static int profile_arguments_flag(); | 1838 static int profile_arguments_flag(); |
1691 static bool profile_arguments_jsr292_only(); | 1839 static bool profile_arguments_jsr292_only(); |
1692 static bool profile_all_arguments(); | 1840 static bool profile_all_arguments(); |
1693 static bool profile_arguments_for_invoke(methodHandle m, int bci); | 1841 static bool profile_arguments_for_invoke(methodHandle m, int bci); |
1842 static int profile_return_flag(); | |
1843 static bool profile_all_return(); | |
1844 static bool profile_return_for_invoke(methodHandle m, int bci); | |
1694 | 1845 |
1695 public: | 1846 public: |
1696 static int header_size() { | 1847 static int header_size() { |
1697 return sizeof(MethodData)/wordSize; | 1848 return sizeof(MethodData)/wordSize; |
1698 } | 1849 } |
1931 // verification | 2082 // verification |
1932 void verify_on(outputStream* st); | 2083 void verify_on(outputStream* st); |
1933 void verify_data_on(outputStream* st); | 2084 void verify_data_on(outputStream* st); |
1934 | 2085 |
1935 static bool profile_arguments(); | 2086 static bool profile_arguments(); |
2087 static bool profile_return(); | |
2088 static bool profile_return_jsr292_only(); | |
1936 }; | 2089 }; |
1937 | 2090 |
1938 #endif // SHARE_VM_OOPS_METHODDATAOOP_HPP | 2091 #endif // SHARE_VM_OOPS_METHODDATAOOP_HPP |