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

Side by Side Diff: src/code-stub-assembler.cc

Issue 2147213004: Revert of [ic] [stubs] Don't use Code::flags in megamorphic stub cache hash computations. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@split-stub-cache
Patch Set: Created 4 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
« no previous file with comments | « src/code-stub-assembler.h ('k') | src/code-stubs.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 2016 the V8 project authors. All rights reserved. 1 // Copyright 2016 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 #include "src/code-stub-assembler.h" 5 #include "src/code-stub-assembler.h"
6 #include "src/code-factory.h" 6 #include "src/code-factory.h"
7 #include "src/frames-inl.h" 7 #include "src/frames-inl.h"
8 #include "src/frames.h" 8 #include "src/frames.h"
9 #include "src/ic/stub-cache.h" 9 #include "src/ic/stub-cache.h"
10 10
(...skipping 2712 matching lines...) Expand 10 before | Expand all | Expand 10 after
2723 var_handler->Bind(handler); 2723 var_handler->Bind(handler);
2724 Goto(if_handler); 2724 Goto(if_handler);
2725 2725
2726 Bind(&next_entry); 2726 Bind(&next_entry);
2727 var_index.Bind(Int32Add(index, Int32Constant(kEntrySize))); 2727 var_index.Bind(Int32Add(index, Int32Constant(kEntrySize)));
2728 Goto(&loop); 2728 Goto(&loop);
2729 } 2729 }
2730 } 2730 }
2731 2731
2732 compiler::Node* CodeStubAssembler::StubCachePrimaryOffset(compiler::Node* name, 2732 compiler::Node* CodeStubAssembler::StubCachePrimaryOffset(compiler::Node* name,
2733 Code::Flags flags,
2733 compiler::Node* map) { 2734 compiler::Node* map) {
2734 // See v8::internal::StubCache::PrimaryOffset(). 2735 // See v8::internal::StubCache::PrimaryOffset().
2735 STATIC_ASSERT(StubCache::kCacheIndexShift == Name::kHashShift); 2736 STATIC_ASSERT(StubCache::kCacheIndexShift == Name::kHashShift);
2736 // Compute the hash of the name (use entire hash field). 2737 // Compute the hash of the name (use entire hash field).
2737 Node* hash_field = LoadNameHashField(name); 2738 Node* hash_field = LoadNameHashField(name);
2738 Assert(WordEqual( 2739 Assert(WordEqual(
2739 Word32And(hash_field, Int32Constant(Name::kHashNotComputedMask)), 2740 Word32And(hash_field, Int32Constant(Name::kHashNotComputedMask)),
2740 Int32Constant(0))); 2741 Int32Constant(0)));
2741 2742
2742 // Using only the low bits in 64-bit mode is unlikely to increase the 2743 // Using only the low bits in 64-bit mode is unlikely to increase the
2743 // risk of collision even if the heap is spread over an area larger than 2744 // risk of collision even if the heap is spread over an area larger than
2744 // 4Gb (and not at all if it isn't). 2745 // 4Gb (and not at all if it isn't).
2745 Node* hash = Int32Add(hash_field, map); 2746 Node* hash = Int32Add(hash_field, map);
2746 // Base the offset on a simple combination of name and map. 2747 // We always set the in_loop bit to zero when generating the lookup code
2748 // so do it here too so the hash codes match.
2749 uint32_t iflags =
2750 (static_cast<uint32_t>(flags) & ~Code::kFlagsNotUsedInLookup);
2751 // Base the offset on a simple combination of name, flags, and map.
2752 hash = Word32Xor(hash, Int32Constant(iflags));
2747 uint32_t mask = (StubCache::kPrimaryTableSize - 1) 2753 uint32_t mask = (StubCache::kPrimaryTableSize - 1)
2748 << StubCache::kCacheIndexShift; 2754 << StubCache::kCacheIndexShift;
2749 return Word32And(hash, Int32Constant(mask)); 2755 return Word32And(hash, Int32Constant(mask));
2750 } 2756 }
2751 2757
2752 compiler::Node* CodeStubAssembler::StubCacheSecondaryOffset( 2758 compiler::Node* CodeStubAssembler::StubCacheSecondaryOffset(
2753 compiler::Node* name, compiler::Node* seed) { 2759 compiler::Node* name, Code::Flags flags, compiler::Node* seed) {
2754 // See v8::internal::StubCache::SecondaryOffset(). 2760 // See v8::internal::StubCache::SecondaryOffset().
2755 2761
2756 // Use the seed from the primary cache in the secondary cache. 2762 // Use the seed from the primary cache in the secondary cache.
2757 Node* hash = Int32Sub(seed, name); 2763 Node* hash = Int32Sub(seed, name);
2764 // We always set the in_loop bit to zero when generating the lookup code
2765 // so do it here too so the hash codes match.
2766 uint32_t iflags =
2767 (static_cast<uint32_t>(flags) & ~Code::kFlagsNotUsedInLookup);
2768 hash = Int32Add(hash, Int32Constant(iflags));
2758 int32_t mask = (StubCache::kSecondaryTableSize - 1) 2769 int32_t mask = (StubCache::kSecondaryTableSize - 1)
2759 << StubCache::kCacheIndexShift; 2770 << StubCache::kCacheIndexShift;
2760 return Word32And(hash, Int32Constant(mask)); 2771 return Word32And(hash, Int32Constant(mask));
2761 } 2772 }
2762 2773
2763 enum CodeStubAssembler::StubCacheTable : int { 2774 enum CodeStubAssembler::StubCacheTable : int {
2764 kPrimary = static_cast<int>(StubCache::kPrimary), 2775 kPrimary = static_cast<int>(StubCache::kPrimary),
2765 kSecondary = static_cast<int>(StubCache::kSecondary) 2776 kSecondary = static_cast<int>(StubCache::kSecondary)
2766 }; 2777 };
2767 2778
2768 void CodeStubAssembler::TryProbeStubCacheTable( 2779 void CodeStubAssembler::TryProbeStubCacheTable(
2769 StubCache* stub_cache, StubCacheTable table_id, 2780 StubCache* stub_cache, StubCacheTable table_id,
2770 compiler::Node* entry_offset, compiler::Node* name, compiler::Node* map, 2781 compiler::Node* entry_offset, compiler::Node* name, Code::Flags flags,
2771 Label* if_handler, Variable* var_handler, Label* if_miss) { 2782 compiler::Node* map, Label* if_handler, Variable* var_handler,
2783 Label* if_miss) {
2772 StubCache::Table table = static_cast<StubCache::Table>(table_id); 2784 StubCache::Table table = static_cast<StubCache::Table>(table_id);
2773 #ifdef DEBUG 2785 #ifdef DEBUG
2774 if (FLAG_test_secondary_stub_cache && table == StubCache::kPrimary) { 2786 if (FLAG_test_secondary_stub_cache && table == StubCache::kPrimary) {
2775 Goto(if_miss); 2787 Goto(if_miss);
2776 return; 2788 return;
2777 } else if (FLAG_test_primary_stub_cache && table == StubCache::kSecondary) { 2789 } else if (FLAG_test_primary_stub_cache && table == StubCache::kSecondary) {
2778 Goto(if_miss); 2790 Goto(if_miss);
2779 return; 2791 return;
2780 } 2792 }
2781 #endif 2793 #endif
2782 // The {table_offset} holds the entry offset times four (due to masking 2794 // The {table_offset} holds the entry offset times four (due to masking
2783 // and shifting optimizations). 2795 // and shifting optimizations).
2784 const int kMultiplier = sizeof(StubCache::Entry) >> Name::kHashShift; 2796 const int kMultiplier = sizeof(StubCache::Entry) >> Name::kHashShift;
2785 entry_offset = Int32Mul(entry_offset, Int32Constant(kMultiplier)); 2797 entry_offset = Int32Mul(entry_offset, Int32Constant(kMultiplier));
2786 2798
2787 // Check that the key in the entry matches the name. 2799 // Check that the key in the entry matches the name.
2788 Node* key_base = 2800 Node* key_base =
2789 ExternalConstant(ExternalReference(stub_cache->key_reference(table))); 2801 ExternalConstant(ExternalReference(stub_cache->key_reference(table)));
2790 Node* entry_key = Load(MachineType::Pointer(), key_base, entry_offset); 2802 Node* entry_key = Load(MachineType::Pointer(), key_base, entry_offset);
2791 GotoIf(WordNotEqual(name, entry_key), if_miss); 2803 GotoIf(WordNotEqual(name, entry_key), if_miss);
2792 2804
2793 // Get the map entry from the cache. 2805 // Get the map entry from the cache.
2794 DCHECK_EQ(kPointerSize * 2, stub_cache->map_reference(table).address() - 2806 DCHECK_EQ(kPointerSize * 2, stub_cache->map_reference(table).address() -
2795 stub_cache->key_reference(table).address()); 2807 stub_cache->key_reference(table).address());
2796 Node* entry_map = 2808 Node* entry_map =
2797 Load(MachineType::Pointer(), key_base, 2809 Load(MachineType::Pointer(), key_base,
2798 Int32Add(entry_offset, Int32Constant(kPointerSize * 2))); 2810 Int32Add(entry_offset, Int32Constant(kPointerSize * 2)));
2799 GotoIf(WordNotEqual(map, entry_map), if_miss); 2811 GotoIf(WordNotEqual(map, entry_map), if_miss);
2800 2812
2813 // Check that the flags match what we're looking for.
2801 DCHECK_EQ(kPointerSize, stub_cache->value_reference(table).address() - 2814 DCHECK_EQ(kPointerSize, stub_cache->value_reference(table).address() -
2802 stub_cache->key_reference(table).address()); 2815 stub_cache->key_reference(table).address());
2803 Node* code = Load(MachineType::Pointer(), key_base, 2816 Node* code = Load(MachineType::Pointer(), key_base,
2804 Int32Add(entry_offset, Int32Constant(kPointerSize))); 2817 Int32Add(entry_offset, Int32Constant(kPointerSize)));
2805 2818
2806 // Check that the flags match what we're looking for.
2807 Code::Flags flags = Code::RemoveHolderFromFlags(
2808 Code::ComputeHandlerFlags(stub_cache->ic_kind()));
2809 Node* code_flags = 2819 Node* code_flags =
2810 LoadObjectField(code, Code::kFlagsOffset, MachineType::Uint32()); 2820 LoadObjectField(code, Code::kFlagsOffset, MachineType::Uint32());
2811 Assert(Word32Equal( 2821 GotoIf(Word32NotEqual(Int32Constant(flags),
2812 Int32Constant(flags), 2822 Word32And(code_flags,
2813 Word32And(code_flags, Int32Constant(~Code::kFlagsNotUsedInLookup)))); 2823 Int32Constant(~Code::kFlagsNotUsedInLookup))),
2824 if_miss);
2814 2825
2815 // We found the handler. 2826 // We found the handler.
2816 var_handler->Bind(code); 2827 var_handler->Bind(code);
2817 Goto(if_handler); 2828 Goto(if_handler);
2818 } 2829 }
2819 2830
2820 void CodeStubAssembler::TryProbeStubCache( 2831 void CodeStubAssembler::TryProbeStubCache(
2821 StubCache* stub_cache, compiler::Node* receiver, compiler::Node* name, 2832 StubCache* stub_cache, compiler::Node* receiver, compiler::Node* name,
2822 Label* if_handler, Variable* var_handler, Label* if_miss) { 2833 Label* if_handler, Variable* var_handler, Label* if_miss) {
2834 Code::Flags flags = Code::RemoveHolderFromFlags(
2835 Code::ComputeHandlerFlags(stub_cache->ic_kind()));
2836
2823 Label try_secondary(this), miss(this); 2837 Label try_secondary(this), miss(this);
2824 2838
2825 Counters* counters = isolate()->counters(); 2839 Counters* counters = isolate()->counters();
2826 IncrementCounter(counters->megamorphic_stub_cache_probes(), 1); 2840 IncrementCounter(counters->megamorphic_stub_cache_probes(), 1);
2827 2841
2828 // Check that the {receiver} isn't a smi. 2842 // Check that the {receiver} isn't a smi.
2829 GotoIf(WordIsSmi(receiver), &miss); 2843 GotoIf(WordIsSmi(receiver), &miss);
2830 2844
2831 Node* receiver_map = LoadMap(receiver); 2845 Node* receiver_map = LoadMap(receiver);
2832 2846
2833 // Probe the primary table. 2847 // Probe the primary table.
2834 Node* primary_offset = StubCachePrimaryOffset(name, receiver_map); 2848 Node* primary_offset = StubCachePrimaryOffset(name, flags, receiver_map);
2835 TryProbeStubCacheTable(stub_cache, kPrimary, primary_offset, name, 2849 TryProbeStubCacheTable(stub_cache, kPrimary, primary_offset, name, flags,
2836 receiver_map, if_handler, var_handler, &try_secondary); 2850 receiver_map, if_handler, var_handler, &try_secondary);
2837 2851
2838 Bind(&try_secondary); 2852 Bind(&try_secondary);
2839 { 2853 {
2840 // Probe the secondary table. 2854 // Probe the secondary table.
2841 Node* secondary_offset = StubCacheSecondaryOffset(name, primary_offset); 2855 Node* secondary_offset =
2856 StubCacheSecondaryOffset(name, flags, primary_offset);
2842 TryProbeStubCacheTable(stub_cache, kSecondary, secondary_offset, name, 2857 TryProbeStubCacheTable(stub_cache, kSecondary, secondary_offset, name,
2843 receiver_map, if_handler, var_handler, &miss); 2858 flags, receiver_map, if_handler, var_handler, &miss);
2844 } 2859 }
2845 2860
2846 Bind(&miss); 2861 Bind(&miss);
2847 { 2862 {
2848 IncrementCounter(counters->megamorphic_stub_cache_misses(), 1); 2863 IncrementCounter(counters->megamorphic_stub_cache_misses(), 1);
2849 Goto(if_miss); 2864 Goto(if_miss);
2850 } 2865 }
2851 } 2866 }
2852 2867
2853 void CodeStubAssembler::LoadIC(const LoadICParameters* p) { 2868 void CodeStubAssembler::LoadIC(const LoadICParameters* p) {
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after
2929 } 2944 }
2930 Bind(&miss); 2945 Bind(&miss);
2931 { 2946 {
2932 TailCallRuntime(Runtime::kLoadGlobalIC_Miss, p->context, p->slot, 2947 TailCallRuntime(Runtime::kLoadGlobalIC_Miss, p->context, p->slot,
2933 p->vector); 2948 p->vector);
2934 } 2949 }
2935 } 2950 }
2936 2951
2937 } // namespace internal 2952 } // namespace internal
2938 } // namespace v8 2953 } // namespace v8
OLDNEW
« no previous file with comments | « src/code-stub-assembler.h ('k') | src/code-stubs.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698