Mercurial > hg > graal-jvmci-8
comparison src/cpu/x86/vm/c1_LIRAssembler_x86.cpp @ 1783:d5d065957597
6953144: Tiered compilation
Summary: Infrastructure for tiered compilation support (interpreter + c1 + c2) for 32 and 64 bit. Simple tiered policy implementation.
Reviewed-by: kvn, never, phh, twisti
author | iveresov |
---|---|
date | Fri, 03 Sep 2010 17:51:07 -0700 |
parents | e9ff18c4ace7 |
children | 7f9553bedfd5 |
comparison
equal
deleted
inserted
replaced
1782:f353275af40e | 1783:d5d065957597 |
---|---|
1611 *op->stub()->entry()); | 1611 *op->stub()->entry()); |
1612 } | 1612 } |
1613 __ bind(*op->stub()->continuation()); | 1613 __ bind(*op->stub()->continuation()); |
1614 } | 1614 } |
1615 | 1615 |
1616 | 1616 void LIR_Assembler::type_profile_helper(Register mdo, |
1617 ciMethodData *md, ciProfileData *data, | |
1618 Register recv, Label* update_done) { | |
1619 uint i; | |
1620 for (i = 0; i < ReceiverTypeData::row_limit(); i++) { | |
1621 Label next_test; | |
1622 // See if the receiver is receiver[n]. | |
1623 __ cmpptr(recv, Address(mdo, md->byte_offset_of_slot(data, ReceiverTypeData::receiver_offset(i)))); | |
1624 __ jccb(Assembler::notEqual, next_test); | |
1625 Address data_addr(mdo, md->byte_offset_of_slot(data, ReceiverTypeData::receiver_count_offset(i))); | |
1626 __ addptr(data_addr, DataLayout::counter_increment); | |
1627 __ jmpb(*update_done); | |
1628 __ bind(next_test); | |
1629 } | |
1630 | |
1631 // Didn't find receiver; find next empty slot and fill it in | |
1632 for (i = 0; i < ReceiverTypeData::row_limit(); i++) { | |
1633 Label next_test; | |
1634 Address recv_addr(mdo, md->byte_offset_of_slot(data, ReceiverTypeData::receiver_offset(i))); | |
1635 __ cmpptr(recv_addr, (intptr_t)NULL_WORD); | |
1636 __ jccb(Assembler::notEqual, next_test); | |
1637 __ movptr(recv_addr, recv); | |
1638 __ movptr(Address(mdo, md->byte_offset_of_slot(data, ReceiverTypeData::receiver_count_offset(i))), DataLayout::counter_increment); | |
1639 __ jmpb(*update_done); | |
1640 __ bind(next_test); | |
1641 } | |
1642 } | |
1643 | |
1644 void LIR_Assembler::emit_checkcast(LIR_OpTypeCheck *op) { | |
1645 assert(op->code() == lir_checkcast, "Invalid operation"); | |
1646 // we always need a stub for the failure case. | |
1647 CodeStub* stub = op->stub(); | |
1648 Register obj = op->object()->as_register(); | |
1649 Register k_RInfo = op->tmp1()->as_register(); | |
1650 Register klass_RInfo = op->tmp2()->as_register(); | |
1651 Register dst = op->result_opr()->as_register(); | |
1652 ciKlass* k = op->klass(); | |
1653 Register Rtmp1 = noreg; | |
1654 | |
1655 // check if it needs to be profiled | |
1656 ciMethodData* md; | |
1657 ciProfileData* data; | |
1658 | |
1659 if (op->should_profile()) { | |
1660 ciMethod* method = op->profiled_method(); | |
1661 assert(method != NULL, "Should have method"); | |
1662 int bci = op->profiled_bci(); | |
1663 md = method->method_data(); | |
1664 if (md == NULL) { | |
1665 bailout("out of memory building methodDataOop"); | |
1666 return; | |
1667 } | |
1668 data = md->bci_to_data(bci); | |
1669 assert(data != NULL, "need data for checkcast"); | |
1670 assert(data->is_ReceiverTypeData(), "need ReceiverTypeData for checkcast"); | |
1671 } | |
1672 Label profile_cast_failure; | |
1673 | |
1674 Label done, done_null; | |
1675 // Where to go in case of cast failure | |
1676 Label *failure_target = op->should_profile() ? &profile_cast_failure : stub->entry(); | |
1677 | |
1678 if (obj == k_RInfo) { | |
1679 k_RInfo = dst; | |
1680 } else if (obj == klass_RInfo) { | |
1681 klass_RInfo = dst; | |
1682 } | |
1683 if (k->is_loaded()) { | |
1684 select_different_registers(obj, dst, k_RInfo, klass_RInfo); | |
1685 } else { | |
1686 Rtmp1 = op->tmp3()->as_register(); | |
1687 select_different_registers(obj, dst, k_RInfo, klass_RInfo, Rtmp1); | |
1688 } | |
1689 | |
1690 assert_different_registers(obj, k_RInfo, klass_RInfo); | |
1691 if (!k->is_loaded()) { | |
1692 jobject2reg_with_patching(k_RInfo, op->info_for_patch()); | |
1693 } else { | |
1694 #ifdef _LP64 | |
1695 __ movoop(k_RInfo, k->constant_encoding()); | |
1696 #endif // _LP64 | |
1697 } | |
1698 assert(obj != k_RInfo, "must be different"); | |
1699 | |
1700 __ cmpptr(obj, (int32_t)NULL_WORD); | |
1701 if (op->should_profile()) { | |
1702 Label profile_done; | |
1703 __ jccb(Assembler::notEqual, profile_done); | |
1704 // Object is null; update methodDataOop | |
1705 Register mdo = klass_RInfo; | |
1706 __ movoop(mdo, md->constant_encoding()); | |
1707 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()); | |
1709 __ orl(data_addr, header_bits); | |
1710 __ jmp(done_null); | |
1711 __ bind(profile_done); | |
1712 } else { | |
1713 __ jcc(Assembler::equal, done_null); | |
1714 } | |
1715 __ verify_oop(obj); | |
1716 | |
1717 if (op->fast_check()) { | |
1718 // get object classo | |
1719 // not a safepoint as obj null check happens earlier | |
1720 if (k->is_loaded()) { | |
1721 #ifdef _LP64 | |
1722 __ cmpptr(k_RInfo, Address(obj, oopDesc::klass_offset_in_bytes())); | |
1723 #else | |
1724 __ cmpoop(Address(obj, oopDesc::klass_offset_in_bytes()), k->constant_encoding()); | |
1725 #endif // _LP64 | |
1726 } else { | |
1727 __ cmpptr(k_RInfo, Address(obj, oopDesc::klass_offset_in_bytes())); | |
1728 } | |
1729 __ jcc(Assembler::notEqual, *failure_target); | |
1730 } else { | |
1731 // get object class | |
1732 // not a safepoint as obj null check happens earlier | |
1733 __ movptr(klass_RInfo, Address(obj, oopDesc::klass_offset_in_bytes())); | |
1734 if (k->is_loaded()) { | |
1735 // See if we get an immediate positive hit | |
1736 #ifdef _LP64 | |
1737 __ cmpptr(k_RInfo, Address(klass_RInfo, k->super_check_offset())); | |
1738 #else | |
1739 __ cmpoop(Address(klass_RInfo, k->super_check_offset()), k->constant_encoding()); | |
1740 #endif // _LP64 | |
1741 if (sizeof(oopDesc) + Klass::secondary_super_cache_offset_in_bytes() != k->super_check_offset()) { | |
1742 __ jcc(Assembler::notEqual, *failure_target); | |
1743 } else { | |
1744 // See if we get an immediate positive hit | |
1745 __ jcc(Assembler::equal, done); | |
1746 // check for self | |
1747 #ifdef _LP64 | |
1748 __ cmpptr(klass_RInfo, k_RInfo); | |
1749 #else | |
1750 __ cmpoop(klass_RInfo, k->constant_encoding()); | |
1751 #endif // _LP64 | |
1752 __ jcc(Assembler::equal, done); | |
1753 | |
1754 __ push(klass_RInfo); | |
1755 #ifdef _LP64 | |
1756 __ push(k_RInfo); | |
1757 #else | |
1758 __ pushoop(k->constant_encoding()); | |
1759 #endif // _LP64 | |
1760 __ call(RuntimeAddress(Runtime1::entry_for(Runtime1::slow_subtype_check_id))); | |
1761 __ pop(klass_RInfo); | |
1762 __ pop(klass_RInfo); | |
1763 // result is a boolean | |
1764 __ cmpl(klass_RInfo, 0); | |
1765 __ jcc(Assembler::equal, *failure_target); | |
1766 } | |
1767 } else { | |
1768 // perform the fast part of the checking logic | |
1769 __ check_klass_subtype_fast_path(klass_RInfo, k_RInfo, Rtmp1, &done, failure_target, NULL); | |
1770 // call out-of-line instance of __ check_klass_subtype_slow_path(...): | |
1771 __ push(klass_RInfo); | |
1772 __ push(k_RInfo); | |
1773 __ call(RuntimeAddress(Runtime1::entry_for(Runtime1::slow_subtype_check_id))); | |
1774 __ pop(klass_RInfo); | |
1775 __ pop(k_RInfo); | |
1776 // result is a boolean | |
1777 __ cmpl(k_RInfo, 0); | |
1778 __ jcc(Assembler::equal, *failure_target); | |
1779 } | |
1780 } | |
1781 __ bind(done); | |
1782 | |
1783 if (op->should_profile()) { | |
1784 Register mdo = klass_RInfo, recv = k_RInfo; | |
1785 __ movoop(mdo, md->constant_encoding()); | |
1786 __ movptr(recv, Address(obj, oopDesc::klass_offset_in_bytes())); | |
1787 Label update_done; | |
1788 type_profile_helper(mdo, md, data, recv, &update_done); | |
1789 __ jmpb(update_done); | |
1790 | |
1791 __ bind(profile_cast_failure); | |
1792 __ movoop(mdo, md->constant_encoding()); | |
1793 Address counter_addr(mdo, md->byte_offset_of_slot(data, CounterData::count_offset())); | |
1794 __ subptr(counter_addr, DataLayout::counter_increment); | |
1795 __ jmp(*stub->entry()); | |
1796 | |
1797 __ bind(update_done); | |
1798 } | |
1799 __ bind(done_null); | |
1800 if (dst != obj) { | |
1801 __ mov(dst, obj); | |
1802 } | |
1803 } | |
1617 | 1804 |
1618 void LIR_Assembler::emit_opTypeCheck(LIR_OpTypeCheck* op) { | 1805 void LIR_Assembler::emit_opTypeCheck(LIR_OpTypeCheck* op) { |
1619 LIR_Code code = op->code(); | 1806 LIR_Code code = op->code(); |
1620 if (code == lir_store_check) { | 1807 if (code == lir_store_check) { |
1621 Register value = op->object()->as_register(); | 1808 Register value = op->object()->as_register(); |
1644 __ pop(k_RInfo); | 1831 __ pop(k_RInfo); |
1645 // result is a boolean | 1832 // result is a boolean |
1646 __ cmpl(k_RInfo, 0); | 1833 __ cmpl(k_RInfo, 0); |
1647 __ jcc(Assembler::equal, *stub->entry()); | 1834 __ jcc(Assembler::equal, *stub->entry()); |
1648 __ bind(done); | 1835 __ bind(done); |
1649 } else if (op->code() == lir_checkcast) { | |
1650 // we always need a stub for the failure case. | |
1651 CodeStub* stub = op->stub(); | |
1652 Register obj = op->object()->as_register(); | |
1653 Register k_RInfo = op->tmp1()->as_register(); | |
1654 Register klass_RInfo = op->tmp2()->as_register(); | |
1655 Register dst = op->result_opr()->as_register(); | |
1656 ciKlass* k = op->klass(); | |
1657 Register Rtmp1 = noreg; | |
1658 | |
1659 Label done; | |
1660 if (obj == k_RInfo) { | |
1661 k_RInfo = dst; | |
1662 } else if (obj == klass_RInfo) { | |
1663 klass_RInfo = dst; | |
1664 } | |
1665 if (k->is_loaded()) { | |
1666 select_different_registers(obj, dst, k_RInfo, klass_RInfo); | |
1667 } else { | |
1668 Rtmp1 = op->tmp3()->as_register(); | |
1669 select_different_registers(obj, dst, k_RInfo, klass_RInfo, Rtmp1); | |
1670 } | |
1671 | |
1672 assert_different_registers(obj, k_RInfo, klass_RInfo); | |
1673 if (!k->is_loaded()) { | |
1674 jobject2reg_with_patching(k_RInfo, op->info_for_patch()); | |
1675 } else { | |
1676 #ifdef _LP64 | |
1677 __ movoop(k_RInfo, k->constant_encoding()); | |
1678 #else | |
1679 k_RInfo = noreg; | |
1680 #endif // _LP64 | |
1681 } | |
1682 assert(obj != k_RInfo, "must be different"); | |
1683 __ cmpptr(obj, (int32_t)NULL_WORD); | |
1684 if (op->profiled_method() != NULL) { | |
1685 ciMethod* method = op->profiled_method(); | |
1686 int bci = op->profiled_bci(); | |
1687 | |
1688 Label profile_done; | |
1689 __ jcc(Assembler::notEqual, profile_done); | |
1690 // Object is null; update methodDataOop | |
1691 ciMethodData* md = method->method_data(); | |
1692 if (md == NULL) { | |
1693 bailout("out of memory building methodDataOop"); | |
1694 return; | |
1695 } | |
1696 ciProfileData* data = md->bci_to_data(bci); | |
1697 assert(data != NULL, "need data for checkcast"); | |
1698 assert(data->is_BitData(), "need BitData for checkcast"); | |
1699 Register mdo = klass_RInfo; | |
1700 __ movoop(mdo, md->constant_encoding()); | |
1701 Address data_addr(mdo, md->byte_offset_of_slot(data, DataLayout::header_offset())); | |
1702 int header_bits = DataLayout::flag_mask_to_header_mask(BitData::null_seen_byte_constant()); | |
1703 __ orl(data_addr, header_bits); | |
1704 __ jmp(done); | |
1705 __ bind(profile_done); | |
1706 } else { | |
1707 __ jcc(Assembler::equal, done); | |
1708 } | |
1709 __ verify_oop(obj); | |
1710 | |
1711 if (op->fast_check()) { | |
1712 // get object classo | |
1713 // not a safepoint as obj null check happens earlier | |
1714 if (k->is_loaded()) { | |
1715 #ifdef _LP64 | |
1716 __ cmpptr(k_RInfo, Address(obj, oopDesc::klass_offset_in_bytes())); | |
1717 #else | |
1718 __ cmpoop(Address(obj, oopDesc::klass_offset_in_bytes()), k->constant_encoding()); | |
1719 #endif // _LP64 | |
1720 } else { | |
1721 __ cmpptr(k_RInfo, Address(obj, oopDesc::klass_offset_in_bytes())); | |
1722 | |
1723 } | |
1724 __ jcc(Assembler::notEqual, *stub->entry()); | |
1725 __ bind(done); | |
1726 } else { | |
1727 // get object class | |
1728 // not a safepoint as obj null check happens earlier | |
1729 __ movptr(klass_RInfo, Address(obj, oopDesc::klass_offset_in_bytes())); | |
1730 if (k->is_loaded()) { | |
1731 // See if we get an immediate positive hit | |
1732 #ifdef _LP64 | |
1733 __ cmpptr(k_RInfo, Address(klass_RInfo, k->super_check_offset())); | |
1734 #else | |
1735 __ cmpoop(Address(klass_RInfo, k->super_check_offset()), k->constant_encoding()); | |
1736 #endif // _LP64 | |
1737 if (sizeof(oopDesc) + Klass::secondary_super_cache_offset_in_bytes() != k->super_check_offset()) { | |
1738 __ jcc(Assembler::notEqual, *stub->entry()); | |
1739 } else { | |
1740 // See if we get an immediate positive hit | |
1741 __ jcc(Assembler::equal, done); | |
1742 // check for self | |
1743 #ifdef _LP64 | |
1744 __ cmpptr(klass_RInfo, k_RInfo); | |
1745 #else | |
1746 __ cmpoop(klass_RInfo, k->constant_encoding()); | |
1747 #endif // _LP64 | |
1748 __ jcc(Assembler::equal, done); | |
1749 | |
1750 __ push(klass_RInfo); | |
1751 #ifdef _LP64 | |
1752 __ push(k_RInfo); | |
1753 #else | |
1754 __ pushoop(k->constant_encoding()); | |
1755 #endif // _LP64 | |
1756 __ call(RuntimeAddress(Runtime1::entry_for(Runtime1::slow_subtype_check_id))); | |
1757 __ pop(klass_RInfo); | |
1758 __ pop(klass_RInfo); | |
1759 // result is a boolean | |
1760 __ cmpl(klass_RInfo, 0); | |
1761 __ jcc(Assembler::equal, *stub->entry()); | |
1762 } | |
1763 __ bind(done); | |
1764 } else { | |
1765 // perform the fast part of the checking logic | |
1766 __ check_klass_subtype_fast_path(klass_RInfo, k_RInfo, Rtmp1, &done, stub->entry(), NULL); | |
1767 // call out-of-line instance of __ check_klass_subtype_slow_path(...): | |
1768 __ push(klass_RInfo); | |
1769 __ push(k_RInfo); | |
1770 __ call(RuntimeAddress(Runtime1::entry_for(Runtime1::slow_subtype_check_id))); | |
1771 __ pop(klass_RInfo); | |
1772 __ pop(k_RInfo); | |
1773 // result is a boolean | |
1774 __ cmpl(k_RInfo, 0); | |
1775 __ jcc(Assembler::equal, *stub->entry()); | |
1776 __ bind(done); | |
1777 } | |
1778 | |
1779 } | |
1780 if (dst != obj) { | |
1781 __ mov(dst, obj); | |
1782 } | |
1783 } else if (code == lir_instanceof) { | 1836 } else if (code == lir_instanceof) { |
1784 Register obj = op->object()->as_register(); | 1837 Register obj = op->object()->as_register(); |
1785 Register k_RInfo = op->tmp1()->as_register(); | 1838 Register k_RInfo = op->tmp1()->as_register(); |
1786 Register klass_RInfo = op->tmp2()->as_register(); | 1839 Register klass_RInfo = op->tmp2()->as_register(); |
1787 Register dst = op->result_opr()->as_register(); | 1840 Register dst = op->result_opr()->as_register(); |
1919 #endif // _LP64 | 1972 #endif // _LP64 |
1920 } else { | 1973 } else { |
1921 Unimplemented(); | 1974 Unimplemented(); |
1922 } | 1975 } |
1923 } | 1976 } |
1924 | |
1925 | 1977 |
1926 void LIR_Assembler::cmove(LIR_Condition condition, LIR_Opr opr1, LIR_Opr opr2, LIR_Opr result) { | 1978 void LIR_Assembler::cmove(LIR_Condition condition, LIR_Opr opr1, LIR_Opr opr2, LIR_Opr result) { |
1927 Assembler::Condition acond, ncond; | 1979 Assembler::Condition acond, ncond; |
1928 switch (condition) { | 1980 switch (condition) { |
1929 case lir_cond_equal: acond = Assembler::equal; ncond = Assembler::notEqual; break; | 1981 case lir_cond_equal: acond = Assembler::equal; ncond = Assembler::notEqual; break; |
3251 Address counter_addr(mdo, md->byte_offset_of_slot(data, CounterData::count_offset())); | 3303 Address counter_addr(mdo, md->byte_offset_of_slot(data, CounterData::count_offset())); |
3252 Bytecodes::Code bc = method->java_code_at_bci(bci); | 3304 Bytecodes::Code bc = method->java_code_at_bci(bci); |
3253 // Perform additional virtual call profiling for invokevirtual and | 3305 // Perform additional virtual call profiling for invokevirtual and |
3254 // invokeinterface bytecodes | 3306 // invokeinterface bytecodes |
3255 if ((bc == Bytecodes::_invokevirtual || bc == Bytecodes::_invokeinterface) && | 3307 if ((bc == Bytecodes::_invokevirtual || bc == Bytecodes::_invokeinterface) && |
3256 Tier1ProfileVirtualCalls) { | 3308 C1ProfileVirtualCalls) { |
3257 assert(op->recv()->is_single_cpu(), "recv must be allocated"); | 3309 assert(op->recv()->is_single_cpu(), "recv must be allocated"); |
3258 Register recv = op->recv()->as_register(); | 3310 Register recv = op->recv()->as_register(); |
3259 assert_different_registers(mdo, recv); | 3311 assert_different_registers(mdo, recv); |
3260 assert(data->is_VirtualCallData(), "need VirtualCallData for virtual calls"); | 3312 assert(data->is_VirtualCallData(), "need VirtualCallData for virtual calls"); |
3261 ciKlass* known_klass = op->known_holder(); | 3313 ciKlass* known_klass = op->known_holder(); |
3262 if (Tier1OptimizeVirtualCallProfiling && known_klass != NULL) { | 3314 if (C1OptimizeVirtualCallProfiling && known_klass != NULL) { |
3263 // We know the type that will be seen at this call site; we can | 3315 // We know the type that will be seen at this call site; we can |
3264 // statically update the methodDataOop rather than needing to do | 3316 // statically update the methodDataOop rather than needing to do |
3265 // dynamic tests on the receiver type | 3317 // dynamic tests on the receiver type |
3266 | 3318 |
3267 // NOTE: we should probably put a lock around this search to | 3319 // NOTE: we should probably put a lock around this search to |
3270 uint i; | 3322 uint i; |
3271 for (i = 0; i < VirtualCallData::row_limit(); i++) { | 3323 for (i = 0; i < VirtualCallData::row_limit(); i++) { |
3272 ciKlass* receiver = vc_data->receiver(i); | 3324 ciKlass* receiver = vc_data->receiver(i); |
3273 if (known_klass->equals(receiver)) { | 3325 if (known_klass->equals(receiver)) { |
3274 Address data_addr(mdo, md->byte_offset_of_slot(data, VirtualCallData::receiver_count_offset(i))); | 3326 Address data_addr(mdo, md->byte_offset_of_slot(data, VirtualCallData::receiver_count_offset(i))); |
3275 __ addl(data_addr, DataLayout::counter_increment); | 3327 __ addptr(data_addr, DataLayout::counter_increment); |
3276 return; | 3328 return; |
3277 } | 3329 } |
3278 } | 3330 } |
3279 | 3331 |
3280 // Receiver type not found in profile data; select an empty slot | 3332 // Receiver type not found in profile data; select an empty slot |
3286 ciKlass* receiver = vc_data->receiver(i); | 3338 ciKlass* receiver = vc_data->receiver(i); |
3287 if (receiver == NULL) { | 3339 if (receiver == NULL) { |
3288 Address recv_addr(mdo, md->byte_offset_of_slot(data, VirtualCallData::receiver_offset(i))); | 3340 Address recv_addr(mdo, md->byte_offset_of_slot(data, VirtualCallData::receiver_offset(i))); |
3289 __ movoop(recv_addr, known_klass->constant_encoding()); | 3341 __ movoop(recv_addr, known_klass->constant_encoding()); |
3290 Address data_addr(mdo, md->byte_offset_of_slot(data, VirtualCallData::receiver_count_offset(i))); | 3342 Address data_addr(mdo, md->byte_offset_of_slot(data, VirtualCallData::receiver_count_offset(i))); |
3291 __ addl(data_addr, DataLayout::counter_increment); | 3343 __ addptr(data_addr, DataLayout::counter_increment); |
3292 return; | 3344 return; |
3293 } | 3345 } |
3294 } | 3346 } |
3295 } else { | 3347 } else { |
3296 __ movptr(recv, Address(recv, oopDesc::klass_offset_in_bytes())); | 3348 __ movptr(recv, Address(recv, oopDesc::klass_offset_in_bytes())); |
3297 Label update_done; | 3349 Label update_done; |
3298 uint i; | 3350 type_profile_helper(mdo, md, data, recv, &update_done); |
3299 for (i = 0; i < VirtualCallData::row_limit(); i++) { | |
3300 Label next_test; | |
3301 // See if the receiver is receiver[n]. | |
3302 __ cmpptr(recv, Address(mdo, md->byte_offset_of_slot(data, VirtualCallData::receiver_offset(i)))); | |
3303 __ jcc(Assembler::notEqual, next_test); | |
3304 Address data_addr(mdo, md->byte_offset_of_slot(data, VirtualCallData::receiver_count_offset(i))); | |
3305 __ addl(data_addr, DataLayout::counter_increment); | |
3306 __ jmp(update_done); | |
3307 __ bind(next_test); | |
3308 } | |
3309 | |
3310 // Didn't find receiver; find next empty slot and fill it in | |
3311 for (i = 0; i < VirtualCallData::row_limit(); i++) { | |
3312 Label next_test; | |
3313 Address recv_addr(mdo, md->byte_offset_of_slot(data, VirtualCallData::receiver_offset(i))); | |
3314 __ cmpptr(recv_addr, (int32_t)NULL_WORD); | |
3315 __ jcc(Assembler::notEqual, next_test); | |
3316 __ movptr(recv_addr, recv); | |
3317 __ movl(Address(mdo, md->byte_offset_of_slot(data, VirtualCallData::receiver_count_offset(i))), DataLayout::counter_increment); | |
3318 __ jmp(update_done); | |
3319 __ bind(next_test); | |
3320 } | |
3321 // Receiver did not match any saved receiver and there is no empty row for it. | 3351 // Receiver did not match any saved receiver and there is no empty row for it. |
3322 // Increment total counter to indicate polymorphic case. | 3352 // Increment total counter to indicate polymorphic case. |
3323 __ addl(counter_addr, DataLayout::counter_increment); | 3353 __ addptr(counter_addr, DataLayout::counter_increment); |
3324 | 3354 |
3325 __ bind(update_done); | 3355 __ bind(update_done); |
3326 } | 3356 } |
3327 } else { | 3357 } else { |
3328 // Static call | 3358 // Static call |
3329 __ addl(counter_addr, DataLayout::counter_increment); | 3359 __ addptr(counter_addr, DataLayout::counter_increment); |
3330 } | 3360 } |
3331 } | 3361 } |
3332 | |
3333 | 3362 |
3334 void LIR_Assembler::emit_delay(LIR_OpDelay*) { | 3363 void LIR_Assembler::emit_delay(LIR_OpDelay*) { |
3335 Unimplemented(); | 3364 Unimplemented(); |
3336 } | 3365 } |
3337 | 3366 |