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

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

Issue 7060010: Merge bleeding edge into the GC branch up to 7948. The asserts (Closed) Base URL: http://v8.googlecode.com/svn/branches/experimental/gc/
Patch Set: Created 9 years, 7 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/lithium-codegen-x64.h » ('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 2011 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
(...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after
90 (1 << Map::kHasNamedInterceptor))); 90 (1 << Map::kHasNamedInterceptor)));
91 __ j(not_zero, miss); 91 __ j(not_zero, miss);
92 92
93 __ movq(r0, FieldOperand(receiver, JSObject::kPropertiesOffset)); 93 __ movq(r0, FieldOperand(receiver, JSObject::kPropertiesOffset));
94 __ CompareRoot(FieldOperand(r0, HeapObject::kMapOffset), 94 __ CompareRoot(FieldOperand(r0, HeapObject::kMapOffset),
95 Heap::kHashTableMapRootIndex); 95 Heap::kHashTableMapRootIndex);
96 __ j(not_equal, miss); 96 __ j(not_equal, miss);
97 } 97 }
98 98
99 99
100 // Probe the string dictionary in the |elements| register. Jump to 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
103 // otherwise.
104 static void GenerateStringDictionaryProbes(MacroAssembler* masm,
105 Label* miss,
106 Label* done,
107 Register elements,
108 Register name,
109 Register r0,
110 Register r1) {
111 // Assert that name contains a string.
112 if (FLAG_debug_code) __ AbortIfNotString(name);
113
114 // Compute the capacity mask.
115 const int kCapacityOffset =
116 StringDictionary::kHeaderSize +
117 StringDictionary::kCapacityIndex * kPointerSize;
118 __ SmiToInteger32(r0, FieldOperand(elements, kCapacityOffset));
119 __ decl(r0);
120
121 // Generate an unrolled loop that performs a few probes before
122 // giving up. Measurements done on Gmail indicate that 2 probes
123 // cover ~93% of loads from dictionaries.
124 static const int kProbes = 4;
125 const int kElementsStartOffset =
126 StringDictionary::kHeaderSize +
127 StringDictionary::kElementsStartIndex * kPointerSize;
128 for (int i = 0; i < kProbes; i++) {
129 // Compute the masked index: (hash + i + i * i) & mask.
130 __ movl(r1, FieldOperand(name, String::kHashFieldOffset));
131 __ shrl(r1, Immediate(String::kHashShift));
132 if (i > 0) {
133 __ addl(r1, Immediate(StringDictionary::GetProbeOffset(i)));
134 }
135 __ and_(r1, r0);
136
137 // Scale the index by multiplying by the entry size.
138 ASSERT(StringDictionary::kEntrySize == 3);
139 __ lea(r1, Operand(r1, r1, times_2, 0)); // r1 = r1 * 3
140
141 // Check if the key is identical to the name.
142 __ cmpq(name, Operand(elements, r1, times_pointer_size,
143 kElementsStartOffset - kHeapObjectTag));
144 if (i != kProbes - 1) {
145 __ j(equal, done);
146 } else {
147 __ j(not_equal, miss);
148 }
149 }
150 }
151
152 100
153 // Helper function used to load a property from a dictionary backing storage. 101 // Helper function used to load a property from a dictionary backing storage.
154 // This function may return false negatives, so miss_label 102 // This function may return false negatives, so miss_label
155 // must always call a backup property load that is complete. 103 // must always call a backup property load that is complete.
156 // This function is safe to call if name is not a symbol, and will jump to 104 // This function is safe to call if name is not a symbol, and will jump to
157 // the miss_label in that case. 105 // the miss_label in that case.
158 // The generated code assumes that the receiver has slow properties, 106 // The generated code assumes that the receiver has slow properties,
159 // is not a global object and does not have interceptors. 107 // is not a global object and does not have interceptors.
160 static void GenerateDictionaryLoad(MacroAssembler* masm, 108 static void GenerateDictionaryLoad(MacroAssembler* masm,
161 Label* miss_label, 109 Label* miss_label,
(...skipping 10 matching lines...) Expand all
172 // 120 //
173 // r0 - used to hold the capacity of the property dictionary. 121 // r0 - used to hold the capacity of the property dictionary.
174 // 122 //
175 // r1 - used to hold the index into the property dictionary. 123 // r1 - used to hold the index into the property dictionary.
176 // 124 //
177 // result - holds the result on exit if the load succeeded. 125 // result - holds the result on exit if the load succeeded.
178 126
179 Label done; 127 Label done;
180 128
181 // Probe the dictionary. 129 // Probe the dictionary.
182 GenerateStringDictionaryProbes(masm, 130 StringDictionaryLookupStub::GeneratePositiveLookup(masm,
183 miss_label, 131 miss_label,
184 &done, 132 &done,
185 elements, 133 elements,
186 name, 134 name,
187 r0, 135 r0,
188 r1); 136 r1);
189 137
190 // If probing finds an entry in the dictionary, r0 contains the 138 // If probing finds an entry in the dictionary, r0 contains the
191 // index into the dictionary. Check that the value is a normal 139 // index into the dictionary. Check that the value is a normal
192 // property. 140 // property.
193 __ bind(&done); 141 __ bind(&done);
194 const int kElementsStartOffset = 142 const int kElementsStartOffset =
195 StringDictionary::kHeaderSize + 143 StringDictionary::kHeaderSize +
196 StringDictionary::kElementsStartIndex * kPointerSize; 144 StringDictionary::kElementsStartIndex * kPointerSize;
197 const int kDetailsOffset = kElementsStartOffset + 2 * kPointerSize; 145 const int kDetailsOffset = kElementsStartOffset + 2 * kPointerSize;
198 __ Test(Operand(elements, r1, times_pointer_size, 146 __ Test(Operand(elements, r1, times_pointer_size,
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
230 // 178 //
231 // value - holds the value to store and is unchanged. 179 // value - holds the value to store and is unchanged.
232 // 180 //
233 // scratch0 - used for index into the property dictionary and is clobbered. 181 // scratch0 - used for index into the property dictionary and is clobbered.
234 // 182 //
235 // scratch1 - used to hold the capacity of the property dictionary and is 183 // scratch1 - used to hold the capacity of the property dictionary and is
236 // clobbered. 184 // clobbered.
237 Label done; 185 Label done;
238 186
239 // Probe the dictionary. 187 // Probe the dictionary.
240 GenerateStringDictionaryProbes(masm, 188 StringDictionaryLookupStub::GeneratePositiveLookup(masm,
241 miss_label, 189 miss_label,
242 &done, 190 &done,
243 elements, 191 elements,
244 name, 192 name,
245 scratch0, 193 scratch0,
246 scratch1); 194 scratch1);
247 195
248 // If probing finds an entry in the dictionary, scratch0 contains the 196 // If probing finds an entry in the dictionary, scratch0 contains the
249 // index into the dictionary. Check that the value is a normal 197 // index into the dictionary. Check that the value is a normal
250 // property that is not read only. 198 // property that is not read only.
251 __ bind(&done); 199 __ bind(&done);
252 const int kElementsStartOffset = 200 const int kElementsStartOffset =
253 StringDictionary::kHeaderSize + 201 StringDictionary::kHeaderSize +
254 StringDictionary::kElementsStartIndex * kPointerSize; 202 StringDictionary::kElementsStartIndex * kPointerSize;
255 const int kDetailsOffset = kElementsStartOffset + 2 * kPointerSize; 203 const int kDetailsOffset = kElementsStartOffset + 2 * kPointerSize;
256 const int kTypeAndReadOnlyMask 204 const int kTypeAndReadOnlyMask
(...skipping 446 matching lines...) Expand 10 before | Expand all | Expand 10 after
703 &miss, // When not a number. 651 &miss, // When not a number.
704 &miss, // When index out of range. 652 &miss, // When index out of range.
705 STRING_INDEX_IS_ARRAY_INDEX); 653 STRING_INDEX_IS_ARRAY_INDEX);
706 char_at_generator.GenerateFast(masm); 654 char_at_generator.GenerateFast(masm);
707 __ ret(0); 655 __ ret(0);
708 656
709 StubRuntimeCallHelper call_helper; 657 StubRuntimeCallHelper call_helper;
710 char_at_generator.GenerateSlow(masm, call_helper); 658 char_at_generator.GenerateSlow(masm, call_helper);
711 659
712 __ bind(&miss); 660 __ bind(&miss);
713 GenerateMiss(masm); 661 GenerateMiss(masm, false);
714 } 662 }
715 663
716 664
717 void KeyedLoadIC::GenerateIndexedInterceptor(MacroAssembler* masm) { 665 void KeyedLoadIC::GenerateIndexedInterceptor(MacroAssembler* masm) {
718 // ----------- S t a t e ------------- 666 // ----------- S t a t e -------------
719 // -- rax : key 667 // -- rax : key
720 // -- rdx : receiver 668 // -- rdx : receiver
721 // -- rsp[0] : return address 669 // -- rsp[0] : return address
722 // ----------------------------------- 670 // -----------------------------------
723 Label slow; 671 Label slow;
(...skipping 22 matching lines...) Expand all
746 __ push(rcx); // return address 694 __ push(rcx); // return address
747 695
748 // Perform tail call to the entry. 696 // Perform tail call to the entry.
749 __ TailCallExternalReference( 697 __ TailCallExternalReference(
750 ExternalReference(IC_Utility(kKeyedLoadPropertyWithInterceptor), 698 ExternalReference(IC_Utility(kKeyedLoadPropertyWithInterceptor),
751 masm->isolate()), 699 masm->isolate()),
752 2, 700 2,
753 1); 701 1);
754 702
755 __ bind(&slow); 703 __ bind(&slow);
756 GenerateMiss(masm); 704 GenerateMiss(masm, false);
757 } 705 }
758 706
759 707
760 void KeyedStoreIC::GenerateGeneric(MacroAssembler* masm, 708 void KeyedStoreIC::GenerateGeneric(MacroAssembler* masm,
761 StrictModeFlag strict_mode) { 709 StrictModeFlag strict_mode) {
762 // ----------- S t a t e ------------- 710 // ----------- S t a t e -------------
763 // -- rax : value 711 // -- rax : value
764 // -- rcx : key 712 // -- rcx : key
765 // -- rdx : receiver 713 // -- rdx : receiver
766 // -- rsp[0] : return address 714 // -- rsp[0] : return address
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after
840 // Check the key against the length in the array, compute the 788 // Check the key against the length in the array, compute the
841 // address to store into and fall through to fast case. 789 // address to store into and fall through to fast case.
842 __ SmiCompareInteger32(FieldOperand(rdx, JSArray::kLengthOffset), rcx); 790 __ SmiCompareInteger32(FieldOperand(rdx, JSArray::kLengthOffset), rcx);
843 __ j(below_equal, &extra); 791 __ j(below_equal, &extra);
844 792
845 // Fast case: Do the store. 793 // Fast case: Do the store.
846 __ bind(&fast); 794 __ bind(&fast);
847 // rax: value 795 // rax: value
848 // rbx: receiver's elements array (a FixedArray) 796 // rbx: receiver's elements array (a FixedArray)
849 // rcx: index 797 // rcx: index
850 NearLabel non_smi_value; 798 Label non_smi_value;
851 __ movq(FieldOperand(rbx, rcx, times_pointer_size, FixedArray::kHeaderSize), 799 __ movq(FieldOperand(rbx, rcx, times_pointer_size, FixedArray::kHeaderSize),
852 rax); 800 rax);
853 __ JumpIfNotSmi(rax, &non_smi_value); 801 __ JumpIfNotSmi(rax, &non_smi_value, Label::kNear);
854 __ ret(0); 802 __ ret(0);
855 __ bind(&non_smi_value); 803 __ bind(&non_smi_value);
856 // Slow case that needs to retain rcx for use by RecordWrite. 804 // Slow case that needs to retain rcx for use by RecordWrite.
857 // Update write barrier for the elements array address. 805 // Update write barrier for the elements array address.
858 __ movq(rdx, rax); 806 __ movq(rdx, rax);
859 __ RecordWriteNonSmi(rbx, 0, rdx, rcx, kDontSaveFPRegs); 807 __ RecordWriteNonSmi(rbx, 0, rdx, rcx, kDontSaveFPRegs);
860 __ ret(0); 808 __ ret(0);
861 } 809 }
862 810
863 811
(...skipping 421 matching lines...) Expand 10 before | Expand all | Expand 10 after
1285 __ push(rcx); // name 1233 __ push(rcx); // name
1286 __ push(rbx); // return address 1234 __ push(rbx); // return address
1287 1235
1288 // Perform tail call to the entry. 1236 // Perform tail call to the entry.
1289 ExternalReference ref = 1237 ExternalReference ref =
1290 ExternalReference(IC_Utility(kLoadIC_Miss), masm->isolate()); 1238 ExternalReference(IC_Utility(kLoadIC_Miss), masm->isolate());
1291 __ TailCallExternalReference(ref, 2, 1); 1239 __ TailCallExternalReference(ref, 2, 1);
1292 } 1240 }
1293 1241
1294 1242
1295 void KeyedLoadIC::GenerateMiss(MacroAssembler* masm) { 1243 void KeyedLoadIC::GenerateMiss(MacroAssembler* masm, bool force_generic) {
1296 // ----------- S t a t e ------------- 1244 // ----------- S t a t e -------------
1297 // -- rax : key 1245 // -- rax : key
1298 // -- rdx : receiver 1246 // -- rdx : receiver
1299 // -- rsp[0] : return address 1247 // -- rsp[0] : return address
1300 // ----------------------------------- 1248 // -----------------------------------
1301 1249
1302 Counters* counters = masm->isolate()->counters(); 1250 Counters* counters = masm->isolate()->counters();
1303 __ IncrementCounter(counters->keyed_load_miss(), 1); 1251 __ IncrementCounter(counters->keyed_load_miss(), 1);
1304 1252
1305 __ pop(rbx); 1253 __ pop(rbx);
1306 __ push(rdx); // receiver 1254 __ push(rdx); // receiver
1307 __ push(rax); // name 1255 __ push(rax); // name
1308 __ push(rbx); // return address 1256 __ push(rbx); // return address
1309 1257
1310 // Perform tail call to the entry. 1258 // Perform tail call to the entry.
1311 ExternalReference ref 1259 ExternalReference ref = force_generic
1312 = ExternalReference(IC_Utility(kKeyedLoadIC_Miss), masm->isolate()); 1260 ? ExternalReference(IC_Utility(kKeyedLoadIC_MissForceGeneric),
1261 masm->isolate())
1262 : ExternalReference(IC_Utility(kKeyedLoadIC_Miss), masm->isolate());
1313 __ TailCallExternalReference(ref, 2, 1); 1263 __ TailCallExternalReference(ref, 2, 1);
1314 } 1264 }
1315 1265
1316 1266
1317 void KeyedLoadIC::GenerateRuntimeGetProperty(MacroAssembler* masm) { 1267 void KeyedLoadIC::GenerateRuntimeGetProperty(MacroAssembler* masm) {
1318 // ----------- S t a t e ------------- 1268 // ----------- S t a t e -------------
1319 // -- rax : key 1269 // -- rax : key
1320 // -- rdx : receiver 1270 // -- rdx : receiver
1321 // -- rsp[0] : return address 1271 // -- rsp[0] : return address
1322 // ----------------------------------- 1272 // -----------------------------------
(...skipping 163 matching lines...) Expand 10 before | Expand all | Expand 10 after
1486 __ push(rax); // value 1436 __ push(rax); // value
1487 __ Push(Smi::FromInt(NONE)); // PropertyAttributes 1437 __ Push(Smi::FromInt(NONE)); // PropertyAttributes
1488 __ Push(Smi::FromInt(strict_mode)); // Strict mode. 1438 __ Push(Smi::FromInt(strict_mode)); // Strict mode.
1489 __ push(rbx); // return address 1439 __ push(rbx); // return address
1490 1440
1491 // Do tail-call to runtime routine. 1441 // Do tail-call to runtime routine.
1492 __ TailCallRuntime(Runtime::kSetProperty, 5, 1); 1442 __ TailCallRuntime(Runtime::kSetProperty, 5, 1);
1493 } 1443 }
1494 1444
1495 1445
1496 void KeyedStoreIC::GenerateMiss(MacroAssembler* masm) { 1446 void KeyedStoreIC::GenerateSlow(MacroAssembler* masm) {
1497 // ----------- S t a t e ------------- 1447 // ----------- S t a t e -------------
1498 // -- rax : value 1448 // -- rax : value
1499 // -- rcx : key 1449 // -- rcx : key
1500 // -- rdx : receiver 1450 // -- rdx : receiver
1501 // -- rsp[0] : return address 1451 // -- rsp[0] : return address
1502 // ----------------------------------- 1452 // -----------------------------------
1503 1453
1504 __ pop(rbx); 1454 __ pop(rbx);
1505 __ push(rdx); // receiver 1455 __ push(rdx); // receiver
1506 __ push(rcx); // key 1456 __ push(rcx); // key
1507 __ push(rax); // value 1457 __ push(rax); // value
1508 __ push(rbx); // return address 1458 __ push(rbx); // return address
1509 1459
1510 // Do tail-call to runtime routine. 1460 // Do tail-call to runtime routine.
1511 ExternalReference ref = 1461 ExternalReference ref(IC_Utility(kKeyedStoreIC_Slow), masm->isolate());
1512 ExternalReference(IC_Utility(kKeyedStoreIC_Miss), masm->isolate()); 1462 __ TailCallExternalReference(ref, 3, 1);
1463 }
1464
1465
1466 void KeyedStoreIC::GenerateMiss(MacroAssembler* masm, bool force_generic) {
1467 // ----------- S t a t e -------------
1468 // -- rax : value
1469 // -- rcx : key
1470 // -- rdx : receiver
1471 // -- rsp[0] : return address
1472 // -----------------------------------
1473
1474 __ pop(rbx);
1475 __ push(rdx); // receiver
1476 __ push(rcx); // key
1477 __ push(rax); // value
1478 __ push(rbx); // return address
1479
1480 // Do tail-call to runtime routine.
1481 ExternalReference ref = force_generic
1482 ? ExternalReference(IC_Utility(kKeyedStoreIC_MissForceGeneric),
1483 masm->isolate())
1484 : ExternalReference(IC_Utility(kKeyedStoreIC_Miss), masm->isolate());
1513 __ TailCallExternalReference(ref, 3, 1); 1485 __ TailCallExternalReference(ref, 3, 1);
1514 } 1486 }
1515 1487
1516 1488
1517 #undef __ 1489 #undef __
1518 1490
1519 1491
1520 Condition CompareIC::ComputeCondition(Token::Value op) { 1492 Condition CompareIC::ComputeCondition(Token::Value op) {
1521 switch (op) { 1493 switch (op) {
1522 case Token::EQ_STRICT: 1494 case Token::EQ_STRICT:
(...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after
1609 Condition cc = *jmp_address == Assembler::kJncShortOpcode 1581 Condition cc = *jmp_address == Assembler::kJncShortOpcode
1610 ? not_zero 1582 ? not_zero
1611 : zero; 1583 : zero;
1612 *jmp_address = static_cast<byte>(Assembler::kJccShortPrefix | cc); 1584 *jmp_address = static_cast<byte>(Assembler::kJccShortPrefix | cc);
1613 } 1585 }
1614 1586
1615 1587
1616 } } // namespace v8::internal 1588 } } // namespace v8::internal
1617 1589
1618 #endif // V8_TARGET_ARCH_X64 1590 #endif // V8_TARGET_ARCH_X64
OLDNEW
« no previous file with comments | « src/x64/full-codegen-x64.cc ('k') | src/x64/lithium-codegen-x64.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698