< prev index next >

src/share/vm/oops/methodData.hpp

Print this page




 518   // as well as CIMethodData data. This function is provided for translating
 519   // an oop in a ProfileData to the ci equivalent. Generally speaking,
 520   // most ProfileData don't require any translation, so we provide the null
 521   // translation here, and the required translators are in the ci subclasses.
 522   virtual void translate_from(const ProfileData* data) {}
 523 
 524   virtual void print_data_on(outputStream* st, const char* extra = NULL) const {
 525     ShouldNotReachHere();
 526   }
 527 
 528   void print_data_on(outputStream* st, const MethodData* md) const;
 529 
 530   void print_shared(outputStream* st, const char* name, const char* extra) const;
 531   void tab(outputStream* st, bool first = false) const;
 532 };
 533 
 534 // BitData
 535 //
 536 // A BitData holds a flag or two in its header.
 537 class BitData : public ProfileData {

 538 protected:
 539   enum {
 540     // null_seen:
 541     //  saw a null operand (cast/aastore/instanceof)
 542       null_seen_flag              = DataLayout::first_flag + 0
 543 #if INCLUDE_JVMCI
 544     // bytecode threw any exception
 545     , exception_seen_flag         = null_seen_flag + 1
 546 #endif
 547   };
 548   enum { bit_cell_count = 0 };  // no additional data fields needed.
 549 public:
 550   BitData(DataLayout* layout) : ProfileData(layout) {
 551   }
 552 
 553   virtual bool is_BitData() const { return true; }
 554 
 555   static int static_cell_count() {
 556     return bit_cell_count;
 557   }


 586   static int bit_data_size_in_bytes() {
 587     return cell_offset_in_bytes(bit_cell_count);
 588   }
 589 
 590   static void set_null_seen(DataLayout* layout) {
 591     set_flag_at(layout, null_seen_flag);
 592   }
 593 
 594   static DataLayout* advance(DataLayout* layout) {
 595     return (DataLayout*) (((address)layout) + (ssize_t)BitData::bit_data_size_in_bytes());
 596   }
 597 #endif // CC_INTERP
 598 
 599   void print_data_on(outputStream* st, const char* extra = NULL) const;
 600 };
 601 
 602 // CounterData
 603 //
 604 // A CounterData corresponds to a simple counter.
 605 class CounterData : public BitData {

 606 protected:
 607   enum {
 608     count_off,
 609     counter_cell_count
 610   };
 611 public:
 612   CounterData(DataLayout* layout) : BitData(layout) {}
 613 
 614   virtual bool is_CounterData() const { return true; }
 615 
 616   static int static_cell_count() {
 617     return counter_cell_count;
 618   }
 619 
 620   virtual int cell_count() const {
 621     return static_cell_count();
 622   }
 623 
 624   // Direct accessor
 625   uint count() const {


 650   // Support counter decrementation at checkcast / subtype check failed.
 651   static void decrement_count(DataLayout* layout) {
 652     increment_uint_at_no_overflow(layout, count_off, -1);
 653   }
 654 
 655   static DataLayout* advance(DataLayout* layout) {
 656     return (DataLayout*) (((address)layout) + (ssize_t)CounterData::counter_data_size_in_bytes());
 657   }
 658 #endif // CC_INTERP
 659 
 660   void print_data_on(outputStream* st, const char* extra = NULL) const;
 661 };
 662 
 663 // JumpData
 664 //
 665 // A JumpData is used to access profiling information for a direct
 666 // branch.  It is a counter, used for counting the number of branches,
 667 // plus a data displacement, used for realigning the data pointer to
 668 // the corresponding target bci.
 669 class JumpData : public ProfileData {

 670 protected:
 671   enum {
 672     taken_off_set,
 673     displacement_off_set,
 674     jump_cell_count
 675   };
 676 
 677   void set_displacement(int displacement) {
 678     set_int_at(displacement_off_set, displacement);
 679   }
 680 
 681 public:
 682   JumpData(DataLayout* layout) : ProfileData(layout) {
 683     assert(layout->tag() == DataLayout::jump_data_tag ||
 684       layout->tag() == DataLayout::branch_data_tag, "wrong type");
 685   }
 686 
 687   virtual bool is_JumpData() const { return true; }
 688 
 689   static int static_cell_count() {


1156   // GC support
1157   virtual void clean_weak_klass_links(BoolObjectClosure* is_alive_closure) {
1158     if (has_arguments()) {
1159       _args.clean_weak_klass_links(is_alive_closure);
1160     }
1161     if (has_return()) {
1162       _ret.clean_weak_klass_links(is_alive_closure);
1163     }
1164   }
1165 
1166   virtual void print_data_on(outputStream* st, const char* extra = NULL) const;
1167 };
1168 
1169 // ReceiverTypeData
1170 //
1171 // A ReceiverTypeData is used to access profiling information about a
1172 // dynamic type check.  It consists of a counter which counts the total times
1173 // that the check is reached, and a series of (Klass*, count) pairs
1174 // which are used to store a type profile for the receiver of the check.
1175 class ReceiverTypeData : public CounterData {

1176 protected:
1177   enum {
1178 #if INCLUDE_JVMCI
1179     // Description of the different counters
1180     // ReceiverTypeData for instanceof/checkcast/aastore:
1181     //   C1/C2: count is incremented on type overflow and decremented for failed type checks
1182     //   JVMCI: count decremented for failed type checks and nonprofiled_count is incremented on type overflow
1183     //          TODO (chaeubl): in fact, JVMCI should also increment the count for failed type checks to mimic the C1/C2 behavior
1184     // VirtualCallData for invokevirtual/invokeinterface:
1185     //   C1/C2: count is incremented on type overflow
1186     //   JVMCI: count is incremented on type overflow, nonprofiled_count is incremented on method overflow
1187 
1188     // JVMCI is interested in knowing the percentage of type checks involving a type not explicitly in the profile
1189     nonprofiled_count_off_set = counter_cell_count,
1190     receiver0_offset,
1191 #else
1192     receiver0_offset = counter_cell_count,
1193 #endif
1194     count0_offset,
1195     receiver_type_row_cell_count = (count0_offset + 1) - receiver0_offset


1661   static ByteSize bci_displacement_offset(uint row) {
1662     return cell_offset(bci_displacement_cell_index(row));
1663   }
1664 
1665 #ifdef CC_INTERP
1666   static DataLayout* advance(MethodData *md, int bci);
1667 #endif // CC_INTERP
1668 
1669   // Specific initialization.
1670   void post_initialize(BytecodeStream* stream, MethodData* mdo);
1671 
1672   void print_data_on(outputStream* st, const char* extra = NULL) const;
1673 };
1674 
1675 // BranchData
1676 //
1677 // A BranchData is used to access profiling data for a two-way branch.
1678 // It consists of taken and not_taken counts as well as a data displacement
1679 // for the taken case.
1680 class BranchData : public JumpData {

1681 protected:
1682   enum {
1683     not_taken_off_set = jump_cell_count,
1684     branch_cell_count
1685   };
1686 
1687   void set_displacement(int displacement) {
1688     set_int_at(displacement_off_set, displacement);
1689   }
1690 
1691 public:
1692   BranchData(DataLayout* layout) : JumpData(layout) {
1693     assert(layout->tag() == DataLayout::branch_data_tag, "wrong type");
1694   }
1695 
1696   virtual bool is_BranchData() const { return true; }
1697 
1698   static int static_cell_count() {
1699     return branch_cell_count;
1700   }


1737     increment_uint_at_no_overflow(layout, not_taken_off_set);
1738   }
1739 
1740   static DataLayout* advance_not_taken(DataLayout* layout) {
1741     return (DataLayout*) (((address)layout) + (ssize_t)BranchData::branch_data_size_in_bytes());
1742   }
1743 #endif // CC_INTERP
1744 
1745   // Specific initialization.
1746   void post_initialize(BytecodeStream* stream, MethodData* mdo);
1747 
1748   void print_data_on(outputStream* st, const char* extra = NULL) const;
1749 };
1750 
1751 // ArrayData
1752 //
1753 // A ArrayData is a base class for accessing profiling data which does
1754 // not have a statically known size.  It consists of an array length
1755 // and an array start.
1756 class ArrayData : public ProfileData {

1757 protected:
1758   friend class DataLayout;
1759 
1760   enum {
1761     array_len_off_set,
1762     array_start_off_set
1763   };
1764 
1765   uint array_uint_at(int index) const {
1766     int aindex = index + array_start_off_set;
1767     return uint_at(aindex);
1768   }
1769   int array_int_at(int index) const {
1770     int aindex = index + array_start_off_set;
1771     return int_at(aindex);
1772   }
1773   oop array_oop_at(int index) const {
1774     int aindex = index + array_start_off_set;
1775     return oop_at(aindex);
1776   }


1814   virtual int cell_count() const {
1815     return array_len() + 1;
1816   }
1817 
1818   // Code generation support
1819   static ByteSize array_len_offset() {
1820     return cell_offset(array_len_off_set);
1821   }
1822   static ByteSize array_start_offset() {
1823     return cell_offset(array_start_off_set);
1824   }
1825 };
1826 
1827 // MultiBranchData
1828 //
1829 // A MultiBranchData is used to access profiling information for
1830 // a multi-way branch (*switch bytecodes).  It consists of a series
1831 // of (count, displacement) pairs, which count the number of times each
1832 // case was taken and specify the data displacment for each branch target.
1833 class MultiBranchData : public ArrayData {

1834 protected:
1835   enum {
1836     default_count_off_set,
1837     default_disaplacement_off_set,
1838     case_array_start
1839   };
1840   enum {
1841     relative_count_off_set,
1842     relative_displacement_off_set,
1843     per_case_cell_count
1844   };
1845 
1846   void set_default_displacement(int displacement) {
1847     array_set_int_at(default_disaplacement_off_set, displacement);
1848   }
1849   void set_displacement_at(int index, int displacement) {
1850     array_set_int_at(case_array_start +
1851                      index * per_case_cell_count +
1852                      relative_displacement_off_set,
1853                      displacement);




 518   // as well as CIMethodData data. This function is provided for translating
 519   // an oop in a ProfileData to the ci equivalent. Generally speaking,
 520   // most ProfileData don't require any translation, so we provide the null
 521   // translation here, and the required translators are in the ci subclasses.
 522   virtual void translate_from(const ProfileData* data) {}
 523 
 524   virtual void print_data_on(outputStream* st, const char* extra = NULL) const {
 525     ShouldNotReachHere();
 526   }
 527 
 528   void print_data_on(outputStream* st, const MethodData* md) const;
 529 
 530   void print_shared(outputStream* st, const char* name, const char* extra) const;
 531   void tab(outputStream* st, bool first = false) const;
 532 };
 533 
 534 // BitData
 535 //
 536 // A BitData holds a flag or two in its header.
 537 class BitData : public ProfileData {
 538   friend class VMStructs;
 539 protected:
 540   enum {
 541     // null_seen:
 542     //  saw a null operand (cast/aastore/instanceof)
 543       null_seen_flag              = DataLayout::first_flag + 0
 544 #if INCLUDE_JVMCI
 545     // bytecode threw any exception
 546     , exception_seen_flag         = null_seen_flag + 1
 547 #endif
 548   };
 549   enum { bit_cell_count = 0 };  // no additional data fields needed.
 550 public:
 551   BitData(DataLayout* layout) : ProfileData(layout) {
 552   }
 553 
 554   virtual bool is_BitData() const { return true; }
 555 
 556   static int static_cell_count() {
 557     return bit_cell_count;
 558   }


 587   static int bit_data_size_in_bytes() {
 588     return cell_offset_in_bytes(bit_cell_count);
 589   }
 590 
 591   static void set_null_seen(DataLayout* layout) {
 592     set_flag_at(layout, null_seen_flag);
 593   }
 594 
 595   static DataLayout* advance(DataLayout* layout) {
 596     return (DataLayout*) (((address)layout) + (ssize_t)BitData::bit_data_size_in_bytes());
 597   }
 598 #endif // CC_INTERP
 599 
 600   void print_data_on(outputStream* st, const char* extra = NULL) const;
 601 };
 602 
 603 // CounterData
 604 //
 605 // A CounterData corresponds to a simple counter.
 606 class CounterData : public BitData {
 607   friend class VMStructs;
 608 protected:
 609   enum {
 610     count_off,
 611     counter_cell_count
 612   };
 613 public:
 614   CounterData(DataLayout* layout) : BitData(layout) {}
 615 
 616   virtual bool is_CounterData() const { return true; }
 617 
 618   static int static_cell_count() {
 619     return counter_cell_count;
 620   }
 621 
 622   virtual int cell_count() const {
 623     return static_cell_count();
 624   }
 625 
 626   // Direct accessor
 627   uint count() const {


 652   // Support counter decrementation at checkcast / subtype check failed.
 653   static void decrement_count(DataLayout* layout) {
 654     increment_uint_at_no_overflow(layout, count_off, -1);
 655   }
 656 
 657   static DataLayout* advance(DataLayout* layout) {
 658     return (DataLayout*) (((address)layout) + (ssize_t)CounterData::counter_data_size_in_bytes());
 659   }
 660 #endif // CC_INTERP
 661 
 662   void print_data_on(outputStream* st, const char* extra = NULL) const;
 663 };
 664 
 665 // JumpData
 666 //
 667 // A JumpData is used to access profiling information for a direct
 668 // branch.  It is a counter, used for counting the number of branches,
 669 // plus a data displacement, used for realigning the data pointer to
 670 // the corresponding target bci.
 671 class JumpData : public ProfileData {
 672   friend class VMStructs;
 673 protected:
 674   enum {
 675     taken_off_set,
 676     displacement_off_set,
 677     jump_cell_count
 678   };
 679 
 680   void set_displacement(int displacement) {
 681     set_int_at(displacement_off_set, displacement);
 682   }
 683 
 684 public:
 685   JumpData(DataLayout* layout) : ProfileData(layout) {
 686     assert(layout->tag() == DataLayout::jump_data_tag ||
 687       layout->tag() == DataLayout::branch_data_tag, "wrong type");
 688   }
 689 
 690   virtual bool is_JumpData() const { return true; }
 691 
 692   static int static_cell_count() {


1159   // GC support
1160   virtual void clean_weak_klass_links(BoolObjectClosure* is_alive_closure) {
1161     if (has_arguments()) {
1162       _args.clean_weak_klass_links(is_alive_closure);
1163     }
1164     if (has_return()) {
1165       _ret.clean_weak_klass_links(is_alive_closure);
1166     }
1167   }
1168 
1169   virtual void print_data_on(outputStream* st, const char* extra = NULL) const;
1170 };
1171 
1172 // ReceiverTypeData
1173 //
1174 // A ReceiverTypeData is used to access profiling information about a
1175 // dynamic type check.  It consists of a counter which counts the total times
1176 // that the check is reached, and a series of (Klass*, count) pairs
1177 // which are used to store a type profile for the receiver of the check.
1178 class ReceiverTypeData : public CounterData {
1179   friend class VMStructs;
1180 protected:
1181   enum {
1182 #if INCLUDE_JVMCI
1183     // Description of the different counters
1184     // ReceiverTypeData for instanceof/checkcast/aastore:
1185     //   C1/C2: count is incremented on type overflow and decremented for failed type checks
1186     //   JVMCI: count decremented for failed type checks and nonprofiled_count is incremented on type overflow
1187     //          TODO (chaeubl): in fact, JVMCI should also increment the count for failed type checks to mimic the C1/C2 behavior
1188     // VirtualCallData for invokevirtual/invokeinterface:
1189     //   C1/C2: count is incremented on type overflow
1190     //   JVMCI: count is incremented on type overflow, nonprofiled_count is incremented on method overflow
1191 
1192     // JVMCI is interested in knowing the percentage of type checks involving a type not explicitly in the profile
1193     nonprofiled_count_off_set = counter_cell_count,
1194     receiver0_offset,
1195 #else
1196     receiver0_offset = counter_cell_count,
1197 #endif
1198     count0_offset,
1199     receiver_type_row_cell_count = (count0_offset + 1) - receiver0_offset


1665   static ByteSize bci_displacement_offset(uint row) {
1666     return cell_offset(bci_displacement_cell_index(row));
1667   }
1668 
1669 #ifdef CC_INTERP
1670   static DataLayout* advance(MethodData *md, int bci);
1671 #endif // CC_INTERP
1672 
1673   // Specific initialization.
1674   void post_initialize(BytecodeStream* stream, MethodData* mdo);
1675 
1676   void print_data_on(outputStream* st, const char* extra = NULL) const;
1677 };
1678 
1679 // BranchData
1680 //
1681 // A BranchData is used to access profiling data for a two-way branch.
1682 // It consists of taken and not_taken counts as well as a data displacement
1683 // for the taken case.
1684 class BranchData : public JumpData {
1685   friend class VMStructs;
1686 protected:
1687   enum {
1688     not_taken_off_set = jump_cell_count,
1689     branch_cell_count
1690   };
1691 
1692   void set_displacement(int displacement) {
1693     set_int_at(displacement_off_set, displacement);
1694   }
1695 
1696 public:
1697   BranchData(DataLayout* layout) : JumpData(layout) {
1698     assert(layout->tag() == DataLayout::branch_data_tag, "wrong type");
1699   }
1700 
1701   virtual bool is_BranchData() const { return true; }
1702 
1703   static int static_cell_count() {
1704     return branch_cell_count;
1705   }


1742     increment_uint_at_no_overflow(layout, not_taken_off_set);
1743   }
1744 
1745   static DataLayout* advance_not_taken(DataLayout* layout) {
1746     return (DataLayout*) (((address)layout) + (ssize_t)BranchData::branch_data_size_in_bytes());
1747   }
1748 #endif // CC_INTERP
1749 
1750   // Specific initialization.
1751   void post_initialize(BytecodeStream* stream, MethodData* mdo);
1752 
1753   void print_data_on(outputStream* st, const char* extra = NULL) const;
1754 };
1755 
1756 // ArrayData
1757 //
1758 // A ArrayData is a base class for accessing profiling data which does
1759 // not have a statically known size.  It consists of an array length
1760 // and an array start.
1761 class ArrayData : public ProfileData {
1762   friend class VMStructs;
1763 protected:
1764   friend class DataLayout;
1765 
1766   enum {
1767     array_len_off_set,
1768     array_start_off_set
1769   };
1770 
1771   uint array_uint_at(int index) const {
1772     int aindex = index + array_start_off_set;
1773     return uint_at(aindex);
1774   }
1775   int array_int_at(int index) const {
1776     int aindex = index + array_start_off_set;
1777     return int_at(aindex);
1778   }
1779   oop array_oop_at(int index) const {
1780     int aindex = index + array_start_off_set;
1781     return oop_at(aindex);
1782   }


1820   virtual int cell_count() const {
1821     return array_len() + 1;
1822   }
1823 
1824   // Code generation support
1825   static ByteSize array_len_offset() {
1826     return cell_offset(array_len_off_set);
1827   }
1828   static ByteSize array_start_offset() {
1829     return cell_offset(array_start_off_set);
1830   }
1831 };
1832 
1833 // MultiBranchData
1834 //
1835 // A MultiBranchData is used to access profiling information for
1836 // a multi-way branch (*switch bytecodes).  It consists of a series
1837 // of (count, displacement) pairs, which count the number of times each
1838 // case was taken and specify the data displacment for each branch target.
1839 class MultiBranchData : public ArrayData {
1840   friend class VMStructs;
1841 protected:
1842   enum {
1843     default_count_off_set,
1844     default_disaplacement_off_set,
1845     case_array_start
1846   };
1847   enum {
1848     relative_count_off_set,
1849     relative_displacement_off_set,
1850     per_case_cell_count
1851   };
1852 
1853   void set_default_displacement(int displacement) {
1854     array_set_int_at(default_disaplacement_off_set, displacement);
1855   }
1856   void set_displacement_at(int index, int displacement) {
1857     array_set_int_at(case_array_start +
1858                      index * per_case_cell_count +
1859                      relative_displacement_off_set,
1860                      displacement);


< prev index next >