OLD | NEW |
1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #if V8_TARGET_ARCH_X87 | 5 #if V8_TARGET_ARCH_X87 |
6 | 6 |
7 #include "src/code-stubs.h" | 7 #include "src/code-stubs.h" |
8 #include "src/api-arguments.h" | 8 #include "src/api-arguments.h" |
9 #include "src/base/bits.h" | 9 #include "src/base/bits.h" |
10 #include "src/bootstrapper.h" | 10 #include "src/bootstrapper.h" |
(...skipping 2436 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2447 NameDictionaryLookupStub stub(masm->isolate(), properties, r0, r0, | 2447 NameDictionaryLookupStub stub(masm->isolate(), properties, r0, r0, |
2448 NEGATIVE_LOOKUP); | 2448 NEGATIVE_LOOKUP); |
2449 __ push(Immediate(Handle<Object>(name))); | 2449 __ push(Immediate(Handle<Object>(name))); |
2450 __ push(Immediate(name->Hash())); | 2450 __ push(Immediate(name->Hash())); |
2451 __ CallStub(&stub); | 2451 __ CallStub(&stub); |
2452 __ test(r0, r0); | 2452 __ test(r0, r0); |
2453 __ j(not_zero, miss); | 2453 __ j(not_zero, miss); |
2454 __ jmp(done); | 2454 __ jmp(done); |
2455 } | 2455 } |
2456 | 2456 |
2457 | |
2458 // Probe the name dictionary in the |elements| register. Jump to the | |
2459 // |done| label if a property with the given name is found leaving the | |
2460 // index into the dictionary in |r0|. Jump to the |miss| label | |
2461 // otherwise. | |
2462 void NameDictionaryLookupStub::GeneratePositiveLookup(MacroAssembler* masm, | |
2463 Label* miss, | |
2464 Label* done, | |
2465 Register elements, | |
2466 Register name, | |
2467 Register r0, | |
2468 Register r1) { | |
2469 DCHECK(!elements.is(r0)); | |
2470 DCHECK(!elements.is(r1)); | |
2471 DCHECK(!name.is(r0)); | |
2472 DCHECK(!name.is(r1)); | |
2473 | |
2474 __ AssertName(name); | |
2475 | |
2476 __ mov(r1, FieldOperand(elements, kCapacityOffset)); | |
2477 __ shr(r1, kSmiTagSize); // convert smi to int | |
2478 __ dec(r1); | |
2479 | |
2480 // Generate an unrolled loop that performs a few probes before | |
2481 // giving up. Measurements done on Gmail indicate that 2 probes | |
2482 // cover ~93% of loads from dictionaries. | |
2483 for (int i = 0; i < kInlinedProbes; i++) { | |
2484 // Compute the masked index: (hash + i + i * i) & mask. | |
2485 __ mov(r0, FieldOperand(name, Name::kHashFieldOffset)); | |
2486 __ shr(r0, Name::kHashShift); | |
2487 if (i > 0) { | |
2488 __ add(r0, Immediate(NameDictionary::GetProbeOffset(i))); | |
2489 } | |
2490 __ and_(r0, r1); | |
2491 | |
2492 // Scale the index by multiplying by the entry size. | |
2493 STATIC_ASSERT(NameDictionary::kEntrySize == 3); | |
2494 __ lea(r0, Operand(r0, r0, times_2, 0)); // r0 = r0 * 3 | |
2495 | |
2496 // Check if the key is identical to the name. | |
2497 __ cmp(name, Operand(elements, | |
2498 r0, | |
2499 times_4, | |
2500 kElementsStartOffset - kHeapObjectTag)); | |
2501 __ j(equal, done); | |
2502 } | |
2503 | |
2504 NameDictionaryLookupStub stub(masm->isolate(), elements, r1, r0, | |
2505 POSITIVE_LOOKUP); | |
2506 __ push(name); | |
2507 __ mov(r0, FieldOperand(name, Name::kHashFieldOffset)); | |
2508 __ shr(r0, Name::kHashShift); | |
2509 __ push(r0); | |
2510 __ CallStub(&stub); | |
2511 | |
2512 __ test(r1, r1); | |
2513 __ j(zero, miss); | |
2514 __ jmp(done); | |
2515 } | |
2516 | |
2517 | |
2518 void NameDictionaryLookupStub::Generate(MacroAssembler* masm) { | 2457 void NameDictionaryLookupStub::Generate(MacroAssembler* masm) { |
2519 // This stub overrides SometimesSetsUpAFrame() to return false. That means | 2458 // This stub overrides SometimesSetsUpAFrame() to return false. That means |
2520 // we cannot call anything that could cause a GC from this stub. | 2459 // we cannot call anything that could cause a GC from this stub. |
2521 // Stack frame on entry: | 2460 // Stack frame on entry: |
2522 // esp[0 * kPointerSize]: return address. | 2461 // esp[0 * kPointerSize]: return address. |
2523 // esp[1 * kPointerSize]: key's hash. | 2462 // esp[1 * kPointerSize]: key's hash. |
2524 // esp[2 * kPointerSize]: key. | 2463 // esp[2 * kPointerSize]: key. |
2525 // Registers: | 2464 // Registers: |
2526 // dictionary_: NameDictionary to probe. | 2465 // dictionary_: NameDictionary to probe. |
2527 // result_: used as scratch. | 2466 // result_: used as scratch. |
(...skipping 1531 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4059 kStackUnwindSpace, nullptr, return_value_operand, | 3998 kStackUnwindSpace, nullptr, return_value_operand, |
4060 NULL); | 3999 NULL); |
4061 } | 4000 } |
4062 | 4001 |
4063 #undef __ | 4002 #undef __ |
4064 | 4003 |
4065 } // namespace internal | 4004 } // namespace internal |
4066 } // namespace v8 | 4005 } // namespace v8 |
4067 | 4006 |
4068 #endif // V8_TARGET_ARCH_X87 | 4007 #endif // V8_TARGET_ARCH_X87 |
OLD | NEW |