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

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

Issue 6614010: [Isolates] Merge 6700:7030 from bleeding_edge to isolates. (Closed) Base URL: http://v8.googlecode.com/svn/branches/experimental/isolates/
Patch Set: '' Created 9 years, 9 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/full-codegen-x64.cc ('k') | src/x64/jump-target-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 2011 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
11 // with the distribution. 11 // with the distribution.
(...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after
101 // |done| label if a property with the given name is found leaving the 101 // |done| label if a property with the given name is found leaving the
102 // index into the dictionary in |r1|. Jump to the |miss| label 102 // index into the dictionary in |r1|. Jump to the |miss| label
103 // otherwise. 103 // otherwise.
104 static void GenerateStringDictionaryProbes(MacroAssembler* masm, 104 static void GenerateStringDictionaryProbes(MacroAssembler* masm,
105 Label* miss, 105 Label* miss,
106 Label* done, 106 Label* done,
107 Register elements, 107 Register elements,
108 Register name, 108 Register name,
109 Register r0, 109 Register r0,
110 Register r1) { 110 Register r1) {
111 // Assert that name contains a string.
112 if (FLAG_debug_code) __ AbortIfNotString(name);
113
111 // Compute the capacity mask. 114 // Compute the capacity mask.
112 const int kCapacityOffset = 115 const int kCapacityOffset =
113 StringDictionary::kHeaderSize + 116 StringDictionary::kHeaderSize +
114 StringDictionary::kCapacityIndex * kPointerSize; 117 StringDictionary::kCapacityIndex * kPointerSize;
115 __ SmiToInteger32(r0, FieldOperand(elements, kCapacityOffset)); 118 __ SmiToInteger32(r0, FieldOperand(elements, kCapacityOffset));
116 __ decl(r0); 119 __ decl(r0);
117 120
118 // Generate an unrolled loop that performs a few probes before 121 // Generate an unrolled loop that performs a few probes before
119 // giving up. Measurements done on Gmail indicate that 2 probes 122 // giving up. Measurements done on Gmail indicate that 2 probes
120 // cover ~93% of loads from dictionaries. 123 // cover ~93% of loads from dictionaries.
(...skipping 635 matching lines...) Expand 10 before | Expand all | Expand 10 after
756 759
757 // Perform tail call to the entry. 760 // Perform tail call to the entry.
758 __ TailCallExternalReference(ExternalReference( 761 __ TailCallExternalReference(ExternalReference(
759 IC_Utility(kKeyedLoadPropertyWithInterceptor)), 2, 1); 762 IC_Utility(kKeyedLoadPropertyWithInterceptor)), 2, 1);
760 763
761 __ bind(&slow); 764 __ bind(&slow);
762 GenerateMiss(masm); 765 GenerateMiss(masm);
763 } 766 }
764 767
765 768
766 void KeyedStoreIC::GenerateGeneric(MacroAssembler* masm) { 769 void KeyedStoreIC::GenerateGeneric(MacroAssembler* masm,
770 StrictModeFlag strict_mode) {
767 // ----------- S t a t e ------------- 771 // ----------- S t a t e -------------
768 // -- rax : value 772 // -- rax : value
769 // -- rcx : key 773 // -- rcx : key
770 // -- rdx : receiver 774 // -- rdx : receiver
771 // -- rsp[0] : return address 775 // -- rsp[0] : return address
772 // ----------------------------------- 776 // -----------------------------------
773 Label slow, slow_with_tagged_index, fast, array, extra, check_pixel_array; 777 Label slow, slow_with_tagged_index, fast, array, extra, check_pixel_array;
774 778
775 // Check that the object isn't a smi. 779 // Check that the object isn't a smi.
776 __ JumpIfSmi(rdx, &slow_with_tagged_index); 780 __ JumpIfSmi(rdx, &slow_with_tagged_index);
(...skipping 26 matching lines...) Expand all
803 __ SmiCompareInteger32(FieldOperand(rbx, FixedArray::kLengthOffset), rcx); 807 __ SmiCompareInteger32(FieldOperand(rbx, FixedArray::kLengthOffset), rcx);
804 // rax: value 808 // rax: value
805 // rbx: FixedArray 809 // rbx: FixedArray
806 // rcx: index 810 // rcx: index
807 __ j(above, &fast); 811 __ j(above, &fast);
808 812
809 // Slow case: call runtime. 813 // Slow case: call runtime.
810 __ bind(&slow); 814 __ bind(&slow);
811 __ Integer32ToSmi(rcx, rcx); 815 __ Integer32ToSmi(rcx, rcx);
812 __ bind(&slow_with_tagged_index); 816 __ bind(&slow_with_tagged_index);
813 GenerateRuntimeSetProperty(masm); 817 GenerateRuntimeSetProperty(masm, strict_mode);
814 // Never returns to here. 818 // Never returns to here.
815 819
816 // Check whether the elements is a pixel array. 820 // Check whether the elements is a pixel array.
817 // rax: value 821 // rax: value
818 // rdx: receiver 822 // rdx: receiver
819 // rbx: receiver's elements array 823 // rbx: receiver's elements array
820 // rcx: index, zero-extended. 824 // rcx: index, zero-extended.
821 __ bind(&check_pixel_array); 825 __ bind(&check_pixel_array);
822 __ CompareRoot(FieldOperand(rbx, HeapObject::kMapOffset), 826 GenerateFastPixelArrayStore(masm,
823 Heap::kPixelArrayMapRootIndex); 827 rdx,
824 __ j(not_equal, &slow); 828 rcx,
825 // Check that the value is a smi. If a conversion is needed call into the 829 rax,
826 // runtime to convert and clamp. 830 rbx,
827 __ JumpIfNotSmi(rax, &slow); 831 rdi,
828 __ cmpl(rcx, FieldOperand(rbx, PixelArray::kLengthOffset)); 832 false,
829 __ j(above_equal, &slow); 833 true,
830 // No more bailouts to slow case on this path, so key not needed. 834 NULL,
831 __ SmiToInteger32(rdi, rax); 835 &slow,
832 { // Clamp the value to [0..255]. 836 &slow,
833 NearLabel done; 837 &slow);
834 __ testl(rdi, Immediate(0xFFFFFF00));
835 __ j(zero, &done);
836 __ setcc(negative, rdi); // 1 if negative, 0 if positive.
837 __ decb(rdi); // 0 if negative, 255 if positive.
838 __ bind(&done);
839 }
840 __ movq(rbx, FieldOperand(rbx, PixelArray::kExternalPointerOffset));
841 __ movb(Operand(rbx, rcx, times_1, 0), rdi);
842 __ ret(0);
843 838
844 // Extra capacity case: Check if there is extra capacity to 839 // Extra capacity case: Check if there is extra capacity to
845 // perform the store and update the length. Used for adding one 840 // perform the store and update the length. Used for adding one
846 // element to the array by writing to array[array.length]. 841 // element to the array by writing to array[array.length].
847 __ bind(&extra); 842 __ bind(&extra);
848 // rax: value 843 // rax: value
849 // rdx: receiver (a JSArray) 844 // rdx: receiver (a JSArray)
850 // rbx: receiver's elements array (a FixedArray) 845 // rbx: receiver's elements array (a FixedArray)
851 // rcx: index 846 // rcx: index
852 // flags: smicompare (rdx.length(), rbx) 847 // flags: smicompare (rdx.length(), rbx)
(...skipping 375 matching lines...) Expand 10 before | Expand all | Expand 10 after
1228 // ----------- S t a t e ------------- 1223 // ----------- S t a t e -------------
1229 // rcx : function name 1224 // rcx : function name
1230 // rsp[0] : return address 1225 // rsp[0] : return address
1231 // rsp[8] : argument argc 1226 // rsp[8] : argument argc
1232 // rsp[16] : argument argc - 1 1227 // rsp[16] : argument argc - 1
1233 // ... 1228 // ...
1234 // rsp[argc * 8] : argument 1 1229 // rsp[argc * 8] : argument 1
1235 // rsp[(argc + 1) * 8] : argument 0 = receiver 1230 // rsp[(argc + 1) * 8] : argument 0 = receiver
1236 // ----------------------------------- 1231 // -----------------------------------
1237 1232
1233 // Check if the name is a string.
1234 Label miss;
1235 __ JumpIfSmi(rcx, &miss);
1236 Condition cond = masm->IsObjectStringType(rcx, rax, rax);
1237 __ j(NegateCondition(cond), &miss);
1238 GenerateCallNormal(masm, argc); 1238 GenerateCallNormal(masm, argc);
1239 __ bind(&miss);
1239 GenerateMiss(masm, argc); 1240 GenerateMiss(masm, argc);
1240 } 1241 }
1241 1242
1242 1243
1243 void KeyedCallIC::GenerateMiss(MacroAssembler* masm, int argc) { 1244 void KeyedCallIC::GenerateMiss(MacroAssembler* masm, int argc) {
1244 // ----------- S t a t e ------------- 1245 // ----------- S t a t e -------------
1245 // rcx : function name 1246 // rcx : function name
1246 // rsp[0] : return address 1247 // rsp[0] : return address
1247 // rsp[8] : argument argc 1248 // rsp[8] : argument argc
1248 // rsp[16] : argument argc - 1 1249 // rsp[16] : argument argc - 1
(...skipping 220 matching lines...) Expand 10 before | Expand all | Expand 10 after
1469 __ pop(rbx); 1470 __ pop(rbx);
1470 __ push(rdx); // receiver 1471 __ push(rdx); // receiver
1471 __ push(rax); // name 1472 __ push(rax); // name
1472 __ push(rbx); // return address 1473 __ push(rbx); // return address
1473 1474
1474 // Perform tail call to the entry. 1475 // Perform tail call to the entry.
1475 __ TailCallRuntime(Runtime::kKeyedGetProperty, 2, 1); 1476 __ TailCallRuntime(Runtime::kKeyedGetProperty, 2, 1);
1476 } 1477 }
1477 1478
1478 1479
1479 void StoreIC::GenerateMegamorphic(MacroAssembler* masm) { 1480 void StoreIC::GenerateMegamorphic(MacroAssembler* masm,
1481 StrictModeFlag strict_mode) {
1480 // ----------- S t a t e ------------- 1482 // ----------- S t a t e -------------
1481 // -- rax : value 1483 // -- rax : value
1482 // -- rcx : name 1484 // -- rcx : name
1483 // -- rdx : receiver 1485 // -- rdx : receiver
1484 // -- rsp[0] : return address 1486 // -- rsp[0] : return address
1485 // ----------------------------------- 1487 // -----------------------------------
1486 1488
1487 // Get the receiver from the stack and probe the stub cache. 1489 // Get the receiver from the stack and probe the stub cache.
1488 Code::Flags flags = Code::ComputeFlags(Code::STORE_IC, 1490 Code::Flags flags = Code::ComputeFlags(Code::STORE_IC,
1489 NOT_IN_LOOP, 1491 NOT_IN_LOOP,
1490 MONOMORPHIC); 1492 MONOMORPHIC,
1493 strict_mode);
1491 Isolate::Current()->stub_cache()->GenerateProbe(masm, flags, rdx, rcx, rbx, 1494 Isolate::Current()->stub_cache()->GenerateProbe(masm, flags, rdx, rcx, rbx,
1492 no_reg); 1495 no_reg);
1493 1496
1494 // Cache miss: Jump to runtime. 1497 // Cache miss: Jump to runtime.
1495 GenerateMiss(masm); 1498 GenerateMiss(masm);
1496 } 1499 }
1497 1500
1498 1501
1499 void StoreIC::GenerateMiss(MacroAssembler* masm) { 1502 void StoreIC::GenerateMiss(MacroAssembler* masm) {
1500 // ----------- S t a t e ------------- 1503 // ----------- S t a t e -------------
(...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after
1588 GenerateDictionaryStore(masm, &miss, rbx, rcx, rax, r8, r9); 1591 GenerateDictionaryStore(masm, &miss, rbx, rcx, rax, r8, r9);
1589 __ IncrementCounter(COUNTERS->store_normal_hit(), 1); 1592 __ IncrementCounter(COUNTERS->store_normal_hit(), 1);
1590 __ ret(0); 1593 __ ret(0);
1591 1594
1592 __ bind(&miss); 1595 __ bind(&miss);
1593 __ IncrementCounter(COUNTERS->store_normal_miss(), 1); 1596 __ IncrementCounter(COUNTERS->store_normal_miss(), 1);
1594 GenerateMiss(masm); 1597 GenerateMiss(masm);
1595 } 1598 }
1596 1599
1597 1600
1598 void StoreIC::GenerateGlobalProxy(MacroAssembler* masm) { 1601 void StoreIC::GenerateGlobalProxy(MacroAssembler* masm,
1602 StrictModeFlag strict_mode) {
1599 // ----------- S t a t e ------------- 1603 // ----------- S t a t e -------------
1600 // -- rax : value 1604 // -- rax : value
1601 // -- rcx : name 1605 // -- rcx : name
1602 // -- rdx : receiver 1606 // -- rdx : receiver
1603 // -- rsp[0] : return address 1607 // -- rsp[0] : return address
1604 // ----------------------------------- 1608 // -----------------------------------
1605 __ pop(rbx); 1609 __ pop(rbx);
1606 __ push(rdx); 1610 __ push(rdx);
1607 __ push(rcx); 1611 __ push(rcx);
1608 __ push(rax); 1612 __ push(rax);
1609 __ push(rbx); 1613 __ Push(Smi::FromInt(NONE)); // PropertyAttributes
1614 __ Push(Smi::FromInt(strict_mode));
1615 __ push(rbx); // return address
1610 1616
1611 // Do tail-call to runtime routine. 1617 // Do tail-call to runtime routine.
1612 __ TailCallRuntime(Runtime::kSetProperty, 3, 1); 1618 __ TailCallRuntime(Runtime::kSetProperty, 5, 1);
1613 } 1619 }
1614 1620
1615 1621
1616 void KeyedStoreIC::GenerateRuntimeSetProperty(MacroAssembler* masm) { 1622 void KeyedStoreIC::GenerateRuntimeSetProperty(MacroAssembler* masm,
1623 StrictModeFlag strict_mode) {
1617 // ----------- S t a t e ------------- 1624 // ----------- S t a t e -------------
1618 // -- rax : value 1625 // -- rax : value
1619 // -- rcx : key 1626 // -- rcx : key
1620 // -- rdx : receiver 1627 // -- rdx : receiver
1621 // -- rsp[0] : return address 1628 // -- rsp[0] : return address
1622 // ----------------------------------- 1629 // -----------------------------------
1623 1630
1624 __ pop(rbx); 1631 __ pop(rbx);
1625 __ push(rdx); // receiver 1632 __ push(rdx); // receiver
1626 __ push(rcx); // key 1633 __ push(rcx); // key
1627 __ push(rax); // value 1634 __ push(rax); // value
1635 __ Push(Smi::FromInt(NONE)); // PropertyAttributes
1636 __ Push(Smi::FromInt(strict_mode)); // Strict mode.
1628 __ push(rbx); // return address 1637 __ push(rbx); // return address
1629 1638
1630 // Do tail-call to runtime routine. 1639 // Do tail-call to runtime routine.
1631 __ TailCallRuntime(Runtime::kSetProperty, 3, 1); 1640 __ TailCallRuntime(Runtime::kSetProperty, 5, 1);
1632 } 1641 }
1633 1642
1634 1643
1635 void KeyedStoreIC::GenerateMiss(MacroAssembler* masm) { 1644 void KeyedStoreIC::GenerateMiss(MacroAssembler* masm) {
1636 // ----------- S t a t e ------------- 1645 // ----------- S t a t e -------------
1637 // -- rax : value 1646 // -- rax : value
1638 // -- rcx : key 1647 // -- rcx : key
1639 // -- rdx : receiver 1648 // -- rdx : receiver
1640 // -- rsp[0] : return address 1649 // -- rsp[0] : return address
1641 // ----------------------------------- 1650 // -----------------------------------
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after
1704 set_target(*rewritten); 1713 set_target(*rewritten);
1705 1714
1706 #ifdef DEBUG 1715 #ifdef DEBUG
1707 if (FLAG_trace_ic) { 1716 if (FLAG_trace_ic) {
1708 PrintF("[CompareIC (%s->%s)#%s]\n", 1717 PrintF("[CompareIC (%s->%s)#%s]\n",
1709 GetStateName(previous_state), 1718 GetStateName(previous_state),
1710 GetStateName(state), 1719 GetStateName(state),
1711 Token::Name(op_)); 1720 Token::Name(op_));
1712 } 1721 }
1713 #endif 1722 #endif
1723
1724 // Activate inlined smi code.
1725 if (previous_state == UNINITIALIZED) {
1726 PatchInlinedSmiCode(address());
1727 }
1714 } 1728 }
1715 1729
1716 void PatchInlinedSmiCode(Address address) { 1730 void PatchInlinedSmiCode(Address address) {
1717 // Disabled, then patched inline smi code is not implemented on X64. 1731 // The address of the instruction following the call.
1718 // So we do nothing in this case. 1732 Address test_instruction_address =
1733 address + Assembler::kCallTargetAddressOffset;
1734
1735 // If the instruction following the call is not a test al, nothing
1736 // was inlined.
1737 if (*test_instruction_address != Assembler::kTestAlByte) {
1738 ASSERT(*test_instruction_address == Assembler::kNopByte);
1739 return;
1740 }
1741
1742 Address delta_address = test_instruction_address + 1;
1743 // The delta to the start of the map check instruction and the
1744 // condition code uses at the patched jump.
1745 int8_t delta = *reinterpret_cast<int8_t*>(delta_address);
1746 if (FLAG_trace_ic) {
1747 PrintF("[ patching ic at %p, test=%p, delta=%d\n",
1748 address, test_instruction_address, delta);
1749 }
1750
1751 // Patch with a short conditional jump. There must be a
1752 // short jump-if-carry/not-carry at this position.
1753 Address jmp_address = test_instruction_address - delta;
1754 ASSERT(*jmp_address == Assembler::kJncShortOpcode ||
1755 *jmp_address == Assembler::kJcShortOpcode);
1756 Condition cc = *jmp_address == Assembler::kJncShortOpcode
1757 ? not_zero
1758 : zero;
1759 *jmp_address = static_cast<byte>(Assembler::kJccShortPrefix | cc);
1719 } 1760 }
1720 1761
1721 1762
1722 } } // namespace v8::internal 1763 } } // namespace v8::internal
1723 1764
1724 #endif // V8_TARGET_ARCH_X64 1765 #endif // V8_TARGET_ARCH_X64
OLDNEW
« no previous file with comments | « src/x64/full-codegen-x64.cc ('k') | src/x64/jump-target-x64.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698