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

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

Issue 3008017: Port inline in-object property stores from ia32 to x64. (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/x64/codegen-x64.cc ('k') | src/x64/virtual-frame-x64.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 361 matching lines...) Expand 10 before | Expand all | Expand 10 after
372 Smi::FromInt(PropertyDetails::TypeField::mask())); 372 Smi::FromInt(PropertyDetails::TypeField::mask()));
373 __ j(not_zero, miss); 373 __ j(not_zero, miss);
374 374
375 // Get the value at the masked, scaled index. 375 // Get the value at the masked, scaled index.
376 const int kValueOffset = 376 const int kValueOffset =
377 NumberDictionary::kElementsStartOffset + kPointerSize; 377 NumberDictionary::kElementsStartOffset + kPointerSize;
378 __ movq(result, FieldOperand(elements, r2, times_pointer_size, kValueOffset)); 378 __ movq(result, FieldOperand(elements, r2, times_pointer_size, kValueOffset));
379 } 379 }
380 380
381 381
382 // One byte opcode for test eax,0xXXXXXXXX. 382 // One byte opcode for test rax,0xXXXXXXXX.
383 static const byte kTestEaxByte = 0xA9; 383 static const byte kTestEaxByte = 0xA9;
384 384
385 385
386 static bool PatchInlinedMapCheck(Address address, Object* map) { 386 static bool PatchInlinedMapCheck(Address address, Object* map) {
387 // Arguments are address of start of call sequence that called 387 // Arguments are address of start of call sequence that called
388 // the IC, 388 // the IC,
389 Address test_instruction_address = 389 Address test_instruction_address =
390 address + Assembler::kCallTargetAddressOffset; 390 address + Assembler::kCallTargetAddressOffset;
391 // The keyed load has a fast inlined case if the IC call instruction 391 // The keyed load has a fast inlined case if the IC call instruction
392 // is immediately followed by a test instruction. 392 // is immediately followed by a test instruction.
(...skipping 1120 matching lines...) Expand 10 before | Expand all | Expand 10 after
1513 masm, rdx, rcx, rax, rbx, rdi, &check_number_dictionary, &slow_load); 1513 masm, rdx, rcx, rax, rbx, rdi, &check_number_dictionary, &slow_load);
1514 __ IncrementCounter(&Counters::keyed_call_generic_smi_fast, 1); 1514 __ IncrementCounter(&Counters::keyed_call_generic_smi_fast, 1);
1515 1515
1516 __ bind(&do_call); 1516 __ bind(&do_call);
1517 // receiver in rdx is not used after this point. 1517 // receiver in rdx is not used after this point.
1518 // rcx: key 1518 // rcx: key
1519 // rdi: function 1519 // rdi: function
1520 GenerateFunctionTailCall(masm, argc, &slow_call); 1520 GenerateFunctionTailCall(masm, argc, &slow_call);
1521 1521
1522 __ bind(&check_number_dictionary); 1522 __ bind(&check_number_dictionary);
1523 // eax: elements 1523 // rax: elements
1524 // ecx: smi key 1524 // rcx: smi key
1525 // Check whether the elements is a number dictionary. 1525 // Check whether the elements is a number dictionary.
1526 __ CompareRoot(FieldOperand(rax, HeapObject::kMapOffset), 1526 __ CompareRoot(FieldOperand(rax, HeapObject::kMapOffset),
1527 Heap::kHashTableMapRootIndex); 1527 Heap::kHashTableMapRootIndex);
1528 __ j(not_equal, &slow_load); 1528 __ j(not_equal, &slow_load);
1529 __ SmiToInteger32(rbx, rcx); 1529 __ SmiToInteger32(rbx, rcx);
1530 // ebx: untagged index 1530 // ebx: untagged index
1531 GenerateNumberDictionaryLoad(masm, &slow_load, rax, rcx, rbx, r9, rdi, rdi); 1531 GenerateNumberDictionaryLoad(masm, &slow_load, rax, rcx, rbx, r9, rdi, rdi);
1532 __ IncrementCounter(&Counters::keyed_call_generic_smi_dict, 1); 1532 __ IncrementCounter(&Counters::keyed_call_generic_smi_dict, 1);
1533 __ jmp(&do_call); 1533 __ jmp(&do_call);
1534 1534
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after
1596 // ... 1596 // ...
1597 // rsp[argc * 8] : argument 1 1597 // rsp[argc * 8] : argument 1
1598 // rsp[(argc + 1) * 8] : argument 0 = receiver 1598 // rsp[(argc + 1) * 8] : argument 0 = receiver
1599 // ----------------------------------- 1599 // -----------------------------------
1600 1600
1601 GenerateCallNormal(masm, argc); 1601 GenerateCallNormal(masm, argc);
1602 GenerateMiss(masm, argc); 1602 GenerateMiss(masm, argc);
1603 } 1603 }
1604 1604
1605 1605
1606 // The offset from the inlined patch site to the start of the 1606 // The offset from the inlined patch site to the start of the inlined
1607 // inlined load instruction. 1607 // load instruction.
1608 const int LoadIC::kOffsetToLoadInstruction = 20; 1608 const int LoadIC::kOffsetToLoadInstruction = 20;
1609 1609
1610 1610
1611 void LoadIC::GenerateMiss(MacroAssembler* masm) { 1611 void LoadIC::GenerateMiss(MacroAssembler* masm) {
1612 // ----------- S t a t e ------------- 1612 // ----------- S t a t e -------------
1613 // -- rax : receiver 1613 // -- rax : receiver
1614 // -- rcx : name 1614 // -- rcx : name
1615 // -- rsp[0] : return address 1615 // -- rsp[0] : return address
1616 // ----------------------------------- 1616 // -----------------------------------
1617 1617
(...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after
1706 StubCompiler::GenerateLoadStringLength(masm, rax, rdx, rbx, &miss); 1706 StubCompiler::GenerateLoadStringLength(masm, rax, rdx, rbx, &miss);
1707 __ bind(&miss); 1707 __ bind(&miss);
1708 StubCompiler::GenerateLoadMiss(masm, Code::LOAD_IC); 1708 StubCompiler::GenerateLoadMiss(masm, Code::LOAD_IC);
1709 } 1709 }
1710 1710
1711 1711
1712 bool LoadIC::PatchInlinedLoad(Address address, Object* map, int offset) { 1712 bool LoadIC::PatchInlinedLoad(Address address, Object* map, int offset) {
1713 // The address of the instruction following the call. 1713 // The address of the instruction following the call.
1714 Address test_instruction_address = 1714 Address test_instruction_address =
1715 address + Assembler::kCallTargetAddressOffset; 1715 address + Assembler::kCallTargetAddressOffset;
1716 // If the instruction following the call is not a test eax, nothing 1716 // If the instruction following the call is not a test rax, nothing
1717 // was inlined. 1717 // was inlined.
1718 if (*test_instruction_address != kTestEaxByte) return false; 1718 if (*test_instruction_address != kTestEaxByte) return false;
1719 1719
1720 Address delta_address = test_instruction_address + 1; 1720 Address delta_address = test_instruction_address + 1;
1721 // The delta to the start of the map check instruction. 1721 // The delta to the start of the map check instruction.
1722 int delta = *reinterpret_cast<int*>(delta_address); 1722 int delta = *reinterpret_cast<int*>(delta_address);
1723 1723
1724 // The map address is the last 8 bytes of the 10-byte 1724 // The map address is the last 8 bytes of the 10-byte
1725 // immediate move instruction, so we add 2 to get the 1725 // immediate move instruction, so we add 2 to get the
1726 // offset to the last 8 bytes. 1726 // offset to the last 8 bytes.
1727 Address map_address = test_instruction_address + delta + 2; 1727 Address map_address = test_instruction_address + delta + 2;
1728 *(reinterpret_cast<Object**>(map_address)) = map; 1728 *(reinterpret_cast<Object**>(map_address)) = map;
1729 1729
1730 // The offset is in the 32-bit displacement of a seven byte 1730 // The offset is in the 32-bit displacement of a seven byte
1731 // memory-to-register move instruction (REX.W 0x88 ModR/M disp32), 1731 // memory-to-register move instruction (REX.W 0x88 ModR/M disp32),
1732 // so we add 3 to get the offset of the displacement. 1732 // so we add 3 to get the offset of the displacement.
1733 Address offset_address = 1733 Address offset_address =
1734 test_instruction_address + delta + kOffsetToLoadInstruction + 3; 1734 test_instruction_address + delta + kOffsetToLoadInstruction + 3;
1735 *reinterpret_cast<int*>(offset_address) = offset - kHeapObjectTag; 1735 *reinterpret_cast<int*>(offset_address) = offset - kHeapObjectTag;
1736 return true; 1736 return true;
1737 } 1737 }
1738 1738
1739 1739
1740 // The offset from the inlined patch site to the start of the inlined
1741 // store instruction.
1742 const int StoreIC::kOffsetToStoreInstruction = 20;
1743
1744
1740 bool StoreIC::PatchInlinedStore(Address address, Object* map, int offset) { 1745 bool StoreIC::PatchInlinedStore(Address address, Object* map, int offset) {
1741 // TODO(787): Implement inline stores on x64. 1746 // The address of the instruction following the call.
1742 return false; 1747 Address test_instruction_address =
1748 address + Assembler::kCallTargetAddressOffset;
1749
1750 // If the instruction following the call is not a test rax, nothing
1751 // was inlined.
1752 if (*test_instruction_address != kTestEaxByte) return false;
1753
1754 // Extract the encoded deltas from the test rax instruction.
1755 Address encoded_offsets_address = test_instruction_address + 1;
1756 int encoded_offsets = *reinterpret_cast<int*>(encoded_offsets_address);
1757 int delta_to_map_check = -(encoded_offsets & 0xFFFF);
1758 int delta_to_record_write = encoded_offsets >> 16;
1759
1760 // Patch the map to check. The map address is the last 8 bytes of
1761 // the 10-byte immediate move instruction.
1762 Address map_check_address = test_instruction_address + delta_to_map_check;
1763 Address map_address = map_check_address + 2;
1764 *(reinterpret_cast<Object**>(map_address)) = map;
1765
1766 // Patch the offset in the store instruction. The offset is in the
1767 // last 4 bytes of a 7 byte register-to-memory move instruction.
1768 Address offset_address =
1769 map_check_address + StoreIC::kOffsetToStoreInstruction + 3;
1770 // The offset should have initial value (kMaxInt - 1), cleared value
1771 // (-1) or we should be clearing the inlined version.
1772 ASSERT(*reinterpret_cast<int*>(offset_address) == kMaxInt - 1 ||
1773 *reinterpret_cast<int*>(offset_address) == -1 ||
1774 (offset == 0 && map == Heap::null_value()));
1775 *reinterpret_cast<int*>(offset_address) = offset - kHeapObjectTag;
1776
1777 // Patch the offset in the write-barrier code. The offset is the
1778 // last 4 bytes of a 7 byte lea instruction.
1779 offset_address = map_check_address + delta_to_record_write + 3;
1780 // The offset should have initial value (kMaxInt), cleared value
1781 // (-1) or we should be clearing the inlined version.
1782 ASSERT(*reinterpret_cast<int*>(offset_address) == kMaxInt ||
1783 *reinterpret_cast<int*>(offset_address) == -1 ||
1784 (offset == 0 && map == Heap::null_value()));
1785 *reinterpret_cast<int*>(offset_address) = offset - kHeapObjectTag;
1786
1787 return true;
1743 } 1788 }
1744 1789
1745 1790
1746 void StoreIC::GenerateMiss(MacroAssembler* masm) { 1791 void StoreIC::GenerateMiss(MacroAssembler* masm) {
1747 // ----------- S t a t e ------------- 1792 // ----------- S t a t e -------------
1748 // -- rax : value 1793 // -- rax : value
1749 // -- rcx : name 1794 // -- rcx : name
1750 // -- rdx : receiver 1795 // -- rdx : receiver
1751 // -- rsp[0] : return address 1796 // -- rsp[0] : return address
1752 // ----------------------------------- 1797 // -----------------------------------
(...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after
1853 GenerateMiss(masm); 1898 GenerateMiss(masm);
1854 } 1899 }
1855 1900
1856 1901
1857 #undef __ 1902 #undef __
1858 1903
1859 1904
1860 } } // namespace v8::internal 1905 } } // namespace v8::internal
1861 1906
1862 #endif // V8_TARGET_ARCH_X64 1907 #endif // V8_TARGET_ARCH_X64
OLDNEW
« no previous file with comments | « src/x64/codegen-x64.cc ('k') | src/x64/virtual-frame-x64.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698