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 6132 : 8026694: New type profiling points break compilation replay
Summary: fixes compilation replay with new profiling points
Reviewed-by:


 840 
 841 // Type entries used for arguments passed at a call and parameters on
 842 // method entry. 2 cells per entry: one for the type encoded as in
 843 // TypeEntries and one initialized with the stack slot where the
 844 // profiled object is to be found so that the interpreter can locate
 845 // it quickly.
 846 class TypeStackSlotEntries : public TypeEntries {
 847 
 848 private:
 849   enum {
 850     stack_slot_entry,
 851     type_entry,
 852     per_arg_cell_count
 853   };
 854 
 855   // offset of cell for stack slot for entry i within ProfileData object
 856   int stack_slot_offset(int i) const {
 857     return _base_off + stack_slot_local_offset(i);
 858   }
 859 
 860 protected:
 861   const int _number_of_entries;
 862 
 863   // offset of cell for type for entry i within ProfileData object
 864   int type_offset(int i) const {
 865     return _base_off + type_local_offset(i);
 866   }
 867 
 868 public:
 869 
 870   TypeStackSlotEntries(int base_off, int nb_entries)
 871     : TypeEntries(base_off), _number_of_entries(nb_entries) {}
 872 
 873   static int compute_cell_count(Symbol* signature, bool include_receiver, int max);
 874 
 875   void post_initialize(Symbol* signature, bool has_receiver, bool include_receiver);
 876 


 877   // offset of cell for stack slot for entry i within this block of cells for a TypeStackSlotEntries
 878   static int stack_slot_local_offset(int i) {
 879     return i * per_arg_cell_count + stack_slot_entry;
 880   }
 881 
 882   // offset of cell for type for entry i within this block of cells for a TypeStackSlotEntries
 883   static int type_local_offset(int i) {
 884     return i * per_arg_cell_count + type_entry;
 885   }
 886 
 887   // stack slot for entry i
 888   uint stack_slot(int i) const {
 889     assert(i >= 0 && i < _number_of_entries, "oob");
 890     return _pd->uint_at(stack_slot_offset(i));
 891   }
 892 
 893   // set stack slot for entry i
 894   void set_stack_slot(int i, uint num) {
 895     assert(i >= 0 && i < _number_of_entries, "oob");
 896     _pd->set_uint_at(stack_slot_offset(i), num);
 897   }
 898 
 899   // type for entry i
 900   intptr_t type(int i) const {
 901     assert(i >= 0 && i < _number_of_entries, "oob");
 902     return _pd->intptr_at(type_offset(i));
 903   }
 904 
 905   // set type for entry i
 906   void set_type(int i, intptr_t k) {
 907     assert(i >= 0 && i < _number_of_entries, "oob");
 908     _pd->set_intptr_at(type_offset(i), k);
 909   }
 910 
 911   static ByteSize per_arg_size() {
 912     return in_ByteSize(per_arg_cell_count * DataLayout::cell_size);
 913   }
 914 
 915   static int per_arg_count() {
 916     return per_arg_cell_count ;
 917   }
 918 




 919   // GC support
 920   void clean_weak_klass_links(BoolObjectClosure* is_alive_closure);
 921 
 922 #ifndef PRODUCT
 923   void print_data_on(outputStream* st) const;
 924 #endif
 925 };
 926 
 927 // Type entry used for return from a call. A single cell to record the
 928 // type.
 929 class ReturnTypeEntry : public TypeEntries {
 930 
 931 private:
 932   enum {
 933     cell_count = 1
 934   };
 935 
 936 public:
 937   ReturnTypeEntry(int base_off)
 938     : TypeEntries(base_off) {}


1117     bool res = cell_count_no_header() >= TypeStackSlotEntries::per_arg_count();
1118     assert (!res || TypeEntriesAtCall::arguments_profiling_enabled(), "no profiling of arguments");
1119     return res;
1120   }
1121 
1122   // An entry for a return value takes less space than an entry for an
1123   // argument, so if the remainder of the number of cells divided by
1124   // the number of cells for an argument is not null, a return value
1125   // is profiled in this object.
1126   bool has_return() const {
1127     bool res = (cell_count_no_header() % TypeStackSlotEntries::per_arg_count()) != 0;
1128     assert (!res || TypeEntriesAtCall::return_profiling_enabled(), "no profiling of return values");
1129     return res;
1130   }
1131 
1132   // Code generation support
1133   static ByteSize args_data_offset() {
1134     return cell_offset(CounterData::static_cell_count()) + TypeEntriesAtCall::args_data_offset();
1135   }
1136 








1137   // GC support
1138   virtual void clean_weak_klass_links(BoolObjectClosure* is_alive_closure) {
1139     if (has_arguments()) {
1140       _args.clean_weak_klass_links(is_alive_closure);
1141     }
1142     if (has_return()) {
1143       _ret.clean_weak_klass_links(is_alive_closure);
1144     }
1145   }
1146 
1147 #ifndef PRODUCT
1148   virtual void print_data_on(outputStream* st, const char* extra = NULL) const;
1149 #endif
1150 };
1151 
1152 // ReceiverTypeData
1153 //
1154 // A ReceiverTypeData is used to access profiling information about a
1155 // dynamic type check.  It consists of a counter which counts the total times
1156 // that the check is reached, and a series of (Klass*, count) pairs


1430     bool res = (cell_count_no_header() % TypeStackSlotEntries::per_arg_count()) != 0;
1431     assert (!res || TypeEntriesAtCall::return_profiling_enabled(), "no profiling of return values");
1432     return res;
1433   }
1434 
1435   // An entry for a return value takes less space than an entry for an
1436   // argument so if the number of cells exceeds the number of cells
1437   // needed for an argument, this object contains type information for
1438   // at least one argument.
1439   bool has_arguments() const {
1440     bool res = cell_count_no_header() >= TypeStackSlotEntries::per_arg_count();
1441     assert (!res || TypeEntriesAtCall::arguments_profiling_enabled(), "no profiling of arguments");
1442     return res;
1443   }
1444 
1445   // Code generation support
1446   static ByteSize args_data_offset() {
1447     return cell_offset(VirtualCallData::static_cell_count()) + TypeEntriesAtCall::args_data_offset();
1448   }
1449 








1450   // GC support
1451   virtual void clean_weak_klass_links(BoolObjectClosure* is_alive_closure) {
1452     ReceiverTypeData::clean_weak_klass_links(is_alive_closure);
1453     if (has_arguments()) {
1454       _args.clean_weak_klass_links(is_alive_closure);
1455     }
1456     if (has_return()) {
1457       _ret.clean_weak_klass_links(is_alive_closure);
1458     }
1459   }
1460 
1461 #ifndef PRODUCT
1462   virtual void print_data_on(outputStream* st, const char* extra = NULL) const;
1463 #endif
1464 };
1465 
1466 // RetData
1467 //
1468 // A RetData is used to access profiling information for a ret bytecode.
1469 // It is composed of a count of the number of times that the ret has


1932     return cell_offset(type_local_offset(i));
1933   }
1934 };
1935 
1936 // SpeculativeTrapData
1937 //
1938 // A SpeculativeTrapData is used to record traps due to type
1939 // speculation. It records the root of the compilation: that type
1940 // speculation is wrong in the context of one compilation (for
1941 // method1) doesn't mean it's wrong in the context of another one (for
1942 // method2). Type speculation could have more/different data in the
1943 // context of the compilation of method2 and it's worthwhile to try an
1944 // optimization that failed for compilation of method1 in the context
1945 // of compilation of method2.
1946 // Space for SpeculativeTrapData entries is allocated from the extra
1947 // data space in the MDO. If we run out of space, the trap data for
1948 // the ProfileData at that bci is updated.
1949 class SpeculativeTrapData : public ProfileData {
1950 protected:
1951   enum {
1952     method_offset,
1953     speculative_trap_cell_count
1954   };
1955 public:
1956   SpeculativeTrapData(DataLayout* layout) : ProfileData(layout) {
1957     assert(layout->tag() == DataLayout::speculative_trap_data_tag, "wrong type");
1958   }
1959 
1960   virtual bool is_SpeculativeTrapData() const { return true; }
1961 
1962   static int static_cell_count() {
1963     return speculative_trap_cell_count;
1964   }
1965 
1966   virtual int cell_count() const {
1967     return static_cell_count();
1968   }
1969 
1970   // Direct accessor
1971   Method* method() const {
1972     return (Method*)intptr_at(method_offset);
1973   }
1974 
1975   void set_method(Method* m) {
1976     set_intptr_at(method_offset, (intptr_t)m);




1977   }
1978 
1979 #ifndef PRODUCT
1980   virtual void print_data_on(outputStream* st, const char* extra = NULL) const;
1981 #endif
1982 };
1983 
1984 // MethodData*
1985 //
1986 // A MethodData* holds information which has been collected about
1987 // a method.  Its layout looks like this:
1988 //
1989 // -----------------------------
1990 // | header                    |
1991 // | klass                     |
1992 // -----------------------------
1993 // | method                    |
1994 // | size of the MethodData* |
1995 // -----------------------------
1996 // | Data entries...           |




 840 
 841 // Type entries used for arguments passed at a call and parameters on
 842 // method entry. 2 cells per entry: one for the type encoded as in
 843 // TypeEntries and one initialized with the stack slot where the
 844 // profiled object is to be found so that the interpreter can locate
 845 // it quickly.
 846 class TypeStackSlotEntries : public TypeEntries {
 847 
 848 private:
 849   enum {
 850     stack_slot_entry,
 851     type_entry,
 852     per_arg_cell_count
 853   };
 854 
 855   // offset of cell for stack slot for entry i within ProfileData object
 856   int stack_slot_offset(int i) const {
 857     return _base_off + stack_slot_local_offset(i);
 858   }
 859 

 860   const int _number_of_entries;
 861 
 862   // offset of cell for type for entry i within ProfileData object
 863   int type_offset_in_cells(int i) const {
 864     return _base_off + type_local_offset(i);
 865   }
 866 
 867 public:
 868 
 869   TypeStackSlotEntries(int base_off, int nb_entries)
 870     : TypeEntries(base_off), _number_of_entries(nb_entries) {}
 871 
 872   static int compute_cell_count(Symbol* signature, bool include_receiver, int max);
 873 
 874   void post_initialize(Symbol* signature, bool has_receiver, bool include_receiver);
 875 
 876   int number_of_entries() const { return _number_of_entries; }
 877 
 878   // offset of cell for stack slot for entry i within this block of cells for a TypeStackSlotEntries
 879   static int stack_slot_local_offset(int i) {
 880     return i * per_arg_cell_count + stack_slot_entry;
 881   }
 882 
 883   // offset of cell for type for entry i within this block of cells for a TypeStackSlotEntries
 884   static int type_local_offset(int i) {
 885     return i * per_arg_cell_count + type_entry;
 886   }
 887 
 888   // stack slot for entry i
 889   uint stack_slot(int i) const {
 890     assert(i >= 0 && i < _number_of_entries, "oob");
 891     return _pd->uint_at(stack_slot_offset(i));
 892   }
 893 
 894   // set stack slot for entry i
 895   void set_stack_slot(int i, uint num) {
 896     assert(i >= 0 && i < _number_of_entries, "oob");
 897     _pd->set_uint_at(stack_slot_offset(i), num);
 898   }
 899 
 900   // type for entry i
 901   intptr_t type(int i) const {
 902     assert(i >= 0 && i < _number_of_entries, "oob");
 903     return _pd->intptr_at(type_offset_in_cells(i));
 904   }
 905 
 906   // set type for entry i
 907   void set_type(int i, intptr_t k) {
 908     assert(i >= 0 && i < _number_of_entries, "oob");
 909     _pd->set_intptr_at(type_offset_in_cells(i), k);
 910   }
 911 
 912   static ByteSize per_arg_size() {
 913     return in_ByteSize(per_arg_cell_count * DataLayout::cell_size);
 914   }
 915 
 916   static int per_arg_count() {
 917     return per_arg_cell_count ;
 918   }
 919 
 920   ByteSize type_offset(int i) const {
 921     return DataLayout::cell_offset(type_offset_in_cells(i));
 922   }
 923 
 924   // GC support
 925   void clean_weak_klass_links(BoolObjectClosure* is_alive_closure);
 926 
 927 #ifndef PRODUCT
 928   void print_data_on(outputStream* st) const;
 929 #endif
 930 };
 931 
 932 // Type entry used for return from a call. A single cell to record the
 933 // type.
 934 class ReturnTypeEntry : public TypeEntries {
 935 
 936 private:
 937   enum {
 938     cell_count = 1
 939   };
 940 
 941 public:
 942   ReturnTypeEntry(int base_off)
 943     : TypeEntries(base_off) {}


1122     bool res = cell_count_no_header() >= TypeStackSlotEntries::per_arg_count();
1123     assert (!res || TypeEntriesAtCall::arguments_profiling_enabled(), "no profiling of arguments");
1124     return res;
1125   }
1126 
1127   // An entry for a return value takes less space than an entry for an
1128   // argument, so if the remainder of the number of cells divided by
1129   // the number of cells for an argument is not null, a return value
1130   // is profiled in this object.
1131   bool has_return() const {
1132     bool res = (cell_count_no_header() % TypeStackSlotEntries::per_arg_count()) != 0;
1133     assert (!res || TypeEntriesAtCall::return_profiling_enabled(), "no profiling of return values");
1134     return res;
1135   }
1136 
1137   // Code generation support
1138   static ByteSize args_data_offset() {
1139     return cell_offset(CounterData::static_cell_count()) + TypeEntriesAtCall::args_data_offset();
1140   }
1141 
1142   ByteSize argument_type_offset(int i) {
1143     return _args.type_offset(i);
1144   }
1145 
1146   ByteSize return_type_offset() {
1147     return _ret.type_offset();
1148   }
1149 
1150   // GC support
1151   virtual void clean_weak_klass_links(BoolObjectClosure* is_alive_closure) {
1152     if (has_arguments()) {
1153       _args.clean_weak_klass_links(is_alive_closure);
1154     }
1155     if (has_return()) {
1156       _ret.clean_weak_klass_links(is_alive_closure);
1157     }
1158   }
1159 
1160 #ifndef PRODUCT
1161   virtual void print_data_on(outputStream* st, const char* extra = NULL) const;
1162 #endif
1163 };
1164 
1165 // ReceiverTypeData
1166 //
1167 // A ReceiverTypeData is used to access profiling information about a
1168 // dynamic type check.  It consists of a counter which counts the total times
1169 // that the check is reached, and a series of (Klass*, count) pairs


1443     bool res = (cell_count_no_header() % TypeStackSlotEntries::per_arg_count()) != 0;
1444     assert (!res || TypeEntriesAtCall::return_profiling_enabled(), "no profiling of return values");
1445     return res;
1446   }
1447 
1448   // An entry for a return value takes less space than an entry for an
1449   // argument so if the number of cells exceeds the number of cells
1450   // needed for an argument, this object contains type information for
1451   // at least one argument.
1452   bool has_arguments() const {
1453     bool res = cell_count_no_header() >= TypeStackSlotEntries::per_arg_count();
1454     assert (!res || TypeEntriesAtCall::arguments_profiling_enabled(), "no profiling of arguments");
1455     return res;
1456   }
1457 
1458   // Code generation support
1459   static ByteSize args_data_offset() {
1460     return cell_offset(VirtualCallData::static_cell_count()) + TypeEntriesAtCall::args_data_offset();
1461   }
1462 
1463   ByteSize argument_type_offset(int i) {
1464     return _args.type_offset(i);
1465   }
1466 
1467   ByteSize return_type_offset() {
1468     return _ret.type_offset();
1469   }
1470 
1471   // GC support
1472   virtual void clean_weak_klass_links(BoolObjectClosure* is_alive_closure) {
1473     ReceiverTypeData::clean_weak_klass_links(is_alive_closure);
1474     if (has_arguments()) {
1475       _args.clean_weak_klass_links(is_alive_closure);
1476     }
1477     if (has_return()) {
1478       _ret.clean_weak_klass_links(is_alive_closure);
1479     }
1480   }
1481 
1482 #ifndef PRODUCT
1483   virtual void print_data_on(outputStream* st, const char* extra = NULL) const;
1484 #endif
1485 };
1486 
1487 // RetData
1488 //
1489 // A RetData is used to access profiling information for a ret bytecode.
1490 // It is composed of a count of the number of times that the ret has


1953     return cell_offset(type_local_offset(i));
1954   }
1955 };
1956 
1957 // SpeculativeTrapData
1958 //
1959 // A SpeculativeTrapData is used to record traps due to type
1960 // speculation. It records the root of the compilation: that type
1961 // speculation is wrong in the context of one compilation (for
1962 // method1) doesn't mean it's wrong in the context of another one (for
1963 // method2). Type speculation could have more/different data in the
1964 // context of the compilation of method2 and it's worthwhile to try an
1965 // optimization that failed for compilation of method1 in the context
1966 // of compilation of method2.
1967 // Space for SpeculativeTrapData entries is allocated from the extra
1968 // data space in the MDO. If we run out of space, the trap data for
1969 // the ProfileData at that bci is updated.
1970 class SpeculativeTrapData : public ProfileData {
1971 protected:
1972   enum {
1973     speculative_trap_method,
1974     speculative_trap_cell_count
1975   };
1976 public:
1977   SpeculativeTrapData(DataLayout* layout) : ProfileData(layout) {
1978     assert(layout->tag() == DataLayout::speculative_trap_data_tag, "wrong type");
1979   }
1980 
1981   virtual bool is_SpeculativeTrapData() const { return true; }
1982 
1983   static int static_cell_count() {
1984     return speculative_trap_cell_count;
1985   }
1986 
1987   virtual int cell_count() const {
1988     return static_cell_count();
1989   }
1990 
1991   // Direct accessor
1992   Method* method() const {
1993     return (Method*)intptr_at(speculative_trap_method);
1994   }
1995 
1996   void set_method(Method* m) {
1997     set_intptr_at(speculative_trap_method, (intptr_t)m);
1998   }
1999 
2000   static ByteSize method_offset() {
2001     return cell_offset(speculative_trap_method);
2002   }
2003 
2004 #ifndef PRODUCT
2005   virtual void print_data_on(outputStream* st, const char* extra = NULL) const;
2006 #endif
2007 };
2008 
2009 // MethodData*
2010 //
2011 // A MethodData* holds information which has been collected about
2012 // a method.  Its layout looks like this:
2013 //
2014 // -----------------------------
2015 // | header                    |
2016 // | klass                     |
2017 // -----------------------------
2018 // | method                    |
2019 // | size of the MethodData* |
2020 // -----------------------------
2021 // | Data entries...           |


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