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... |
|