| 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 |