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);
|