Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(2)

Side by Side Diff: src/ia32/ic-ia32.cc

Issue 3046006: Inline in-object property stores when in loop and not in top-level (Closed) Base URL: http://v8.googlecode.com/svn/branches/bleeding_edge/
Patch Set: '' Created 10 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « src/ia32/codegen-ia32.cc ('k') | src/ia32/macro-assembler-ia32.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2010 the V8 project authors. All rights reserved. 1 // Copyright 2010 the V8 project authors. All rights reserved.
2 // Redistribution and use in source and binary forms, with or without 2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are 3 // modification, are permitted provided that the following conditions are
4 // met: 4 // met:
5 // 5 //
6 // * Redistributions of source code must retain the above copyright 6 // * Redistributions of source code must retain the above copyright
7 // notice, this list of conditions and the following disclaimer. 7 // notice, this list of conditions and the following disclaimer.
8 // * Redistributions in binary form must reproduce the above 8 // * Redistributions in binary form must reproduce the above
9 // copyright notice, this list of conditions and the following 9 // copyright notice, this list of conditions and the following
10 // disclaimer in the documentation and/or other materials provided 10 // disclaimer in the documentation and/or other materials provided
(...skipping 1626 matching lines...) Expand 10 before | Expand all | Expand 10 after
1637 1637
1638 // Perform tail call to the entry. 1638 // Perform tail call to the entry.
1639 ExternalReference ref = ExternalReference(IC_Utility(kLoadIC_Miss)); 1639 ExternalReference ref = ExternalReference(IC_Utility(kLoadIC_Miss));
1640 __ TailCallExternalReference(ref, 2, 1); 1640 __ TailCallExternalReference(ref, 2, 1);
1641 } 1641 }
1642 1642
1643 1643
1644 // One byte opcode for test eax,0xXXXXXXXX. 1644 // One byte opcode for test eax,0xXXXXXXXX.
1645 static const byte kTestEaxByte = 0xA9; 1645 static const byte kTestEaxByte = 0xA9;
1646 1646
1647
1648 void LoadIC::ClearInlinedVersion(Address address) {
1649 // Reset the map check of the inlined inobject property load (if
1650 // present) to guarantee failure by holding an invalid map (the null
1651 // value). The offset can be patched to anything.
1652 PatchInlinedLoad(address, Heap::null_value(), kMaxInt);
1653 }
1654
1655
1656 void KeyedLoadIC::ClearInlinedVersion(Address address) {
1657 // Insert null as the map to check for to make sure the map check fails
1658 // sending control flow to the IC instead of the inlined version.
1659 PatchInlinedLoad(address, Heap::null_value());
1660 }
1661
1662
1663 void KeyedStoreIC::ClearInlinedVersion(Address address) {
1664 // Insert null as the elements map to check for. This will make
1665 // sure that the elements fast-case map check fails so that control
1666 // flows to the IC instead of the inlined version.
1667 PatchInlinedStore(address, Heap::null_value());
1668 }
1669
1670
1671 void KeyedStoreIC::RestoreInlinedVersion(Address address) {
1672 // Restore the fast-case elements map check so that the inlined
1673 // version can be used again.
1674 PatchInlinedStore(address, Heap::fixed_array_map());
1675 }
1676
1677
1678 bool LoadIC::PatchInlinedLoad(Address address, Object* map, int offset) { 1647 bool LoadIC::PatchInlinedLoad(Address address, Object* map, int offset) {
1679 // The address of the instruction following the call. 1648 // The address of the instruction following the call.
1680 Address test_instruction_address = 1649 Address test_instruction_address =
1681 address + Assembler::kCallTargetAddressOffset; 1650 address + Assembler::kCallTargetAddressOffset;
1682 // If the instruction following the call is not a test eax, nothing 1651 // If the instruction following the call is not a test eax, nothing
1683 // was inlined. 1652 // was inlined.
1684 if (*test_instruction_address != kTestEaxByte) return false; 1653 if (*test_instruction_address != kTestEaxByte) return false;
1685 1654
1686 Address delta_address = test_instruction_address + 1; 1655 Address delta_address = test_instruction_address + 1;
1687 // The delta to the start of the map check instruction. 1656 // The delta to the start of the map check instruction.
1688 int delta = *reinterpret_cast<int*>(delta_address); 1657 int delta = *reinterpret_cast<int*>(delta_address);
1689 1658
1690 // The map address is the last 4 bytes of the 7-byte 1659 // The map address is the last 4 bytes of the 7-byte
1691 // operand-immediate compare instruction, so we add 3 to get the 1660 // operand-immediate compare instruction, so we add 3 to get the
1692 // offset to the last 4 bytes. 1661 // offset to the last 4 bytes.
1693 Address map_address = test_instruction_address + delta + 3; 1662 Address map_address = test_instruction_address + delta + 3;
1694 *(reinterpret_cast<Object**>(map_address)) = map; 1663 *(reinterpret_cast<Object**>(map_address)) = map;
1695 1664
1696 // The offset is in the last 4 bytes of a six byte 1665 // The offset is in the last 4 bytes of a six byte
1697 // memory-to-register move instruction, so we add 2 to get the 1666 // memory-to-register move instruction, so we add 2 to get the
1698 // offset to the last 4 bytes. 1667 // offset to the last 4 bytes.
1699 Address offset_address = 1668 Address offset_address =
1700 test_instruction_address + delta + kOffsetToLoadInstruction + 2; 1669 test_instruction_address + delta + kOffsetToLoadInstruction + 2;
1701 *reinterpret_cast<int*>(offset_address) = offset - kHeapObjectTag; 1670 *reinterpret_cast<int*>(offset_address) = offset - kHeapObjectTag;
1702 return true; 1671 return true;
1703 } 1672 }
1704 1673
1705 1674
1675 bool StoreIC::PatchInlinedStore(Address address, Object* map, int offset) {
1676 // The address of the instruction following the call.
1677 Address test_instruction_address =
1678 address + Assembler::kCallTargetAddressOffset;
1679
1680 // If the instruction following the call is not a test eax, nothing
1681 // was inlined.
1682 if (*test_instruction_address != kTestEaxByte) return false;
1683
1684 // Extract the encoded deltas from the test eax instruction.
1685 Address encoded_offsets_address = test_instruction_address + 1;
1686 int encoded_offsets = *reinterpret_cast<int*>(encoded_offsets_address);
1687 int delta_to_map_check = -(encoded_offsets & 0xFFFF);
1688 int delta_to_record_write = encoded_offsets >> 16;
1689
1690 // Patch the map to check. The map address is the last 4 bytes of
1691 // the 7-byte operand-immediate compare instruction.
1692 Address map_check_address = test_instruction_address + delta_to_map_check;
1693 Address map_address = map_check_address + 3;
1694 *(reinterpret_cast<Object**>(map_address)) = map;
1695
1696 // Patch the offset in the store instruction. The offset is in the
1697 // last 4 bytes of a six byte register-to-memory move instruction.
1698 Address offset_address =
1699 map_check_address + StoreIC::kOffsetToStoreInstruction + 2;
1700 // The offset should have initial value (kMaxInt - 1), cleared value
1701 // (-1) or we should be clearing the inlined version.
1702 ASSERT(*reinterpret_cast<int*>(offset_address) == kMaxInt - 1 ||
1703 *reinterpret_cast<int*>(offset_address) == -1 ||
1704 (offset == 0 && map == Heap::null_value()));
1705 *reinterpret_cast<int*>(offset_address) = offset - kHeapObjectTag;
1706
1707 // Patch the offset in the write-barrier code. The offset is the
1708 // last 4 bytes of a six byte lea instruction.
1709 offset_address = map_check_address + delta_to_record_write + 2;
1710 // The offset should have initial value (kMaxInt), cleared value
1711 // (-1) or we should be clearing the inlined version.
1712 ASSERT(*reinterpret_cast<int*>(offset_address) == kMaxInt ||
1713 *reinterpret_cast<int*>(offset_address) == -1 ||
1714 (offset == 0 && map == Heap::null_value()));
1715 *reinterpret_cast<int*>(offset_address) = offset - kHeapObjectTag;
1716
1717 return true;
1718 }
1719
1720
1706 static bool PatchInlinedMapCheck(Address address, Object* map) { 1721 static bool PatchInlinedMapCheck(Address address, Object* map) {
1707 Address test_instruction_address = 1722 Address test_instruction_address =
1708 address + Assembler::kCallTargetAddressOffset; 1723 address + Assembler::kCallTargetAddressOffset;
1709 // The keyed load has a fast inlined case if the IC call instruction 1724 // The keyed load has a fast inlined case if the IC call instruction
1710 // is immediately followed by a test instruction. 1725 // is immediately followed by a test instruction.
1711 if (*test_instruction_address != kTestEaxByte) return false; 1726 if (*test_instruction_address != kTestEaxByte) return false;
1712 1727
1713 // Fetch the offset from the test instruction to the map cmp 1728 // Fetch the offset from the test instruction to the map cmp
1714 // instruction. This offset is stored in the last 4 bytes of the 5 1729 // instruction. This offset is stored in the last 4 bytes of the 5
1715 // byte test instruction. 1730 // byte test instruction.
(...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after
1807 __ push(ecx); 1822 __ push(ecx);
1808 __ push(eax); 1823 __ push(eax);
1809 __ push(ebx); 1824 __ push(ebx);
1810 1825
1811 // Perform tail call to the entry. 1826 // Perform tail call to the entry.
1812 ExternalReference ref = ExternalReference(IC_Utility(kStoreIC_Miss)); 1827 ExternalReference ref = ExternalReference(IC_Utility(kStoreIC_Miss));
1813 __ TailCallExternalReference(ref, 3, 1); 1828 __ TailCallExternalReference(ref, 3, 1);
1814 } 1829 }
1815 1830
1816 1831
1832 // The offset from the inlined patch site to the start of the inlined
1833 // store instruction. It is 7 bytes (test reg, imm) plus 6 bytes (jne
1834 // slow_label).
1835 const int StoreIC::kOffsetToStoreInstruction = 13;
1836
1837
1817 void StoreIC::GenerateArrayLength(MacroAssembler* masm) { 1838 void StoreIC::GenerateArrayLength(MacroAssembler* masm) {
1818 // ----------- S t a t e ------------- 1839 // ----------- S t a t e -------------
1819 // -- eax : value 1840 // -- eax : value
1820 // -- ecx : name 1841 // -- ecx : name
1821 // -- edx : receiver 1842 // -- edx : receiver
1822 // -- esp[0] : return address 1843 // -- esp[0] : return address
1823 // ----------------------------------- 1844 // -----------------------------------
1824 // 1845 //
1825 // This accepts as a receiver anything JSObject::SetElementsLength accepts 1846 // This accepts as a receiver anything JSObject::SetElementsLength accepts
1826 // (currently anything except for external and pixel arrays which means 1847 // (currently anything except for external and pixel arrays which means
(...skipping 109 matching lines...) Expand 10 before | Expand all | Expand 10 after
1936 ExternalReference ref = ExternalReference(IC_Utility(kKeyedStoreIC_Miss)); 1957 ExternalReference ref = ExternalReference(IC_Utility(kKeyedStoreIC_Miss));
1937 __ TailCallExternalReference(ref, 3, 1); 1958 __ TailCallExternalReference(ref, 3, 1);
1938 } 1959 }
1939 1960
1940 #undef __ 1961 #undef __
1941 1962
1942 1963
1943 } } // namespace v8::internal 1964 } } // namespace v8::internal
1944 1965
1945 #endif // V8_TARGET_ARCH_IA32 1966 #endif // V8_TARGET_ARCH_IA32
OLDNEW
« no previous file with comments | « src/ia32/codegen-ia32.cc ('k') | src/ia32/macro-assembler-ia32.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698