src/share/vm/oops/methodData.hpp
Index Unified diffs Context diffs Sdiffs Patch New Old Previous File Next File hotspot Sdiff src/share/vm/oops

src/share/vm/oops/methodData.hpp

Print this page
rev 5349 : 8023657: New type profiling points: arguments to call
Summary: x86 interpreter and c1 type profiling for arguments at calls
Reviewed-by:
rev 5350 : 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:


 254 class ProfileData;
 255 class   BitData;
 256 class     CounterData;
 257 class       ReceiverTypeData;
 258 class         VirtualCallData;
 259 class           VirtualCallTypeData;
 260 class       RetData;
 261 class       CallTypeData;
 262 class   JumpData;
 263 class     BranchData;
 264 class   ArrayData;
 265 class     MultiBranchData;
 266 class     ArgInfoData;
 267 
 268 // ProfileData
 269 //
 270 // A ProfileData object is created to refer to a section of profiling
 271 // data in a structured way.
 272 class ProfileData : public ResourceObj {
 273   friend class TypeEntries;


 274   friend class TypeStackSlotEntries;
 275 private:
 276 #ifndef PRODUCT
 277   enum {
 278     tab_width_one = 16,
 279     tab_width_two = 36
 280   };
 281 #endif // !PRODUCT
 282 
 283   // This is a pointer to a section of profiling data.
 284   DataLayout* _data;
 285 
 286 protected:
 287   DataLayout* data() { return _data; }
 288   const DataLayout* data() const { return _data; }
 289 
 290   enum {
 291     cell_size = DataLayout::cell_size
 292   };
 293 


 726 
 727   intptr_t intptr_at(int index) const {
 728     return _pd->intptr_at(index);
 729   }
 730 };
 731 
 732 // Type entries used for arguments passed at a call and parameters on
 733 // method entry. 2 cells per entry: one for the type encoded as in
 734 // TypeEntries and one initialized with the stack slot where the
 735 // profiled object is to be found so that the interpreter can locate
 736 // it quickly.
 737 class TypeStackSlotEntries : public TypeEntries {
 738 
 739 private:
 740   enum {
 741     stack_slot_entry,
 742     type_entry,
 743     per_arg_cell_count
 744   };
 745 


















































































































































 746   // Start with a header if needed. It stores the number of cells used
 747   // for this call type information. Unless we collect only profiling
 748   // for a single argument the number of cells is unknown statically.

 749   static int header_cell_count() {
 750     return (TypeProfileArgsLimit > 1) ? 1 : 0;
 751   }
 752 
 753   static int cell_count_local_offset() {
 754      assert(arguments_profiling_enabled() && TypeProfileArgsLimit > 1, "no cell count");
 755      return 0;
 756    }
 757 
 758   int cell_count_global_offset() const {
 759     return _base_off + cell_count_local_offset();
 760   }
 761   
 762   // offset of cell for stack slot for entry i within ProfileData object
 763   int stack_slot_global_offset(int i) const {
 764     return _base_off + stack_slot_local_offset(i);





 765   }
 766 
 767   void check_number_of_arguments(uint total) {
 768     assert(number_of_arguments() == total, "should be set in DataLayout::initialize");
 769   }
 770 
 771   // number of cells not counting the header
 772   int cell_count_no_header() const {
 773     return _pd->uint_at(cell_count_global_offset());
 774   }
 775 
 776   static bool arguments_profiling_enabled();
 777   static void assert_arguments_profiling_enabled() {
 778     assert(arguments_profiling_enabled(), "args profiling should be on");
 779   }






 780 
 781 protected:
 782 
 783   // offset of cell for type for entry i within ProfileData object
 784   int type_global_offset(int i) const {
 785     return _base_off + type_local_offset(i);







 786   }
 787 
 788 public:
 789 
 790   TypeStackSlotEntries(int base_off, ProfileData* pd)
 791     : TypeEntries(base_off, pd) {}


 792 
 793   static int compute_cell_count(BytecodeStream* stream);
 794 
 795   static void initialize(DataLayout* dl, int base, int cell_count) {
 796     if (TypeProfileArgsLimit > 1) {
 797       int off = base + cell_count_local_offset();
 798       dl->set_cell_at(off, cell_count - base - header_cell_count());
 799     }
 800   }
 801 
 802   void post_initialize(BytecodeStream* stream);
 803 
 804   uint number_of_arguments() const {
 805     assert_arguments_profiling_enabled();
 806     if (TypeProfileArgsLimit > 1) {




 807       int cell_count = cell_count_no_header();

 808       int nb = cell_count / TypeStackSlotEntries::per_arg_count();
 809       assert(nb > 0 && nb <= TypeProfileArgsLimit , "only when we profile args");
 810       return nb;
 811     } else {
 812       assert(TypeProfileArgsLimit == 1, "at least one arg");
 813       return 1;
 814     }
 815   }
 816   
 817   int cell_count() const {
 818     assert_arguments_profiling_enabled();
 819     if (TypeProfileArgsLimit > 1) {
 820       return _base_off + header_cell_count() + _pd->int_at_unchecked(cell_count_global_offset());
 821     } else {
 822       return _base_off + TypeStackSlotEntries::per_arg_count();



 823     }
 824   }
 825 
 826   // offset of cell for stack slot for entry i within this block of cells for a TypeStackSlotEntries
 827   static int stack_slot_local_offset(int i) {
 828     assert_arguments_profiling_enabled();
 829     return header_cell_count() + i * per_arg_cell_count + stack_slot_entry;
 830   }
 831 
 832   // offset of cell for type for entry i within this block of cells for a TypeStackSlotEntries
 833   static int type_local_offset(int i) {
 834     return header_cell_count() + i * per_arg_cell_count + type_entry;
 835   }
 836 
 837   // stack slot for entry i
 838   uint stack_slot(int i) const {
 839     assert(i >= 0 && i < number_of_arguments(), "oob");
 840     return _pd->uint_at(stack_slot_global_offset(i));
 841   }
 842 
 843   // set stack slot for entry i
 844   void set_stack_slot(int i, uint num) {
 845     assert(i >= 0 && i < number_of_arguments(), "oob");
 846     _pd->set_uint_at(stack_slot_global_offset(i), num);
 847   }
 848   
 849   // type for entry i
 850   intptr_t type(int i) const {
 851     assert(i >= 0 && i < number_of_arguments(), "oob");
 852     return _pd->intptr_at(type_global_offset(i));
 853   }
 854 
 855   // set type for entry i
 856   void set_type(int i, intptr_t k) {
 857     assert(i >= 0 && i < number_of_arguments(), "oob");
 858     _pd->set_intptr_at(type_global_offset(i), k);



 859   }
 860 
 861   static ByteSize per_arg_size() {
 862     return in_ByteSize(per_arg_cell_count * DataLayout::cell_size);

 863   }
 864 
 865   static int per_arg_count() {
 866     return per_arg_cell_count ;

 867   }
 868 
 869   // Code generation support
 870    static ByteSize cell_count_offset() {
 871      return in_ByteSize(cell_count_local_offset() * DataLayout::cell_size);
 872    }
 873  
 874    static ByteSize args_data_offset() {
 875      return in_ByteSize(header_cell_count() * DataLayout::cell_size);
 876    }
 877  
 878    static ByteSize stack_slot_offset(int i) {
 879      return in_ByteSize(stack_slot_local_offset(i) * DataLayout::cell_size);
 880    }
 881  
 882    static ByteSize type_offset(int i) {
 883      return in_ByteSize(type_local_offset(i) * DataLayout::cell_size);




 884    }
 885 
 886   // GC support
 887   void clean_weak_klass_links(BoolObjectClosure* is_alive_closure);
 888 
 889 #ifndef PRODUCT
 890   void print_data_on(outputStream* st) const;
 891 #endif
 892 };
 893 
 894 // CallTypeData
 895 //
 896 // A CallTypeData is used to access profiling information about a non
 897 // virtual call for which we collect type information about arguments.

 898 class CallTypeData : public CounterData {
 899 private:
 900   TypeStackSlotEntries _args;
 901 
 902 public:
 903   CallTypeData(DataLayout* layout) :
 904     CounterData(layout), _args(CounterData::static_cell_count(), this)  {
 905     assert(layout->tag() == DataLayout::call_type_data_tag, "wrong type");
 906   }
 907 
 908   const TypeStackSlotEntries* args() const { return &_args; }
 909 
 910   virtual bool is_CallTypeData() const { return true; }
 911 
 912   static int static_cell_count() {
 913     return -1;
 914   }
 915 
 916   static int compute_cell_count(BytecodeStream* stream) {
 917     return CounterData::static_cell_count() + TypeStackSlotEntries::compute_cell_count(stream);
 918   }
 919   
 920   static void initialize(DataLayout* dl, int cell_count) {
 921     TypeStackSlotEntries::initialize(dl, CounterData::static_cell_count(), cell_count);
 922   }
 923 
 924   virtual void post_initialize(BytecodeStream* stream, MethodData* mdo) {
 925     _args.post_initialize(stream);
 926   }
 927 
 928   virtual int cell_count() const {
 929     return _args.cell_count();
 930   }
 931 
 932   uint number_of_arguments() const {
 933     return args()->number_of_arguments();
 934   }
 935 
 936   void set_argument_type(int i, Klass* k) {
 937     intptr_t current = _args.type(i);
 938     _args.set_type(i, TypeEntries::with_status(k, current));



 939   }
 940 
 941   // Code generation support
 942   static ByteSize args_data_offset() {
 943     return cell_offset(CounterData::static_cell_count()) + TypeStackSlotEntries::args_data_offset();
 944   }
 945 
 946   // GC support
 947   virtual void clean_weak_klass_links(BoolObjectClosure* is_alive_closure) {
 948     _args.clean_weak_klass_links(is_alive_closure);
 949   }
 950 
 951 #ifndef PRODUCT
 952   virtual void print_data_on(outputStream* st) const;
 953 #endif
 954 };
 955 
 956 // ReceiverTypeData
 957 //
 958 // A ReceiverTypeData is used to access profiling information about a
 959 // dynamic type check.  It consists of a counter which counts the total times
 960 // that the check is reached, and a series of (Klass*, count) pairs
 961 // which are used to store a type profile for the receiver of the check.
 962 class ReceiverTypeData : public CounterData {
 963 protected:
 964   enum {
 965     receiver0_offset = counter_cell_count,
 966     count0_offset,
 967     receiver_type_row_cell_count = (count0_offset + 1) - receiver0_offset
 968   };


1081   }
1082 
1083   virtual int cell_count() const {
1084     return static_cell_count();
1085   }
1086 
1087   // Direct accessors
1088   static ByteSize virtual_call_data_size() {
1089     return cell_offset(static_cell_count());
1090   }
1091 
1092 #ifndef PRODUCT
1093   void print_data_on(outputStream* st) const;
1094 #endif
1095 };
1096 
1097 // VirtualCallTypeData
1098 //
1099 // A VirtualCallTypeData is used to access profiling information about
1100 // a virtual call for which we collect type information about
1101 // arguments.
1102 class VirtualCallTypeData : public VirtualCallData {
1103 private:
1104   TypeStackSlotEntries _args;
1105 
1106 public:
1107   VirtualCallTypeData(DataLayout* layout) :
1108     VirtualCallData(layout), _args(VirtualCallData::static_cell_count(), this)  {
1109     assert(layout->tag() == DataLayout::virtual_call_type_data_tag, "wrong type");
1110   }
1111 
1112   const TypeStackSlotEntries* args() const { return &_args; }
1113 
1114   virtual bool is_VirtualCallTypeData() const { return true; }
1115 
1116   static int static_cell_count() {
1117     return -1;
1118   }
1119 
1120   static int compute_cell_count(BytecodeStream* stream) {
1121     return VirtualCallData::static_cell_count() + TypeStackSlotEntries::compute_cell_count(stream);
1122   }
1123   
1124   static void initialize(DataLayout* dl, int cell_count) {
1125     TypeStackSlotEntries::initialize(dl, VirtualCallData::static_cell_count(), cell_count);
1126   }
1127 
1128   virtual void post_initialize(BytecodeStream* stream, MethodData* mdo) {
1129     _args.post_initialize(stream);
1130   }
1131 
1132   virtual int cell_count() const {
1133     return _args.cell_count();
1134   }
1135 
1136   uint number_of_arguments() const {
1137     return args()->number_of_arguments();
1138   }
1139 
1140   void set_argument_type(int i, Klass* k) {
1141     intptr_t current = _args.type(i);
1142     _args.set_type(i, TypeEntries::with_status(k, current));



1143   }
1144 
1145   // Code generation support
1146   static ByteSize args_data_offset() {
1147     return cell_offset(VirtualCallData::static_cell_count()) + TypeStackSlotEntries::args_data_offset();
1148   }
1149 
1150   // GC support
1151   virtual void clean_weak_klass_links(BoolObjectClosure* is_alive_closure) {
1152     ReceiverTypeData::clean_weak_klass_links(is_alive_closure);
1153     _args.clean_weak_klass_links(is_alive_closure);
1154   }
1155 
1156 #ifndef PRODUCT
1157   virtual void print_data_on(outputStream* st) const;
1158 #endif
1159 };
1160 
1161 // RetData
1162 //
1163 // A RetData is used to access profiling information for a ret bytecode.
1164 // It is composed of a count of the number of times that the ret has
1165 // been executed, followed by a series of triples of the form
1166 // (bci, count, di) which count the number of times that some bci was the
1167 // target of the ret and cache a corresponding data displacement.
1168 class RetData : public CounterData {
1169 protected:
1170   enum {
1171     bci0_offset = counter_cell_count,
1172     count0_offset,
1173     displacement0_offset,


1665   // What is the index of the first data entry?
1666   int first_di() const { return 0; }
1667 
1668   // Find or create an extra ProfileData:
1669   ProfileData* bci_to_extra_data(int bci, bool create_if_missing);
1670 
1671   // return the argument info cell
1672   ArgInfoData *arg_info();
1673 
1674   enum {
1675     no_type_profile = 0,
1676     type_profile_jsr292 = 1,
1677     type_profile_all = 2
1678   };
1679 
1680   static bool profile_jsr292(methodHandle m, int bci);
1681   static int profile_arguments_flag();
1682   static bool profile_arguments_jsr292_only();
1683   static bool profile_all_arguments();
1684   static bool profile_arguments_for_invoke(methodHandle m, int bci);




1685 
1686 public:
1687   static int header_size() {
1688     return sizeof(MethodData)/wordSize;
1689   }
1690 
1691   // Compute the size of a MethodData* before it is created.
1692   static int compute_allocation_size_in_bytes(methodHandle method);
1693   static int compute_allocation_size_in_words(methodHandle method);
1694   static int compute_extra_data_count(int data_size, int empty_bc_count);
1695 
1696   // Determine if a given bytecode can have profile information.
1697   static bool bytecode_has_profile(Bytecodes::Code code) {
1698     return bytecode_cell_count(code) != no_profile_data;
1699   }
1700 
1701   // reset into original state
1702   void init();
1703 
1704   // My size


1907   void set_size(int object_size_in_bytes) { _size = object_size_in_bytes; }
1908 
1909   // Printing
1910 #ifndef PRODUCT
1911   void print_on      (outputStream* st) const;
1912 #endif
1913   void print_value_on(outputStream* st) const;
1914 
1915 #ifndef PRODUCT
1916   // printing support for method data
1917   void print_data_on(outputStream* st) const;
1918 #endif
1919 
1920   const char* internal_name() const { return "{method data}"; }
1921 
1922   // verification
1923   void verify_on(outputStream* st);
1924   void verify_data_on(outputStream* st);
1925 
1926   static bool profile_arguments();

1927 };
1928 
1929 #endif // SHARE_VM_OOPS_METHODDATAOOP_HPP


 254 class ProfileData;
 255 class   BitData;
 256 class     CounterData;
 257 class       ReceiverTypeData;
 258 class         VirtualCallData;
 259 class           VirtualCallTypeData;
 260 class       RetData;
 261 class       CallTypeData;
 262 class   JumpData;
 263 class     BranchData;
 264 class   ArrayData;
 265 class     MultiBranchData;
 266 class     ArgInfoData;
 267 
 268 // ProfileData
 269 //
 270 // A ProfileData object is created to refer to a section of profiling
 271 // data in a structured way.
 272 class ProfileData : public ResourceObj {
 273   friend class TypeEntries;
 274   friend class TypeEntriesAtCall;
 275   friend class ReturnTypeEntry;
 276   friend class TypeStackSlotEntries;
 277 private:
 278 #ifndef PRODUCT
 279   enum {
 280     tab_width_one = 16,
 281     tab_width_two = 36
 282   };
 283 #endif // !PRODUCT
 284 
 285   // This is a pointer to a section of profiling data.
 286   DataLayout* _data;
 287 
 288 protected:
 289   DataLayout* data() { return _data; }
 290   const DataLayout* data() const { return _data; }
 291 
 292   enum {
 293     cell_size = DataLayout::cell_size
 294   };
 295 


 728 
 729   intptr_t intptr_at(int index) const {
 730     return _pd->intptr_at(index);
 731   }
 732 };
 733 
 734 // Type entries used for arguments passed at a call and parameters on
 735 // method entry. 2 cells per entry: one for the type encoded as in
 736 // TypeEntries and one initialized with the stack slot where the
 737 // profiled object is to be found so that the interpreter can locate
 738 // it quickly.
 739 class TypeStackSlotEntries : public TypeEntries {
 740 
 741 private:
 742   enum {
 743     stack_slot_entry,
 744     type_entry,
 745     per_arg_cell_count
 746   };
 747 
 748   // offset of cell for stack slot for entry i within ProfileData object
 749   int stack_slot_offset(int i) const {
 750     return _base_off + stack_slot_local_offset(i);
 751   }
 752 
 753 protected:
 754   const int _nb_entries;
 755 
 756   // offset of cell for type for entry i within ProfileData object
 757   int type_offset(int i) const {
 758     return _base_off + type_local_offset(i);
 759   }
 760 
 761 public:
 762 
 763   TypeStackSlotEntries(int base_off, ProfileData* pd, int nb_entries)
 764     : TypeEntries(base_off, pd), _nb_entries(nb_entries) {}
 765 
 766   static int compute_cell_count(Symbol* signature, int max);
 767 
 768   void post_initialize(Symbol* signature, bool has_receiver);
 769 
 770   // offset of cell for stack slot for entry i within this block of cells for a TypeStackSlotEntries
 771   static int stack_slot_local_offset(int i) {
 772     return i * per_arg_cell_count + stack_slot_entry;
 773   }
 774 
 775   // offset of cell for type for entry i within this block of cells for a TypeStackSlotEntries
 776   static int type_local_offset(int i) {
 777     return i * per_arg_cell_count + type_entry;
 778   }
 779 
 780   // stack slot for entry i
 781   uint stack_slot(int i) const {
 782     assert(i >= 0 && i < _nb_entries, "oob");
 783     return _pd->uint_at(stack_slot_offset(i));
 784   }
 785 
 786   // set stack slot for entry i
 787   void set_stack_slot(int i, uint num) {
 788     assert(i >= 0 && i < _nb_entries, "oob");
 789     _pd->set_uint_at(stack_slot_offset(i), num);
 790   }
 791   
 792   // type for entry i
 793   intptr_t type(int i) const {
 794     assert(i >= 0 && i < _nb_entries, "oob");
 795     return _pd->intptr_at(type_offset(i));
 796   }
 797 
 798   // set type for entry i
 799   void set_type(int i, intptr_t k) {
 800     assert(i >= 0 && i < _nb_entries, "oob");
 801     _pd->set_intptr_at(type_offset(i), k);
 802   }
 803 
 804   static ByteSize per_arg_size() {
 805     return in_ByteSize(per_arg_cell_count * DataLayout::cell_size);
 806   }
 807 
 808   static int per_arg_count() {
 809     return per_arg_cell_count ;
 810   }
 811 
 812   // GC support
 813   void clean_weak_klass_links(BoolObjectClosure* is_alive_closure);
 814 
 815 #ifndef PRODUCT
 816   void print_data_on(outputStream* st) const;
 817 #endif
 818 };
 819 
 820 // Type entry used for return from a call. A single cell to record the
 821 // type.
 822 class ReturnTypeEntry : public TypeEntries {
 823 
 824 private:
 825   enum {
 826     cell_count = 1
 827   };
 828 
 829 public:
 830   ReturnTypeEntry(int base_off, ProfileData* pd)
 831     : TypeEntries(base_off, pd) {}
 832 
 833   void post_initialize() {
 834     set_type(type_none());
 835   }
 836 
 837   intptr_t type() const {
 838     assert_profiling_enabled();
 839     return _pd->intptr_at(_base_off);
 840   }
 841 
 842   void set_type(intptr_t k) {
 843     assert_profiling_enabled();
 844     _pd->set_intptr_at(_base_off, k);
 845   }
 846 
 847   static int static_cell_count() {
 848     assert_profiling_enabled();
 849     return cell_count;
 850   }
 851 
 852   static ByteSize size() {
 853     assert_profiling_enabled();
 854     return in_ByteSize(cell_count * DataLayout::cell_size);
 855   }
 856 
 857   ByteSize type_offset() {
 858     assert_profiling_enabled();
 859     return DataLayout::cell_offset(_base_off);
 860   }
 861 
 862   static bool profiling_enabled();
 863 
 864   static void assert_profiling_enabled() {
 865     assert(profiling_enabled(), "args profiling should be on");
 866   }
 867 
 868   // GC support
 869   void clean_weak_klass_links(BoolObjectClosure* is_alive_closure);
 870 
 871 #ifndef PRODUCT
 872   void print_data_on(outputStream* st) const;
 873 #endif
 874 };
 875 
 876 // Entries to collect type information at a call: contains arguments
 877 // (TypeStackSlotEntries), a return type (ReturnTypeEntry) and a
 878 // number of cells. Because the number of cells for the return type is
 879 // smaller than the number of cells for the type of an arguments, the
 880 // number of cells is used to tell how many arguments are profiled and
 881 // whether a return value is profiled. See has_arguments() and
 882 // has_return().
 883 class TypeEntriesAtCall {
 884 
 885 private:
 886 
 887   // offset within the ProfileData object where the entries start
 888   const int _base_off;
 889   // entries for arguments if any
 890   TypeStackSlotEntries _args;
 891   // entry for return type if any
 892   ReturnTypeEntry _ret;
 893 
 894   // Start with a header if needed. It stores the number of cells used
 895   // for this call type information. Unless we collect only return
 896   // type profiling or only profiling for a single argument the number
 897   // of cells is unknown statically.
 898   static int header_cell_count() {
 899     return (arguments_profiling_enabled() && (TypeProfileArgsLimit > 1 || return_profiling_enabled())) ? 1 : 0;
 900   }
 901 
 902   static int cell_count_local_offset() {
 903     assert(arguments_profiling_enabled() && (TypeProfileArgsLimit > 1 || return_profiling_enabled()), "no cell count");
 904     return 0;
 905   }
 906 
 907   int cell_count_global_offset() const {
 908     return _base_off + cell_count_local_offset();
 909   }
 910 
 911   static int stack_slot_local_offset(int i) {
 912     assert_arguments_profiling_enabled();
 913     return header_cell_count() + TypeStackSlotEntries::stack_slot_local_offset(i);
 914   }
 915 
 916   static int argument_type_local_offset(int i) {
 917     assert_arguments_profiling_enabled();
 918     return header_cell_count() + TypeStackSlotEntries::type_local_offset(i);;
 919   }
 920 
 921   void check_number_of_arguments(uint total) {
 922     assert(number_of_arguments() == total, "should be set in DataLayout::initialize");
 923   }
 924 
 925   // number of cells not counting the header
 926   int cell_count_no_header() const {
 927     return _pd->uint_at(cell_count_global_offset());
 928   }
 929   
 930   static bool arguments_profiling_enabled();
 931   static void assert_arguments_profiling_enabled() {
 932     assert(arguments_profiling_enabled(), "args profiling should be on");
 933   }
 934   static bool return_profiling_enabled() {
 935     return ReturnTypeEntry::profiling_enabled();
 936   }
 937   static void assert_return_profiling_enabled() {
 938     ReturnTypeEntry::assert_profiling_enabled();
 939   }
 940 
 941 protected:
 942 
 943   // ProfileData object these entries are part of
 944   ProfileData* _pd;
 945 
 946   // An entry for a return value takes less space than an entry for an
 947   // argument so if the number of cells exceeds the number of cells
 948   // needed for an argument, this object contains type information for
 949   // at least one argument.
 950   bool has_arguments() const {
 951     assert_arguments_profiling_enabled();
 952     return return_profiling_enabled() ? (cell_count_no_header() >= TypeStackSlotEntries::per_arg_count()) : true;
 953   }
 954 
 955 public:
 956   TypeEntriesAtCall(int base_off, ProfileData* pd)
 957     : _base_off(base_off), _pd(pd),
 958       _args(base_off + header_cell_count(), pd, arguments_profiling_enabled() ? number_of_arguments() : 0),
 959       _ret((arguments_profiling_enabled() && return_profiling_enabled()) ? cell_count() - ReturnTypeEntry::static_cell_count() : _base_off, pd)
 960   {}
 961 
 962   static int compute_cell_count(BytecodeStream* stream);
 963 
 964   static void initialize(DataLayout* dl, int base, int cell_count) {
 965     if (arguments_profiling_enabled() && (TypeProfileArgsLimit > 1 || return_profiling_enabled())) {
 966       int off = base + cell_count_local_offset();
 967       dl->set_cell_at(off, cell_count - base - header_cell_count());
 968     }
 969   }
 970 
 971   void post_initialize(BytecodeStream* stream);
 972 
 973   uint number_of_arguments() const {
 974     assert_arguments_profiling_enabled();
 975     if (TypeProfileArgsLimit > 1) {
 976       // An entry for a return value takes less space than an entry
 977       // for an argument, so number of cells divided by the number of
 978       // cells for an argument is the number of arguments being
 979       // profiled in this object.
 980       int cell_count = cell_count_no_header();
 981       assert(!return_profiling_enabled() || TypeStackSlotEntries::per_arg_count() > ReturnTypeEntry::static_cell_count(), "need each per arg entry to be bigger than ret entry");
 982       int nb = cell_count / TypeStackSlotEntries::per_arg_count();
 983       assert((!has_arguments() && nb == 0) || (nb > 0 && nb <= TypeProfileArgsLimit) , "only when we profile args");
 984       return nb;
 985     } else {
 986       assert(TypeProfileArgsLimit == 1, "at least one arg");
 987       return 1;
 988     }
 989   }
 990   
 991   int cell_count() const {
 992     if (arguments_profiling_enabled() && (TypeProfileArgsLimit > 1 || return_profiling_enabled())) {

 993       return _base_off + header_cell_count() + _pd->int_at_unchecked(cell_count_global_offset());
 994     } else if (arguments_profiling_enabled()) {
 995       return _base_off + TypeStackSlotEntries::per_arg_count();
 996     } else {
 997      assert_return_profiling_enabled();
 998       return _base_off + ReturnTypeEntry::static_cell_count();
 999     } 
1000   }
1001 
1002   const TypeStackSlotEntries* args_type_data() const { return &_args; }
1003   const ReturnTypeEntry* ret_type_data() const { return &_ret; }


























1004 
1005   // An entry for a return value takes less space than an entry for an
1006   // argument, so if the remainder of the number of cells divided by
1007   // the number of cells for an argument is not null, a return value
1008   // is profiled in this object.
1009   bool has_return() const {
1010    assert_return_profiling_enabled();
1011    return arguments_profiling_enabled() ? (cell_count_no_header() % TypeStackSlotEntries::per_arg_count()) != 0 : true;
1012   }
1013 
1014   void set_argument_type(int i, Klass* k) {
1015     intptr_t current = _args.type(i);
1016     _args.set_type(i, TypeEntries::with_status(k, current));
1017   }
1018 
1019   void set_return_type(Klass* k) {
1020     intptr_t current = _ret.type();
1021     _ret.set_type(TypeEntries::with_status(k, current));
1022   }
1023 
1024   // Code generation support
1025   static ByteSize cell_count_offset() {
1026     return in_ByteSize(cell_count_local_offset() * DataLayout::cell_size);
1027   }
1028 
1029   static ByteSize args_data_offset() {
1030     return in_ByteSize(header_cell_count() * DataLayout::cell_size);
1031   }
1032 
1033   static ByteSize stack_slot_offset(int i) {
1034     return in_ByteSize(stack_slot_local_offset(i) * DataLayout::cell_size);
1035   }
1036 
1037   static ByteSize argument_type_offset(int i) {
1038     return in_ByteSize(argument_type_local_offset(i) * DataLayout::cell_size);
1039   }
1040 
1041   ByteSize return_type_offset() {
1042     return _ret.type_offset();
1043   }
1044 
1045   // GC support
1046   void clean_weak_klass_links(BoolObjectClosure* is_alive_closure);
1047 
1048 #ifndef PRODUCT
1049   void print_data_on(outputStream* st) const;
1050 #endif
1051 };
1052 
1053 // CallTypeData
1054 //
1055 // A CallTypeData is used to access profiling information about a non
1056 // virtual call for which we collect type information about arguments
1057 // and return value.
1058 class CallTypeData : public CounterData {
1059 private:
1060   TypeEntriesAtCall _args_and_ret;
1061 
1062 public:
1063   CallTypeData(DataLayout* layout) :
1064     CounterData(layout), _args_and_ret(CounterData::static_cell_count(), this)  {
1065     assert(layout->tag() == DataLayout::call_type_data_tag, "wrong type");
1066   }
1067 
1068   const TypeEntriesAtCall* args_and_ret() const { return &_args_and_ret; }
1069 
1070   virtual bool is_CallTypeData() const { return true; }
1071 
1072   static int static_cell_count() {
1073     return -1;
1074   }
1075 
1076   static int compute_cell_count(BytecodeStream* stream) {
1077     return CounterData::static_cell_count() + TypeEntriesAtCall::compute_cell_count(stream);
1078   }
1079   
1080   static void initialize(DataLayout* dl, int cell_count) {
1081     TypeEntriesAtCall::initialize(dl, CounterData::static_cell_count(), cell_count);
1082   }
1083 
1084   virtual void post_initialize(BytecodeStream* stream, MethodData* mdo) {
1085     _args_and_ret.post_initialize(stream);
1086   }
1087 
1088   virtual int cell_count() const {
1089     return _args_and_ret.cell_count();
1090   }
1091 
1092   uint number_of_arguments() const {
1093     return args_and_ret()->number_of_arguments();
1094   }
1095 
1096   void set_argument_type(int i, Klass* k) {
1097     _args_and_ret.set_argument_type(i, k);
1098   }
1099 
1100   void set_return_type(Klass* k) {
1101     _args_and_ret.set_return_type(k);
1102   }
1103   
1104   // Code generation support
1105   static ByteSize args_data_offset() {
1106     return cell_offset(CounterData::static_cell_count()) + TypeEntriesAtCall::args_data_offset();
1107   }
1108 
1109   // GC support
1110   virtual void clean_weak_klass_links(BoolObjectClosure* is_alive_closure) {
1111     _args_and_ret.clean_weak_klass_links(is_alive_closure);
1112   }
1113 
1114 #ifndef PRODUCT
1115   virtual void print_data_on(outputStream* st) const;
1116 #endif
1117 };
1118 
1119 // ReceiverTypeData
1120 //
1121 // A ReceiverTypeData is used to access profiling information about a
1122 // dynamic type check.  It consists of a counter which counts the total times
1123 // that the check is reached, and a series of (Klass*, count) pairs
1124 // which are used to store a type profile for the receiver of the check.
1125 class ReceiverTypeData : public CounterData {
1126 protected:
1127   enum {
1128     receiver0_offset = counter_cell_count,
1129     count0_offset,
1130     receiver_type_row_cell_count = (count0_offset + 1) - receiver0_offset
1131   };


1244   }
1245 
1246   virtual int cell_count() const {
1247     return static_cell_count();
1248   }
1249 
1250   // Direct accessors
1251   static ByteSize virtual_call_data_size() {
1252     return cell_offset(static_cell_count());
1253   }
1254 
1255 #ifndef PRODUCT
1256   void print_data_on(outputStream* st) const;
1257 #endif
1258 };
1259 
1260 // VirtualCallTypeData
1261 //
1262 // A VirtualCallTypeData is used to access profiling information about
1263 // a virtual call for which we collect type information about
1264 // arguments and return value.
1265 class VirtualCallTypeData : public VirtualCallData {
1266 private:
1267   TypeEntriesAtCall _args_and_ret;
1268 
1269 public:
1270   VirtualCallTypeData(DataLayout* layout) :
1271     VirtualCallData(layout), _args_and_ret(VirtualCallData::static_cell_count(), this)  {
1272     assert(layout->tag() == DataLayout::virtual_call_type_data_tag, "wrong type");
1273   }
1274 
1275   const TypeEntriesAtCall* args_and_ret() const { return &_args_and_ret; }
1276 
1277   virtual bool is_VirtualCallTypeData() const { return true; }
1278 
1279   static int static_cell_count() {
1280     return -1;
1281   }
1282 
1283   static int compute_cell_count(BytecodeStream* stream) {
1284     return VirtualCallData::static_cell_count() + TypeEntriesAtCall::compute_cell_count(stream);
1285   }
1286   
1287   static void initialize(DataLayout* dl, int cell_count) {
1288     TypeEntriesAtCall::initialize(dl, VirtualCallData::static_cell_count(), cell_count);
1289   }
1290 
1291   virtual void post_initialize(BytecodeStream* stream, MethodData* mdo) {
1292     _args_and_ret.post_initialize(stream);
1293   }
1294 
1295   virtual int cell_count() const {
1296     return _args_and_ret.cell_count();
1297   }
1298 
1299   uint number_of_arguments() const {
1300     return args_and_ret()->number_of_arguments();
1301   }
1302 
1303   void set_argument_type(int i, Klass* k) {
1304     _args_and_ret.set_argument_type(i, k);
1305   }
1306 
1307   void set_return_type(Klass* k) {
1308     _args_and_ret.set_return_type(k);
1309   }
1310 
1311   // Code generation support
1312   static ByteSize args_data_offset() {
1313     return cell_offset(VirtualCallData::static_cell_count()) + TypeEntriesAtCall::args_data_offset();
1314   }
1315 
1316   // GC support
1317   virtual void clean_weak_klass_links(BoolObjectClosure* is_alive_closure) {
1318     ReceiverTypeData::clean_weak_klass_links(is_alive_closure);
1319     _args_and_ret.clean_weak_klass_links(is_alive_closure);
1320   }
1321 
1322 #ifndef PRODUCT
1323   virtual void print_data_on(outputStream* st) const;
1324 #endif
1325 };
1326 
1327 // RetData
1328 //
1329 // A RetData is used to access profiling information for a ret bytecode.
1330 // It is composed of a count of the number of times that the ret has
1331 // been executed, followed by a series of triples of the form
1332 // (bci, count, di) which count the number of times that some bci was the
1333 // target of the ret and cache a corresponding data displacement.
1334 class RetData : public CounterData {
1335 protected:
1336   enum {
1337     bci0_offset = counter_cell_count,
1338     count0_offset,
1339     displacement0_offset,


1831   // What is the index of the first data entry?
1832   int first_di() const { return 0; }
1833 
1834   // Find or create an extra ProfileData:
1835   ProfileData* bci_to_extra_data(int bci, bool create_if_missing);
1836 
1837   // return the argument info cell
1838   ArgInfoData *arg_info();
1839 
1840   enum {
1841     no_type_profile = 0,
1842     type_profile_jsr292 = 1,
1843     type_profile_all = 2
1844   };
1845 
1846   static bool profile_jsr292(methodHandle m, int bci);
1847   static int profile_arguments_flag();
1848   static bool profile_arguments_jsr292_only();
1849   static bool profile_all_arguments();
1850   static bool profile_arguments_for_invoke(methodHandle m, int bci);
1851   static int profile_return_flag();
1852   static bool profile_return_jsr292_only();
1853   static bool profile_all_return();
1854   static bool profile_return_for_invoke(methodHandle m, int bci);
1855 
1856 public:
1857   static int header_size() {
1858     return sizeof(MethodData)/wordSize;
1859   }
1860 
1861   // Compute the size of a MethodData* before it is created.
1862   static int compute_allocation_size_in_bytes(methodHandle method);
1863   static int compute_allocation_size_in_words(methodHandle method);
1864   static int compute_extra_data_count(int data_size, int empty_bc_count);
1865 
1866   // Determine if a given bytecode can have profile information.
1867   static bool bytecode_has_profile(Bytecodes::Code code) {
1868     return bytecode_cell_count(code) != no_profile_data;
1869   }
1870 
1871   // reset into original state
1872   void init();
1873 
1874   // My size


2077   void set_size(int object_size_in_bytes) { _size = object_size_in_bytes; }
2078 
2079   // Printing
2080 #ifndef PRODUCT
2081   void print_on      (outputStream* st) const;
2082 #endif
2083   void print_value_on(outputStream* st) const;
2084 
2085 #ifndef PRODUCT
2086   // printing support for method data
2087   void print_data_on(outputStream* st) const;
2088 #endif
2089 
2090   const char* internal_name() const { return "{method data}"; }
2091 
2092   // verification
2093   void verify_on(outputStream* st);
2094   void verify_data_on(outputStream* st);
2095 
2096   static bool profile_arguments();
2097   static bool profile_return();
2098 };
2099 
2100 #endif // SHARE_VM_OOPS_METHODDATAOOP_HPP
src/share/vm/oops/methodData.hpp
Index Unified diffs Context diffs Sdiffs Patch New Old Previous File Next File