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_IA32 | 5 #if V8_TARGET_ARCH_IA32 |
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 2618 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2629 NameDictionaryLookupStub stub(masm->isolate(), properties, r0, r0, | 2629 NameDictionaryLookupStub stub(masm->isolate(), properties, r0, r0, |
2630 NEGATIVE_LOOKUP); | 2630 NEGATIVE_LOOKUP); |
2631 __ push(Immediate(Handle<Object>(name))); | 2631 __ push(Immediate(Handle<Object>(name))); |
2632 __ push(Immediate(name->Hash())); | 2632 __ push(Immediate(name->Hash())); |
2633 __ CallStub(&stub); | 2633 __ CallStub(&stub); |
2634 __ test(r0, r0); | 2634 __ test(r0, r0); |
2635 __ j(not_zero, miss); | 2635 __ j(not_zero, miss); |
2636 __ jmp(done); | 2636 __ jmp(done); |
2637 } | 2637 } |
2638 | 2638 |
2639 | |
2640 // Probe the name dictionary in the |elements| register. Jump to the | |
2641 // |done| label if a property with the given name is found leaving the | |
2642 // index into the dictionary in |r0|. Jump to the |miss| label | |
2643 // otherwise. | |
2644 void NameDictionaryLookupStub::GeneratePositiveLookup(MacroAssembler* masm, | |
2645 Label* miss, | |
2646 Label* done, | |
2647 Register elements, | |
2648 Register name, | |
2649 Register r0, | |
2650 Register r1) { | |
2651 DCHECK(!elements.is(r0)); | |
2652 DCHECK(!elements.is(r1)); | |
2653 DCHECK(!name.is(r0)); | |
2654 DCHECK(!name.is(r1)); | |
2655 | |
2656 __ AssertName(name); | |
2657 | |
2658 __ mov(r1, FieldOperand(elements, kCapacityOffset)); | |
2659 __ shr(r1, kSmiTagSize); // convert smi to int | |
2660 __ dec(r1); | |
2661 | |
2662 // Generate an unrolled loop that performs a few probes before | |
2663 // giving up. Measurements done on Gmail indicate that 2 probes | |
2664 // cover ~93% of loads from dictionaries. | |
2665 for (int i = 0; i < kInlinedProbes; i++) { | |
2666 // Compute the masked index: (hash + i + i * i) & mask. | |
2667 __ mov(r0, FieldOperand(name, Name::kHashFieldOffset)); | |
2668 __ shr(r0, Name::kHashShift); | |
2669 if (i > 0) { | |
2670 __ add(r0, Immediate(NameDictionary::GetProbeOffset(i))); | |
2671 } | |
2672 __ and_(r0, r1); | |
2673 | |
2674 // Scale the index by multiplying by the entry size. | |
2675 STATIC_ASSERT(NameDictionary::kEntrySize == 3); | |
2676 __ lea(r0, Operand(r0, r0, times_2, 0)); // r0 = r0 * 3 | |
2677 | |
2678 // Check if the key is identical to the name. | |
2679 __ cmp(name, Operand(elements, | |
2680 r0, | |
2681 times_4, | |
2682 kElementsStartOffset - kHeapObjectTag)); | |
2683 __ j(equal, done); | |
2684 } | |
2685 | |
2686 NameDictionaryLookupStub stub(masm->isolate(), elements, r1, r0, | |
2687 POSITIVE_LOOKUP); | |
2688 __ push(name); | |
2689 __ mov(r0, FieldOperand(name, Name::kHashFieldOffset)); | |
2690 __ shr(r0, Name::kHashShift); | |
2691 __ push(r0); | |
2692 __ CallStub(&stub); | |
2693 | |
2694 __ test(r1, r1); | |
2695 __ j(zero, miss); | |
2696 __ jmp(done); | |
2697 } | |
2698 | |
2699 | |
2700 void NameDictionaryLookupStub::Generate(MacroAssembler* masm) { | 2639 void NameDictionaryLookupStub::Generate(MacroAssembler* masm) { |
2701 // This stub overrides SometimesSetsUpAFrame() to return false. That means | 2640 // This stub overrides SometimesSetsUpAFrame() to return false. That means |
2702 // we cannot call anything that could cause a GC from this stub. | 2641 // we cannot call anything that could cause a GC from this stub. |
2703 // Stack frame on entry: | 2642 // Stack frame on entry: |
2704 // esp[0 * kPointerSize]: return address. | 2643 // esp[0 * kPointerSize]: return address. |
2705 // esp[1 * kPointerSize]: key's hash. | 2644 // esp[1 * kPointerSize]: key's hash. |
2706 // esp[2 * kPointerSize]: key. | 2645 // esp[2 * kPointerSize]: key. |
2707 // Registers: | 2646 // Registers: |
2708 // dictionary_: NameDictionary to probe. | 2647 // dictionary_: NameDictionary to probe. |
2709 // result_: used as scratch. | 2648 // result_: used as scratch. |
(...skipping 1546 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4256 kStackUnwindSpace, nullptr, return_value_operand, | 4195 kStackUnwindSpace, nullptr, return_value_operand, |
4257 NULL); | 4196 NULL); |
4258 } | 4197 } |
4259 | 4198 |
4260 #undef __ | 4199 #undef __ |
4261 | 4200 |
4262 } // namespace internal | 4201 } // namespace internal |
4263 } // namespace v8 | 4202 } // namespace v8 |
4264 | 4203 |
4265 #endif // V8_TARGET_ARCH_IA32 | 4204 #endif // V8_TARGET_ARCH_IA32 |
OLD | NEW |