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

Side by Side Diff: src/ic/arm64/stub-cache-arm64.cc

Issue 2123983004: [ic] Split megamorphic stub cache in two caches (for loads and for stores). (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@flags-fix
Patch Set: Rebasing 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
OLDNEW
1 // Copyright 2013 the V8 project authors. All rights reserved. 1 // Copyright 2013 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_ARM64 5 #if V8_TARGET_ARCH_ARM64
6 6
7 #include "src/codegen.h" 7 #include "src/codegen.h"
8 #include "src/ic/ic.h" 8 #include "src/ic/ic.h"
9 #include "src/ic/stub-cache.h" 9 #include "src/ic/stub-cache.h"
10 #include "src/interface-descriptors.h" 10 #include "src/interface-descriptors.h"
11 11
12 namespace v8 { 12 namespace v8 {
13 namespace internal { 13 namespace internal {
14 14
15 15
16 #define __ ACCESS_MASM(masm) 16 #define __ ACCESS_MASM(masm)
17 17
18 18
19 // Probe primary or secondary table. 19 // Probe primary or secondary table.
20 // If the entry is found in the cache, the generated code jump to the first 20 // If the entry is found in the cache, the generated code jump to the first
21 // instruction of the stub in the cache. 21 // instruction of the stub in the cache.
22 // If there is a miss the code fall trough. 22 // If there is a miss the code fall trough.
23 // 23 //
24 // 'receiver', 'name' and 'offset' registers are preserved on miss. 24 // 'receiver', 'name' and 'offset' registers are preserved on miss.
25 static void ProbeTable(Isolate* isolate, MacroAssembler* masm, 25 static void ProbeTable(StubCache* stub_cache, MacroAssembler* masm,
26 Code::Flags flags, StubCache::Table table, 26 Code::Flags flags, StubCache::Table table,
27 Register receiver, Register name, Register offset, 27 Register receiver, Register name, Register offset,
28 Register scratch, Register scratch2, Register scratch3) { 28 Register scratch, Register scratch2, Register scratch3) {
29 // Some code below relies on the fact that the Entry struct contains 29 // Some code below relies on the fact that the Entry struct contains
30 // 3 pointers (name, code, map). 30 // 3 pointers (name, code, map).
31 STATIC_ASSERT(sizeof(StubCache::Entry) == (3 * kPointerSize)); 31 STATIC_ASSERT(sizeof(StubCache::Entry) == (3 * kPointerSize));
32 32
33 ExternalReference key_offset(isolate->stub_cache()->key_reference(table)); 33 ExternalReference key_offset(stub_cache->key_reference(table));
34 ExternalReference value_offset(isolate->stub_cache()->value_reference(table)); 34 ExternalReference value_offset(stub_cache->value_reference(table));
35 ExternalReference map_offset(isolate->stub_cache()->map_reference(table)); 35 ExternalReference map_offset(stub_cache->map_reference(table));
36 36
37 uintptr_t key_off_addr = reinterpret_cast<uintptr_t>(key_offset.address()); 37 uintptr_t key_off_addr = reinterpret_cast<uintptr_t>(key_offset.address());
38 uintptr_t value_off_addr = 38 uintptr_t value_off_addr =
39 reinterpret_cast<uintptr_t>(value_offset.address()); 39 reinterpret_cast<uintptr_t>(value_offset.address());
40 uintptr_t map_off_addr = reinterpret_cast<uintptr_t>(map_offset.address()); 40 uintptr_t map_off_addr = reinterpret_cast<uintptr_t>(map_offset.address());
41 41
42 Label miss; 42 Label miss;
43 43
44 DCHECK(!AreAliased(name, offset, scratch, scratch2, scratch3)); 44 DCHECK(!AreAliased(name, offset, scratch, scratch2, scratch3));
45 45
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
79 #endif 79 #endif
80 80
81 // Jump to the first instruction in the code stub. 81 // Jump to the first instruction in the code stub.
82 __ Add(scratch, scratch, Code::kHeaderSize - kHeapObjectTag); 82 __ Add(scratch, scratch, Code::kHeaderSize - kHeapObjectTag);
83 __ Br(scratch); 83 __ Br(scratch);
84 84
85 // Miss: fall through. 85 // Miss: fall through.
86 __ Bind(&miss); 86 __ Bind(&miss);
87 } 87 }
88 88
89 89 void StubCache::GenerateProbe(MacroAssembler* masm, Register receiver,
90 void StubCache::GenerateProbe(MacroAssembler* masm, Code::Kind ic_kind,
91 Code::Flags flags, Register receiver,
92 Register name, Register scratch, Register extra, 90 Register name, Register scratch, Register extra,
93 Register extra2, Register extra3) { 91 Register extra2, Register extra3) {
94 Isolate* isolate = masm->isolate(); 92 Code::Flags flags =
93 Code::RemoveHolderFromFlags(Code::ComputeHandlerFlags(ic_kind_));
94
95 Label miss; 95 Label miss;
96 96
97 // Make sure that there are no register conflicts. 97 // Make sure that there are no register conflicts.
98 DCHECK(!AreAliased(receiver, name, scratch, extra, extra2, extra3)); 98 DCHECK(!AreAliased(receiver, name, scratch, extra, extra2, extra3));
99 99
100 // Make sure extra and extra2 registers are valid. 100 // Make sure extra and extra2 registers are valid.
101 DCHECK(!extra.is(no_reg)); 101 DCHECK(!extra.is(no_reg));
102 DCHECK(!extra2.is(no_reg)); 102 DCHECK(!extra2.is(no_reg));
103 DCHECK(!extra3.is(no_reg)); 103 DCHECK(!extra3.is(no_reg));
104 104
105 #ifdef DEBUG 105 #ifdef DEBUG
106 // If vector-based ics are in use, ensure that scratch, extra, extra2 and 106 // If vector-based ics are in use, ensure that scratch, extra, extra2 and
107 // extra3 don't conflict with the vector and slot registers, which need 107 // extra3 don't conflict with the vector and slot registers, which need
108 // to be preserved for a handler call or miss. 108 // to be preserved for a handler call or miss.
109 if (IC::ICUseVector(ic_kind)) { 109 if (IC::ICUseVector(ic_kind_)) {
110 Register vector, slot; 110 Register vector, slot;
111 if (ic_kind == Code::STORE_IC || ic_kind == Code::KEYED_STORE_IC) { 111 if (ic_kind_ == Code::STORE_IC || ic_kind_ == Code::KEYED_STORE_IC) {
112 vector = VectorStoreICDescriptor::VectorRegister(); 112 vector = VectorStoreICDescriptor::VectorRegister();
113 slot = VectorStoreICDescriptor::SlotRegister(); 113 slot = VectorStoreICDescriptor::SlotRegister();
114 } else { 114 } else {
115 DCHECK(ic_kind_ == Code::LOAD_IC || ic_kind_ == Code::KEYED_LOAD_IC);
115 vector = LoadWithVectorDescriptor::VectorRegister(); 116 vector = LoadWithVectorDescriptor::VectorRegister();
116 slot = LoadWithVectorDescriptor::SlotRegister(); 117 slot = LoadWithVectorDescriptor::SlotRegister();
117 } 118 }
118 DCHECK(!AreAliased(vector, slot, scratch, extra, extra2, extra3)); 119 DCHECK(!AreAliased(vector, slot, scratch, extra, extra2, extra3));
119 } 120 }
120 #endif 121 #endif
121 122
122 Counters* counters = masm->isolate()->counters(); 123 Counters* counters = masm->isolate()->counters();
123 __ IncrementCounter(counters->megamorphic_stub_cache_probes(), 1, extra2, 124 __ IncrementCounter(counters->megamorphic_stub_cache_probes(), 1, extra2,
124 extra3); 125 extra3);
125 126
126 // Check that the receiver isn't a smi. 127 // Check that the receiver isn't a smi.
127 __ JumpIfSmi(receiver, &miss); 128 __ JumpIfSmi(receiver, &miss);
128 129
129 // Compute the hash for primary table. 130 // Compute the hash for primary table.
130 __ Ldr(scratch, FieldMemOperand(name, Name::kHashFieldOffset)); 131 __ Ldr(scratch, FieldMemOperand(name, Name::kHashFieldOffset));
131 __ Ldr(extra, FieldMemOperand(receiver, HeapObject::kMapOffset)); 132 __ Ldr(extra, FieldMemOperand(receiver, HeapObject::kMapOffset));
132 __ Add(scratch, scratch, extra); 133 __ Add(scratch, scratch, extra);
133 __ Eor(scratch, scratch, flags); 134 __ Eor(scratch, scratch, flags);
134 // We shift out the last two bits because they are not part of the hash. 135 // We shift out the last two bits because they are not part of the hash.
135 __ Ubfx(scratch, scratch, kCacheIndexShift, 136 __ Ubfx(scratch, scratch, kCacheIndexShift,
136 CountTrailingZeros(kPrimaryTableSize, 64)); 137 CountTrailingZeros(kPrimaryTableSize, 64));
137 138
138 // Probe the primary table. 139 // Probe the primary table.
139 ProbeTable(isolate, masm, flags, kPrimary, receiver, name, scratch, extra, 140 ProbeTable(this, masm, flags, kPrimary, receiver, name, scratch, extra,
140 extra2, extra3); 141 extra2, extra3);
141 142
142 // Primary miss: Compute hash for secondary table. 143 // Primary miss: Compute hash for secondary table.
143 __ Sub(scratch, scratch, Operand(name, LSR, kCacheIndexShift)); 144 __ Sub(scratch, scratch, Operand(name, LSR, kCacheIndexShift));
144 __ Add(scratch, scratch, flags >> kCacheIndexShift); 145 __ Add(scratch, scratch, flags >> kCacheIndexShift);
145 __ And(scratch, scratch, kSecondaryTableSize - 1); 146 __ And(scratch, scratch, kSecondaryTableSize - 1);
146 147
147 // Probe the secondary table. 148 // Probe the secondary table.
148 ProbeTable(isolate, masm, flags, kSecondary, receiver, name, scratch, extra, 149 ProbeTable(this, masm, flags, kSecondary, receiver, name, scratch, extra,
149 extra2, extra3); 150 extra2, extra3);
150 151
151 // Cache miss: Fall-through and let caller handle the miss by 152 // Cache miss: Fall-through and let caller handle the miss by
152 // entering the runtime system. 153 // entering the runtime system.
153 __ Bind(&miss); 154 __ Bind(&miss);
154 __ IncrementCounter(counters->megamorphic_stub_cache_misses(), 1, extra2, 155 __ IncrementCounter(counters->megamorphic_stub_cache_misses(), 1, extra2,
155 extra3); 156 extra3);
156 } 157 }
157 } // namespace internal 158 } // namespace internal
158 } // namespace v8 159 } // namespace v8
159 160
160 #endif // V8_TARGET_ARCH_ARM64 161 #endif // V8_TARGET_ARCH_ARM64
OLDNEW
« no previous file with comments | « src/ic/arm64/ic-arm64.cc ('k') | src/ic/ia32/ic-ia32.cc » ('j') | src/ic/x64/stub-cache-x64.cc » ('J')

Powered by Google App Engine
This is Rietveld 408576698