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

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

Issue 7227010: Create and use shared stub for for DictionaryValue-based elements. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: more arm fixes Created 9 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/code-stubs.cc ('k') | src/ia32/macro-assembler-ia32.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 198 matching lines...) Expand 10 before | Expand all | Expand 10 after
209 const int kValueOffset = kElementsStartOffset + kPointerSize; 209 const int kValueOffset = kElementsStartOffset + kPointerSize;
210 __ lea(r0, Operand(elements, r0, times_4, kValueOffset - kHeapObjectTag)); 210 __ lea(r0, Operand(elements, r0, times_4, kValueOffset - kHeapObjectTag));
211 __ mov(Operand(r0, 0), value); 211 __ mov(Operand(r0, 0), value);
212 212
213 // Update write barrier. Make sure not to clobber the value. 213 // Update write barrier. Make sure not to clobber the value.
214 __ mov(r1, value); 214 __ mov(r1, value);
215 __ RecordWrite(elements, r0, r1); 215 __ RecordWrite(elements, r0, r1);
216 } 216 }
217 217
218 218
219 static void GenerateNumberDictionaryLoad(MacroAssembler* masm,
220 Label* miss,
221 Register elements,
222 Register key,
223 Register r0,
224 Register r1,
225 Register r2,
226 Register result) {
227 // Register use:
228 //
229 // elements - holds the slow-case elements of the receiver and is unchanged.
230 //
231 // key - holds the smi key on entry and is unchanged.
232 //
233 // Scratch registers:
234 //
235 // r0 - holds the untagged key on entry and holds the hash once computed.
236 //
237 // r1 - used to hold the capacity mask of the dictionary
238 //
239 // r2 - used for the index into the dictionary.
240 //
241 // result - holds the result on exit if the load succeeds and we fall through.
242
243 Label done;
244
245 // Compute the hash code from the untagged key. This must be kept in sync
246 // with ComputeIntegerHash in utils.h.
247 //
248 // hash = ~hash + (hash << 15);
249 __ mov(r1, r0);
250 __ not_(r0);
251 __ shl(r1, 15);
252 __ add(r0, Operand(r1));
253 // hash = hash ^ (hash >> 12);
254 __ mov(r1, r0);
255 __ shr(r1, 12);
256 __ xor_(r0, Operand(r1));
257 // hash = hash + (hash << 2);
258 __ lea(r0, Operand(r0, r0, times_4, 0));
259 // hash = hash ^ (hash >> 4);
260 __ mov(r1, r0);
261 __ shr(r1, 4);
262 __ xor_(r0, Operand(r1));
263 // hash = hash * 2057;
264 __ imul(r0, r0, 2057);
265 // hash = hash ^ (hash >> 16);
266 __ mov(r1, r0);
267 __ shr(r1, 16);
268 __ xor_(r0, Operand(r1));
269
270 // Compute capacity mask.
271 __ mov(r1, FieldOperand(elements, NumberDictionary::kCapacityOffset));
272 __ shr(r1, kSmiTagSize); // convert smi to int
273 __ dec(r1);
274
275 // Generate an unrolled loop that performs a few probes before giving up.
276 const int kProbes = 4;
277 for (int i = 0; i < kProbes; i++) {
278 // Use r2 for index calculations and keep the hash intact in r0.
279 __ mov(r2, r0);
280 // Compute the masked index: (hash + i + i * i) & mask.
281 if (i > 0) {
282 __ add(Operand(r2), Immediate(NumberDictionary::GetProbeOffset(i)));
283 }
284 __ and_(r2, Operand(r1));
285
286 // Scale the index by multiplying by the entry size.
287 ASSERT(NumberDictionary::kEntrySize == 3);
288 __ lea(r2, Operand(r2, r2, times_2, 0)); // r2 = r2 * 3
289
290 // Check if the key matches.
291 __ cmp(key, FieldOperand(elements,
292 r2,
293 times_pointer_size,
294 NumberDictionary::kElementsStartOffset));
295 if (i != (kProbes - 1)) {
296 __ j(equal, &done);
297 } else {
298 __ j(not_equal, miss);
299 }
300 }
301
302 __ bind(&done);
303 // Check that the value is a normal propety.
304 const int kDetailsOffset =
305 NumberDictionary::kElementsStartOffset + 2 * kPointerSize;
306 ASSERT_EQ(NORMAL, 0);
307 __ test(FieldOperand(elements, r2, times_pointer_size, kDetailsOffset),
308 Immediate(PropertyDetails::TypeField::mask() << kSmiTagSize));
309 __ j(not_zero, miss);
310
311 // Get the value at the masked, scaled index.
312 const int kValueOffset =
313 NumberDictionary::kElementsStartOffset + kPointerSize;
314 __ mov(result, FieldOperand(elements, r2, times_pointer_size, kValueOffset));
315 }
316
317
318 void LoadIC::GenerateArrayLength(MacroAssembler* masm) { 219 void LoadIC::GenerateArrayLength(MacroAssembler* masm) {
319 // ----------- S t a t e ------------- 220 // ----------- S t a t e -------------
320 // -- eax : receiver 221 // -- eax : receiver
321 // -- ecx : name 222 // -- ecx : name
322 // -- esp[0] : return address 223 // -- esp[0] : return address
323 // ----------------------------------- 224 // -----------------------------------
324 Label miss; 225 Label miss;
325 226
326 StubCompiler::GenerateLoadArrayLength(masm, eax, edx, &miss); 227 StubCompiler::GenerateLoadArrayLength(masm, eax, edx, &miss);
327 __ bind(&miss); 228 __ bind(&miss);
(...skipping 256 matching lines...) Expand 10 before | Expand all | Expand 10 after
584 // eax: key 485 // eax: key
585 // ecx: elements 486 // ecx: elements
586 __ CheckMap(ecx, 487 __ CheckMap(ecx,
587 isolate->factory()->hash_table_map(), 488 isolate->factory()->hash_table_map(),
588 &slow, 489 &slow,
589 DONT_DO_SMI_CHECK); 490 DONT_DO_SMI_CHECK);
590 Label slow_pop_receiver; 491 Label slow_pop_receiver;
591 // Push receiver on the stack to free up a register for the dictionary 492 // Push receiver on the stack to free up a register for the dictionary
592 // probing. 493 // probing.
593 __ push(edx); 494 __ push(edx);
594 GenerateNumberDictionaryLoad(masm, 495 __ LoadFromNumberDictionary(&slow_pop_receiver,
595 &slow_pop_receiver, 496 ecx,
596 ecx, 497 eax,
597 eax, 498 ebx,
598 ebx, 499 edx,
599 edx, 500 edi,
600 edi, 501 eax);
601 eax);
602 // Pop receiver before returning. 502 // Pop receiver before returning.
603 __ pop(edx); 503 __ pop(edx);
604 __ ret(0); 504 __ ret(0);
605 505
606 __ bind(&slow_pop_receiver); 506 __ bind(&slow_pop_receiver);
607 // Pop the receiver from the stack and jump to runtime. 507 // Pop the receiver from the stack and jump to runtime.
608 __ pop(edx); 508 __ pop(edx);
609 509
610 __ bind(&slow); 510 __ bind(&slow);
611 // Slow case: jump to runtime. 511 // Slow case: jump to runtime.
(...skipping 581 matching lines...) Expand 10 before | Expand all | Expand 10 after
1193 // ecx: smi key 1093 // ecx: smi key
1194 // Check whether the elements is a number dictionary. 1094 // Check whether the elements is a number dictionary.
1195 __ CheckMap(eax, 1095 __ CheckMap(eax,
1196 isolate->factory()->hash_table_map(), 1096 isolate->factory()->hash_table_map(),
1197 &slow_load, 1097 &slow_load,
1198 DONT_DO_SMI_CHECK); 1098 DONT_DO_SMI_CHECK);
1199 __ mov(ebx, ecx); 1099 __ mov(ebx, ecx);
1200 __ SmiUntag(ebx); 1100 __ SmiUntag(ebx);
1201 // ebx: untagged index 1101 // ebx: untagged index
1202 // Receiver in edx will be clobbered, need to reload it on miss. 1102 // Receiver in edx will be clobbered, need to reload it on miss.
1203 GenerateNumberDictionaryLoad( 1103 __ LoadFromNumberDictionary(
1204 masm, &slow_reload_receiver, eax, ecx, ebx, edx, edi, edi); 1104 &slow_reload_receiver, eax, ecx, ebx, edx, edi, edi);
1205 __ IncrementCounter(counters->keyed_call_generic_smi_dict(), 1); 1105 __ IncrementCounter(counters->keyed_call_generic_smi_dict(), 1);
1206 __ jmp(&do_call); 1106 __ jmp(&do_call);
1207 1107
1208 __ bind(&slow_reload_receiver); 1108 __ bind(&slow_reload_receiver);
1209 __ mov(edx, Operand(esp, (argc + 1) * kPointerSize)); 1109 __ mov(edx, Operand(esp, (argc + 1) * kPointerSize));
1210 1110
1211 __ bind(&slow_load); 1111 __ bind(&slow_load);
1212 // This branch is taken when calling KeyedCallIC_Miss is neither required 1112 // This branch is taken when calling KeyedCallIC_Miss is neither required
1213 // nor beneficial. 1113 // nor beneficial.
1214 __ IncrementCounter(counters->keyed_call_generic_slow_load(), 1); 1114 __ IncrementCounter(counters->keyed_call_generic_slow_load(), 1);
(...skipping 522 matching lines...) Expand 10 before | Expand all | Expand 10 after
1737 Condition cc = *jmp_address == Assembler::kJncShortOpcode 1637 Condition cc = *jmp_address == Assembler::kJncShortOpcode
1738 ? not_zero 1638 ? not_zero
1739 : zero; 1639 : zero;
1740 *jmp_address = static_cast<byte>(Assembler::kJccShortPrefix | cc); 1640 *jmp_address = static_cast<byte>(Assembler::kJccShortPrefix | cc);
1741 } 1641 }
1742 1642
1743 1643
1744 } } // namespace v8::internal 1644 } } // namespace v8::internal
1745 1645
1746 #endif // V8_TARGET_ARCH_IA32 1646 #endif // V8_TARGET_ARCH_IA32
OLDNEW
« no previous file with comments | « src/code-stubs.cc ('k') | src/ia32/macro-assembler-ia32.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698