Mercurial > hg > truffle
comparison src/cpu/x86/vm/c1_LIRAssembler_x86.cpp @ 1791:3a294e483abc
6919069: client compiler needs to capture more profile information for tiered work
Summary: Added profiling of instanceof and aastore.
Reviewed-by: kvn, jrose, never
author | iveresov |
---|---|
date | Mon, 13 Sep 2010 12:10:49 -0700 |
parents | 7f9553bedfd5 |
children | 5511edd5d719 a3f7f95b0165 |
comparison
equal
deleted
inserted
replaced
1790:7f9553bedfd5 | 1791:3a294e483abc |
---|---|
1622 // See if the receiver is receiver[n]. | 1622 // See if the receiver is receiver[n]. |
1623 __ cmpptr(recv, Address(mdo, md->byte_offset_of_slot(data, ReceiverTypeData::receiver_offset(i)))); | 1623 __ cmpptr(recv, Address(mdo, md->byte_offset_of_slot(data, ReceiverTypeData::receiver_offset(i)))); |
1624 __ jccb(Assembler::notEqual, next_test); | 1624 __ jccb(Assembler::notEqual, next_test); |
1625 Address data_addr(mdo, md->byte_offset_of_slot(data, ReceiverTypeData::receiver_count_offset(i))); | 1625 Address data_addr(mdo, md->byte_offset_of_slot(data, ReceiverTypeData::receiver_count_offset(i))); |
1626 __ addptr(data_addr, DataLayout::counter_increment); | 1626 __ addptr(data_addr, DataLayout::counter_increment); |
1627 __ jmpb(*update_done); | 1627 __ jmp(*update_done); |
1628 __ bind(next_test); | 1628 __ bind(next_test); |
1629 } | 1629 } |
1630 | 1630 |
1631 // Didn't find receiver; find next empty slot and fill it in | 1631 // Didn't find receiver; find next empty slot and fill it in |
1632 for (i = 0; i < ReceiverTypeData::row_limit(); i++) { | 1632 for (i = 0; i < ReceiverTypeData::row_limit(); i++) { |
1634 Address recv_addr(mdo, md->byte_offset_of_slot(data, ReceiverTypeData::receiver_offset(i))); | 1634 Address recv_addr(mdo, md->byte_offset_of_slot(data, ReceiverTypeData::receiver_offset(i))); |
1635 __ cmpptr(recv_addr, (intptr_t)NULL_WORD); | 1635 __ cmpptr(recv_addr, (intptr_t)NULL_WORD); |
1636 __ jccb(Assembler::notEqual, next_test); | 1636 __ jccb(Assembler::notEqual, next_test); |
1637 __ movptr(recv_addr, recv); | 1637 __ movptr(recv_addr, recv); |
1638 __ movptr(Address(mdo, md->byte_offset_of_slot(data, ReceiverTypeData::receiver_count_offset(i))), DataLayout::counter_increment); | 1638 __ movptr(Address(mdo, md->byte_offset_of_slot(data, ReceiverTypeData::receiver_count_offset(i))), DataLayout::counter_increment); |
1639 __ jmpb(*update_done); | 1639 __ jmp(*update_done); |
1640 __ bind(next_test); | 1640 __ bind(next_test); |
1641 } | 1641 } |
1642 } | 1642 } |
1643 | 1643 |
1644 void LIR_Assembler::emit_checkcast(LIR_OpTypeCheck *op) { | 1644 void LIR_Assembler::emit_typecheck_helper(LIR_OpTypeCheck *op, Label* success, Label* failure, Label* obj_is_null) { |
1645 assert(op->code() == lir_checkcast, "Invalid operation"); | |
1646 // we always need a stub for the failure case. | 1645 // we always need a stub for the failure case. |
1647 CodeStub* stub = op->stub(); | 1646 CodeStub* stub = op->stub(); |
1648 Register obj = op->object()->as_register(); | 1647 Register obj = op->object()->as_register(); |
1649 Register k_RInfo = op->tmp1()->as_register(); | 1648 Register k_RInfo = op->tmp1()->as_register(); |
1650 Register klass_RInfo = op->tmp2()->as_register(); | 1649 Register klass_RInfo = op->tmp2()->as_register(); |
1664 if (md == NULL) { | 1663 if (md == NULL) { |
1665 bailout("out of memory building methodDataOop"); | 1664 bailout("out of memory building methodDataOop"); |
1666 return; | 1665 return; |
1667 } | 1666 } |
1668 data = md->bci_to_data(bci); | 1667 data = md->bci_to_data(bci); |
1669 assert(data != NULL, "need data for checkcast"); | 1668 assert(data != NULL, "need data for type check"); |
1670 assert(data->is_ReceiverTypeData(), "need ReceiverTypeData for checkcast"); | 1669 assert(data->is_ReceiverTypeData(), "need ReceiverTypeData for type check"); |
1671 } | 1670 } |
1672 Label profile_cast_failure; | 1671 Label profile_cast_success, profile_cast_failure; |
1673 | 1672 Label *success_target = op->should_profile() ? &profile_cast_success : success; |
1674 Label done, done_null; | 1673 Label *failure_target = op->should_profile() ? &profile_cast_failure : failure; |
1675 // Where to go in case of cast failure | |
1676 Label *failure_target = op->should_profile() ? &profile_cast_failure : stub->entry(); | |
1677 | 1674 |
1678 if (obj == k_RInfo) { | 1675 if (obj == k_RInfo) { |
1679 k_RInfo = dst; | 1676 k_RInfo = dst; |
1680 } else if (obj == klass_RInfo) { | 1677 } else if (obj == klass_RInfo) { |
1681 klass_RInfo = dst; | 1678 klass_RInfo = dst; |
1697 } | 1694 } |
1698 assert(obj != k_RInfo, "must be different"); | 1695 assert(obj != k_RInfo, "must be different"); |
1699 | 1696 |
1700 __ cmpptr(obj, (int32_t)NULL_WORD); | 1697 __ cmpptr(obj, (int32_t)NULL_WORD); |
1701 if (op->should_profile()) { | 1698 if (op->should_profile()) { |
1702 Label profile_done; | 1699 Label not_null; |
1703 __ jccb(Assembler::notEqual, profile_done); | 1700 __ jccb(Assembler::notEqual, not_null); |
1704 // Object is null; update methodDataOop | 1701 // Object is null; update MDO and exit |
1705 Register mdo = klass_RInfo; | 1702 Register mdo = klass_RInfo; |
1706 __ movoop(mdo, md->constant_encoding()); | 1703 __ movoop(mdo, md->constant_encoding()); |
1707 Address data_addr(mdo, md->byte_offset_of_slot(data, DataLayout::header_offset())); | 1704 Address data_addr(mdo, md->byte_offset_of_slot(data, DataLayout::header_offset())); |
1708 int header_bits = DataLayout::flag_mask_to_header_mask(BitData::null_seen_byte_constant()); | 1705 int header_bits = DataLayout::flag_mask_to_header_mask(BitData::null_seen_byte_constant()); |
1709 __ orl(data_addr, header_bits); | 1706 __ orl(data_addr, header_bits); |
1710 __ jmp(done_null); | 1707 __ jmp(*obj_is_null); |
1711 __ bind(profile_done); | 1708 __ bind(not_null); |
1712 } else { | 1709 } else { |
1713 __ jcc(Assembler::equal, done_null); | 1710 __ jcc(Assembler::equal, *obj_is_null); |
1714 } | 1711 } |
1715 __ verify_oop(obj); | 1712 __ verify_oop(obj); |
1716 | 1713 |
1717 if (op->fast_check()) { | 1714 if (op->fast_check()) { |
1718 // get object classo | 1715 // get object class |
1719 // not a safepoint as obj null check happens earlier | 1716 // not a safepoint as obj null check happens earlier |
1720 if (k->is_loaded()) { | 1717 if (k->is_loaded()) { |
1721 #ifdef _LP64 | 1718 #ifdef _LP64 |
1722 __ cmpptr(k_RInfo, Address(obj, oopDesc::klass_offset_in_bytes())); | 1719 __ cmpptr(k_RInfo, Address(obj, oopDesc::klass_offset_in_bytes())); |
1723 #else | 1720 #else |
1725 #endif // _LP64 | 1722 #endif // _LP64 |
1726 } else { | 1723 } else { |
1727 __ cmpptr(k_RInfo, Address(obj, oopDesc::klass_offset_in_bytes())); | 1724 __ cmpptr(k_RInfo, Address(obj, oopDesc::klass_offset_in_bytes())); |
1728 } | 1725 } |
1729 __ jcc(Assembler::notEqual, *failure_target); | 1726 __ jcc(Assembler::notEqual, *failure_target); |
1727 // successful cast, fall through to profile or jump | |
1730 } else { | 1728 } else { |
1731 // get object class | 1729 // get object class |
1732 // not a safepoint as obj null check happens earlier | 1730 // not a safepoint as obj null check happens earlier |
1733 __ movptr(klass_RInfo, Address(obj, oopDesc::klass_offset_in_bytes())); | 1731 __ movptr(klass_RInfo, Address(obj, oopDesc::klass_offset_in_bytes())); |
1734 if (k->is_loaded()) { | 1732 if (k->is_loaded()) { |
1738 #else | 1736 #else |
1739 __ cmpoop(Address(klass_RInfo, k->super_check_offset()), k->constant_encoding()); | 1737 __ cmpoop(Address(klass_RInfo, k->super_check_offset()), k->constant_encoding()); |
1740 #endif // _LP64 | 1738 #endif // _LP64 |
1741 if (sizeof(oopDesc) + Klass::secondary_super_cache_offset_in_bytes() != k->super_check_offset()) { | 1739 if (sizeof(oopDesc) + Klass::secondary_super_cache_offset_in_bytes() != k->super_check_offset()) { |
1742 __ jcc(Assembler::notEqual, *failure_target); | 1740 __ jcc(Assembler::notEqual, *failure_target); |
1741 // successful cast, fall through to profile or jump | |
1743 } else { | 1742 } else { |
1744 // See if we get an immediate positive hit | 1743 // See if we get an immediate positive hit |
1745 __ jcc(Assembler::equal, done); | 1744 __ jcc(Assembler::equal, *success_target); |
1746 // check for self | 1745 // check for self |
1747 #ifdef _LP64 | 1746 #ifdef _LP64 |
1748 __ cmpptr(klass_RInfo, k_RInfo); | 1747 __ cmpptr(klass_RInfo, k_RInfo); |
1749 #else | 1748 #else |
1750 __ cmpoop(klass_RInfo, k->constant_encoding()); | 1749 __ cmpoop(klass_RInfo, k->constant_encoding()); |
1751 #endif // _LP64 | 1750 #endif // _LP64 |
1752 __ jcc(Assembler::equal, done); | 1751 __ jcc(Assembler::equal, *success_target); |
1753 | 1752 |
1754 __ push(klass_RInfo); | 1753 __ push(klass_RInfo); |
1755 #ifdef _LP64 | 1754 #ifdef _LP64 |
1756 __ push(k_RInfo); | 1755 __ push(k_RInfo); |
1757 #else | 1756 #else |
1761 __ pop(klass_RInfo); | 1760 __ pop(klass_RInfo); |
1762 __ pop(klass_RInfo); | 1761 __ pop(klass_RInfo); |
1763 // result is a boolean | 1762 // result is a boolean |
1764 __ cmpl(klass_RInfo, 0); | 1763 __ cmpl(klass_RInfo, 0); |
1765 __ jcc(Assembler::equal, *failure_target); | 1764 __ jcc(Assembler::equal, *failure_target); |
1765 // successful cast, fall through to profile or jump | |
1766 } | 1766 } |
1767 } else { | 1767 } else { |
1768 // perform the fast part of the checking logic | 1768 // perform the fast part of the checking logic |
1769 __ check_klass_subtype_fast_path(klass_RInfo, k_RInfo, Rtmp1, &done, failure_target, NULL); | 1769 __ check_klass_subtype_fast_path(klass_RInfo, k_RInfo, Rtmp1, success_target, failure_target, NULL); |
1770 // call out-of-line instance of __ check_klass_subtype_slow_path(...): | 1770 // call out-of-line instance of __ check_klass_subtype_slow_path(...): |
1771 __ push(klass_RInfo); | 1771 __ push(klass_RInfo); |
1772 __ push(k_RInfo); | 1772 __ push(k_RInfo); |
1773 __ call(RuntimeAddress(Runtime1::entry_for(Runtime1::slow_subtype_check_id))); | 1773 __ call(RuntimeAddress(Runtime1::entry_for(Runtime1::slow_subtype_check_id))); |
1774 __ pop(klass_RInfo); | 1774 __ pop(klass_RInfo); |
1775 __ pop(k_RInfo); | 1775 __ pop(k_RInfo); |
1776 // result is a boolean | 1776 // result is a boolean |
1777 __ cmpl(k_RInfo, 0); | 1777 __ cmpl(k_RInfo, 0); |
1778 __ jcc(Assembler::equal, *failure_target); | 1778 __ jcc(Assembler::equal, *failure_target); |
1779 } | 1779 // successful cast, fall through to profile or jump |
1780 } | 1780 } |
1781 __ bind(done); | 1781 } |
1782 | |
1783 if (op->should_profile()) { | 1782 if (op->should_profile()) { |
1784 Register mdo = klass_RInfo, recv = k_RInfo; | 1783 Register mdo = klass_RInfo, recv = k_RInfo; |
1784 __ bind(profile_cast_success); | |
1785 __ movoop(mdo, md->constant_encoding()); | 1785 __ movoop(mdo, md->constant_encoding()); |
1786 __ movptr(recv, Address(obj, oopDesc::klass_offset_in_bytes())); | 1786 __ movptr(recv, Address(obj, oopDesc::klass_offset_in_bytes())); |
1787 Label update_done; | 1787 Label update_done; |
1788 type_profile_helper(mdo, md, data, recv, &update_done); | 1788 type_profile_helper(mdo, md, data, recv, success); |
1789 __ jmpb(update_done); | 1789 __ jmp(*success); |
1790 | 1790 |
1791 __ bind(profile_cast_failure); | 1791 __ bind(profile_cast_failure); |
1792 __ movoop(mdo, md->constant_encoding()); | 1792 __ movoop(mdo, md->constant_encoding()); |
1793 Address counter_addr(mdo, md->byte_offset_of_slot(data, CounterData::count_offset())); | 1793 Address counter_addr(mdo, md->byte_offset_of_slot(data, CounterData::count_offset())); |
1794 __ subptr(counter_addr, DataLayout::counter_increment); | 1794 __ subptr(counter_addr, DataLayout::counter_increment); |
1795 __ jmp(*stub->entry()); | 1795 __ jmp(*failure); |
1796 | 1796 } |
1797 __ bind(update_done); | 1797 __ jmp(*success); |
1798 } | 1798 } |
1799 __ bind(done_null); | 1799 |
1800 if (dst != obj) { | |
1801 __ mov(dst, obj); | |
1802 } | |
1803 } | |
1804 | 1800 |
1805 void LIR_Assembler::emit_opTypeCheck(LIR_OpTypeCheck* op) { | 1801 void LIR_Assembler::emit_opTypeCheck(LIR_OpTypeCheck* op) { |
1806 LIR_Code code = op->code(); | 1802 LIR_Code code = op->code(); |
1807 if (code == lir_store_check) { | 1803 if (code == lir_store_check) { |
1808 Register value = op->object()->as_register(); | 1804 Register value = op->object()->as_register(); |
1810 Register k_RInfo = op->tmp1()->as_register(); | 1806 Register k_RInfo = op->tmp1()->as_register(); |
1811 Register klass_RInfo = op->tmp2()->as_register(); | 1807 Register klass_RInfo = op->tmp2()->as_register(); |
1812 Register Rtmp1 = op->tmp3()->as_register(); | 1808 Register Rtmp1 = op->tmp3()->as_register(); |
1813 | 1809 |
1814 CodeStub* stub = op->stub(); | 1810 CodeStub* stub = op->stub(); |
1815 Label done; | 1811 |
1812 // check if it needs to be profiled | |
1813 ciMethodData* md; | |
1814 ciProfileData* data; | |
1815 | |
1816 if (op->should_profile()) { | |
1817 ciMethod* method = op->profiled_method(); | |
1818 assert(method != NULL, "Should have method"); | |
1819 int bci = op->profiled_bci(); | |
1820 md = method->method_data(); | |
1821 if (md == NULL) { | |
1822 bailout("out of memory building methodDataOop"); | |
1823 return; | |
1824 } | |
1825 data = md->bci_to_data(bci); | |
1826 assert(data != NULL, "need data for type check"); | |
1827 assert(data->is_ReceiverTypeData(), "need ReceiverTypeData for type check"); | |
1828 } | |
1829 Label profile_cast_success, profile_cast_failure, done; | |
1830 Label *success_target = op->should_profile() ? &profile_cast_success : &done; | |
1831 Label *failure_target = op->should_profile() ? &profile_cast_failure : stub->entry(); | |
1832 | |
1816 __ cmpptr(value, (int32_t)NULL_WORD); | 1833 __ cmpptr(value, (int32_t)NULL_WORD); |
1817 __ jcc(Assembler::equal, done); | 1834 if (op->should_profile()) { |
1835 Label not_null; | |
1836 __ jccb(Assembler::notEqual, not_null); | |
1837 // Object is null; update MDO and exit | |
1838 Register mdo = klass_RInfo; | |
1839 __ movoop(mdo, md->constant_encoding()); | |
1840 Address data_addr(mdo, md->byte_offset_of_slot(data, DataLayout::header_offset())); | |
1841 int header_bits = DataLayout::flag_mask_to_header_mask(BitData::null_seen_byte_constant()); | |
1842 __ orl(data_addr, header_bits); | |
1843 __ jmp(done); | |
1844 __ bind(not_null); | |
1845 } else { | |
1846 __ jcc(Assembler::equal, done); | |
1847 } | |
1848 | |
1818 add_debug_info_for_null_check_here(op->info_for_exception()); | 1849 add_debug_info_for_null_check_here(op->info_for_exception()); |
1819 __ movptr(k_RInfo, Address(array, oopDesc::klass_offset_in_bytes())); | 1850 __ movptr(k_RInfo, Address(array, oopDesc::klass_offset_in_bytes())); |
1820 __ movptr(klass_RInfo, Address(value, oopDesc::klass_offset_in_bytes())); | 1851 __ movptr(klass_RInfo, Address(value, oopDesc::klass_offset_in_bytes())); |
1821 | 1852 |
1822 // get instance klass | 1853 // get instance klass |
1823 __ movptr(k_RInfo, Address(k_RInfo, objArrayKlass::element_klass_offset_in_bytes() + sizeof(oopDesc))); | 1854 __ movptr(k_RInfo, Address(k_RInfo, objArrayKlass::element_klass_offset_in_bytes() + sizeof(oopDesc))); |
1824 // perform the fast part of the checking logic | 1855 // perform the fast part of the checking logic |
1825 __ check_klass_subtype_fast_path(klass_RInfo, k_RInfo, Rtmp1, &done, stub->entry(), NULL); | 1856 __ check_klass_subtype_fast_path(klass_RInfo, k_RInfo, Rtmp1, success_target, failure_target, NULL); |
1826 // call out-of-line instance of __ check_klass_subtype_slow_path(...): | 1857 // call out-of-line instance of __ check_klass_subtype_slow_path(...): |
1827 __ push(klass_RInfo); | 1858 __ push(klass_RInfo); |
1828 __ push(k_RInfo); | 1859 __ push(k_RInfo); |
1829 __ call(RuntimeAddress(Runtime1::entry_for(Runtime1::slow_subtype_check_id))); | 1860 __ call(RuntimeAddress(Runtime1::entry_for(Runtime1::slow_subtype_check_id))); |
1830 __ pop(klass_RInfo); | 1861 __ pop(klass_RInfo); |
1831 __ pop(k_RInfo); | 1862 __ pop(k_RInfo); |
1832 // result is a boolean | 1863 // result is a boolean |
1833 __ cmpl(k_RInfo, 0); | 1864 __ cmpl(k_RInfo, 0); |
1834 __ jcc(Assembler::equal, *stub->entry()); | 1865 __ jcc(Assembler::equal, *failure_target); |
1866 // fall through to the success case | |
1867 | |
1868 if (op->should_profile()) { | |
1869 Register mdo = klass_RInfo, recv = k_RInfo; | |
1870 __ bind(profile_cast_success); | |
1871 __ movoop(mdo, md->constant_encoding()); | |
1872 __ movptr(recv, Address(value, oopDesc::klass_offset_in_bytes())); | |
1873 Label update_done; | |
1874 type_profile_helper(mdo, md, data, recv, &done); | |
1875 __ jmpb(done); | |
1876 | |
1877 __ bind(profile_cast_failure); | |
1878 __ movoop(mdo, md->constant_encoding()); | |
1879 Address counter_addr(mdo, md->byte_offset_of_slot(data, CounterData::count_offset())); | |
1880 __ subptr(counter_addr, DataLayout::counter_increment); | |
1881 __ jmp(*stub->entry()); | |
1882 } | |
1883 | |
1835 __ bind(done); | 1884 __ bind(done); |
1836 } else if (code == lir_instanceof) { | 1885 } else |
1837 Register obj = op->object()->as_register(); | 1886 if (code == lir_checkcast) { |
1838 Register k_RInfo = op->tmp1()->as_register(); | 1887 Register obj = op->object()->as_register(); |
1839 Register klass_RInfo = op->tmp2()->as_register(); | 1888 Register dst = op->result_opr()->as_register(); |
1840 Register dst = op->result_opr()->as_register(); | 1889 Label success; |
1841 ciKlass* k = op->klass(); | 1890 emit_typecheck_helper(op, &success, op->stub()->entry(), &success); |
1842 | 1891 __ bind(success); |
1843 Label done; | 1892 if (dst != obj) { |
1844 Label zero; | 1893 __ mov(dst, obj); |
1845 Label one; | 1894 } |
1846 if (obj == k_RInfo) { | 1895 } else |
1847 k_RInfo = klass_RInfo; | 1896 if (code == lir_instanceof) { |
1848 klass_RInfo = obj; | 1897 Register obj = op->object()->as_register(); |
1849 } | 1898 Register dst = op->result_opr()->as_register(); |
1850 // patching may screw with our temporaries on sparc, | 1899 Label success, failure, done; |
1851 // so let's do it before loading the class | 1900 emit_typecheck_helper(op, &success, &failure, &failure); |
1852 if (!k->is_loaded()) { | 1901 __ bind(failure); |
1853 jobject2reg_with_patching(k_RInfo, op->info_for_patch()); | 1902 __ xorptr(dst, dst); |
1854 } else { | 1903 __ jmpb(done); |
1855 LP64_ONLY(__ movoop(k_RInfo, k->constant_encoding())); | 1904 __ bind(success); |
1856 } | 1905 __ movptr(dst, 1); |
1857 assert(obj != k_RInfo, "must be different"); | 1906 __ bind(done); |
1858 | |
1859 __ verify_oop(obj); | |
1860 if (op->fast_check()) { | |
1861 __ cmpptr(obj, (int32_t)NULL_WORD); | |
1862 __ jcc(Assembler::equal, zero); | |
1863 // get object class | |
1864 // not a safepoint as obj null check happens earlier | |
1865 if (LP64_ONLY(false &&) k->is_loaded()) { | |
1866 NOT_LP64(__ cmpoop(Address(obj, oopDesc::klass_offset_in_bytes()), k->constant_encoding())); | |
1867 k_RInfo = noreg; | |
1868 } else { | 1907 } else { |
1869 __ cmpptr(k_RInfo, Address(obj, oopDesc::klass_offset_in_bytes())); | 1908 ShouldNotReachHere(); |
1870 | 1909 } |
1871 } | |
1872 __ jcc(Assembler::equal, one); | |
1873 } else { | |
1874 // get object class | |
1875 // not a safepoint as obj null check happens earlier | |
1876 __ cmpptr(obj, (int32_t)NULL_WORD); | |
1877 __ jcc(Assembler::equal, zero); | |
1878 __ movptr(klass_RInfo, Address(obj, oopDesc::klass_offset_in_bytes())); | |
1879 | |
1880 #ifndef _LP64 | |
1881 if (k->is_loaded()) { | |
1882 // See if we get an immediate positive hit | |
1883 __ cmpoop(Address(klass_RInfo, k->super_check_offset()), k->constant_encoding()); | |
1884 __ jcc(Assembler::equal, one); | |
1885 if (sizeof(oopDesc) + Klass::secondary_super_cache_offset_in_bytes() == k->super_check_offset()) { | |
1886 // check for self | |
1887 __ cmpoop(klass_RInfo, k->constant_encoding()); | |
1888 __ jcc(Assembler::equal, one); | |
1889 __ push(klass_RInfo); | |
1890 __ pushoop(k->constant_encoding()); | |
1891 __ call(RuntimeAddress(Runtime1::entry_for(Runtime1::slow_subtype_check_id))); | |
1892 __ pop(klass_RInfo); | |
1893 __ pop(dst); | |
1894 __ jmp(done); | |
1895 } | |
1896 } | |
1897 else // next block is unconditional if LP64: | |
1898 #endif // LP64 | |
1899 { | |
1900 assert(dst != klass_RInfo && dst != k_RInfo, "need 3 registers"); | |
1901 | |
1902 // perform the fast part of the checking logic | |
1903 __ check_klass_subtype_fast_path(klass_RInfo, k_RInfo, dst, &one, &zero, NULL); | |
1904 // call out-of-line instance of __ check_klass_subtype_slow_path(...): | |
1905 __ push(klass_RInfo); | |
1906 __ push(k_RInfo); | |
1907 __ call(RuntimeAddress(Runtime1::entry_for(Runtime1::slow_subtype_check_id))); | |
1908 __ pop(klass_RInfo); | |
1909 __ pop(dst); | |
1910 __ jmp(done); | |
1911 } | |
1912 } | |
1913 __ bind(zero); | |
1914 __ xorptr(dst, dst); | |
1915 __ jmp(done); | |
1916 __ bind(one); | |
1917 __ movptr(dst, 1); | |
1918 __ bind(done); | |
1919 } else { | |
1920 ShouldNotReachHere(); | |
1921 } | |
1922 | 1910 |
1923 } | 1911 } |
1924 | 1912 |
1925 | 1913 |
1926 void LIR_Assembler::emit_compare_and_swap(LIR_OpCompareAndSwap* op) { | 1914 void LIR_Assembler::emit_compare_and_swap(LIR_OpCompareAndSwap* op) { |