OLD | NEW |
1 // Copyright 2014 the V8 project authors. All rights reserved. | 1 // Copyright 2014 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/type-feedback-vector.h" | 5 #include "src/type-feedback-vector.h" |
6 | 6 |
7 #include "src/code-stubs.h" | 7 #include "src/code-stubs.h" |
8 #include "src/ic/ic.h" | 8 #include "src/ic/ic.h" |
9 #include "src/ic/ic-state.h" | 9 #include "src/ic/ic-state.h" |
10 #include "src/objects.h" | 10 #include "src/objects.h" |
11 #include "src/type-feedback-vector-inl.h" | 11 #include "src/type-feedback-vector-inl.h" |
12 | 12 |
13 namespace v8 { | 13 namespace v8 { |
14 namespace internal { | 14 namespace internal { |
15 | 15 |
16 std::ostream& operator<<(std::ostream& os, FeedbackVectorSlotKind kind) { | 16 std::ostream& operator<<(std::ostream& os, FeedbackVectorSlotKind kind) { |
17 return os << TypeFeedbackVector::Kind2String(kind); | 17 return os << TypeFeedbackVector::Kind2String(kind); |
18 } | 18 } |
19 | 19 |
20 | 20 |
21 FeedbackVectorSlotKind TypeFeedbackVector::GetKind( | 21 FeedbackVectorSlotKind TypeFeedbackVector::GetKind( |
22 FeedbackVectorICSlot slot) const { | 22 FeedbackVectorSlot slot) const { |
23 int index = VectorICComputer::index(kReservedIndexCount, slot.ToInt()); | 23 int index = VectorICComputer::index(kReservedIndexCount, slot.ToInt()); |
24 int data = Smi::cast(get(index))->value(); | 24 int data = Smi::cast(get(index))->value(); |
25 return VectorICComputer::decode(data, slot.ToInt()); | 25 return VectorICComputer::decode(data, slot.ToInt()); |
26 } | 26 } |
27 | 27 |
28 | 28 |
29 void TypeFeedbackVector::SetKind(FeedbackVectorICSlot slot, | 29 void TypeFeedbackVector::SetKind(FeedbackVectorSlot slot, |
30 FeedbackVectorSlotKind kind) { | 30 FeedbackVectorSlotKind kind) { |
31 int index = VectorICComputer::index(kReservedIndexCount, slot.ToInt()); | 31 int index = VectorICComputer::index(kReservedIndexCount, slot.ToInt()); |
32 int data = Smi::cast(get(index))->value(); | 32 int data = Smi::cast(get(index))->value(); |
33 int new_data = VectorICComputer::encode(data, slot.ToInt(), kind); | 33 int new_data = VectorICComputer::encode(data, slot.ToInt(), kind); |
34 set(index, Smi::FromInt(new_data)); | 34 set(index, Smi::FromInt(new_data)); |
35 } | 35 } |
36 | 36 |
37 | 37 |
38 template Handle<TypeFeedbackVector> TypeFeedbackVector::Allocate( | 38 template Handle<TypeFeedbackVector> TypeFeedbackVector::New( |
39 Isolate* isolate, const StaticFeedbackVectorSpec* spec); | 39 Isolate* isolate, const StaticFeedbackVectorSpec* spec); |
40 template Handle<TypeFeedbackVector> TypeFeedbackVector::Allocate( | 40 template Handle<TypeFeedbackVector> TypeFeedbackVector::New( |
41 Isolate* isolate, const FeedbackVectorSpec* spec); | 41 Isolate* isolate, const FeedbackVectorSpec* spec); |
42 | 42 |
43 | 43 |
44 // static | 44 // static |
45 template <typename Spec> | 45 template <typename Spec> |
46 Handle<TypeFeedbackVector> TypeFeedbackVector::Allocate(Isolate* isolate, | 46 Handle<TypeFeedbackVector> TypeFeedbackVector::New(Isolate* isolate, |
47 const Spec* spec) { | 47 const Spec* spec) { |
48 const int slot_count = spec->slots(); | 48 const int slot_count = spec->slots(); |
49 const int ic_slot_count = spec->ic_slots(); | 49 const int index_count = VectorICComputer::word_count(slot_count); |
50 const int index_count = VectorICComputer::word_count(ic_slot_count); | 50 const int length = slot_count + index_count + kReservedIndexCount; |
51 const int length = slot_count + (ic_slot_count * elements_per_ic_slot()) + | |
52 index_count + kReservedIndexCount; | |
53 if (length == kReservedIndexCount) { | 51 if (length == kReservedIndexCount) { |
54 return Handle<TypeFeedbackVector>::cast( | 52 return Handle<TypeFeedbackVector>::cast( |
55 isolate->factory()->empty_fixed_array()); | 53 isolate->factory()->empty_fixed_array()); |
56 } | 54 } |
| 55 #ifdef DEBUG |
| 56 for (int i = 0; i < slot_count;) { |
| 57 FeedbackVectorSlotKind kind = spec->GetKind(i); |
| 58 int entry_size = TypeFeedbackVector::GetSlotSize(kind); |
| 59 for (int j = 1; j < entry_size; j++) { |
| 60 FeedbackVectorSlotKind kind = spec->GetKind(i + j); |
| 61 DCHECK_EQ(FeedbackVectorSlotKind::INVALID, kind); |
| 62 } |
| 63 i += entry_size; |
| 64 } |
| 65 #endif |
57 | 66 |
58 Handle<FixedArray> array = isolate->factory()->NewFixedArray(length, TENURED); | 67 Handle<FixedArray> array = isolate->factory()->NewFixedArray(length, TENURED); |
59 if (ic_slot_count > 0) { | 68 array->set(kSlotsCountIndex, Smi::FromInt(slot_count)); |
60 array->set(kFirstICSlotIndex, | |
61 Smi::FromInt(slot_count + index_count + kReservedIndexCount)); | |
62 } else { | |
63 array->set(kFirstICSlotIndex, Smi::FromInt(length)); | |
64 } | |
65 array->set(kWithTypesIndex, Smi::FromInt(0)); | 69 array->set(kWithTypesIndex, Smi::FromInt(0)); |
66 array->set(kGenericCountIndex, Smi::FromInt(0)); | 70 array->set(kGenericCountIndex, Smi::FromInt(0)); |
67 // Fill the indexes with zeros. | 71 // Fill the indexes with zeros. |
68 for (int i = 0; i < index_count; i++) { | 72 for (int i = 0; i < index_count; i++) { |
69 array->set(kReservedIndexCount + i, Smi::FromInt(0)); | 73 array->set(kReservedIndexCount + i, Smi::FromInt(0)); |
70 } | 74 } |
71 | 75 |
72 // Ensure we can skip the write barrier | 76 // Ensure we can skip the write barrier |
73 Handle<Object> uninitialized_sentinel = UninitializedSentinel(isolate); | 77 Handle<Object> uninitialized_sentinel = UninitializedSentinel(isolate); |
74 DCHECK_EQ(isolate->heap()->uninitialized_symbol(), *uninitialized_sentinel); | 78 DCHECK_EQ(isolate->heap()->uninitialized_symbol(), *uninitialized_sentinel); |
75 for (int i = kReservedIndexCount + index_count; i < length; i++) { | 79 for (int i = kReservedIndexCount + index_count; i < length; i++) { |
76 array->set(i, *uninitialized_sentinel, SKIP_WRITE_BARRIER); | 80 array->set(i, *uninitialized_sentinel, SKIP_WRITE_BARRIER); |
77 } | 81 } |
78 | 82 |
79 Handle<TypeFeedbackVector> vector = Handle<TypeFeedbackVector>::cast(array); | 83 Handle<TypeFeedbackVector> vector = Handle<TypeFeedbackVector>::cast(array); |
80 for (int i = 0; i < ic_slot_count; i++) { | 84 for (int i = 0; i < slot_count; i++) { |
81 vector->SetKind(FeedbackVectorICSlot(i), spec->GetKind(i)); | 85 vector->SetKind(FeedbackVectorSlot(i), spec->GetKind(i)); |
82 } | 86 } |
83 return vector; | 87 return vector; |
84 } | 88 } |
85 | 89 |
86 | 90 |
87 template int TypeFeedbackVector::GetIndexFromSpec(const FeedbackVectorSpec*, | |
88 FeedbackVectorICSlot); | |
89 template int TypeFeedbackVector::GetIndexFromSpec(const FeedbackVectorSpec*, | |
90 FeedbackVectorSlot); | |
91 | |
92 | |
93 // static | 91 // static |
94 template <typename Spec> | 92 int TypeFeedbackVector::GetIndexFromSpec(const FeedbackVectorSpec* spec, |
95 int TypeFeedbackVector::GetIndexFromSpec(const Spec* spec, | |
96 FeedbackVectorSlot slot) { | 93 FeedbackVectorSlot slot) { |
97 const int ic_slot_count = spec->ic_slots(); | 94 const int slot_count = spec->slots(); |
98 const int index_count = VectorICComputer::word_count(ic_slot_count); | 95 const int index_count = VectorICComputer::word_count(slot_count); |
99 return kReservedIndexCount + index_count + slot.ToInt(); | 96 return kReservedIndexCount + index_count + slot.ToInt(); |
100 } | 97 } |
101 | 98 |
102 | 99 |
103 // static | |
104 template <typename Spec> | |
105 int TypeFeedbackVector::GetIndexFromSpec(const Spec* spec, | |
106 FeedbackVectorICSlot slot) { | |
107 const int slot_count = spec->slots(); | |
108 const int ic_slot_count = spec->ic_slots(); | |
109 const int index_count = VectorICComputer::word_count(ic_slot_count); | |
110 return kReservedIndexCount + index_count + slot_count + | |
111 slot.ToInt() * elements_per_ic_slot(); | |
112 } | |
113 | |
114 | |
115 // static | 100 // static |
116 int TypeFeedbackVector::PushAppliedArgumentsIndex() { | 101 int TypeFeedbackVector::PushAppliedArgumentsIndex() { |
117 const int index_count = VectorICComputer::word_count(1); | 102 const int index_count = VectorICComputer::word_count(1); |
118 return kReservedIndexCount + index_count; | 103 return kReservedIndexCount + index_count; |
119 } | 104 } |
120 | 105 |
121 | 106 |
122 // static | 107 // static |
123 Handle<TypeFeedbackVector> TypeFeedbackVector::CreatePushAppliedArgumentsVector( | 108 Handle<TypeFeedbackVector> TypeFeedbackVector::CreatePushAppliedArgumentsVector( |
124 Isolate* isolate) { | 109 Isolate* isolate) { |
125 FeedbackVectorSlotKind kinds[] = {FeedbackVectorSlotKind::KEYED_LOAD_IC}; | 110 StaticFeedbackVectorSpec spec; |
126 StaticFeedbackVectorSpec spec(0, 1, kinds); | 111 FeedbackVectorSlot slot = spec.AddKeyedLoadICSlot(); |
127 Handle<TypeFeedbackVector> feedback_vector = | 112 Handle<TypeFeedbackVector> feedback_vector = |
128 isolate->factory()->NewTypeFeedbackVector(&spec); | 113 TypeFeedbackVector::New(isolate, &spec); |
129 DCHECK(PushAppliedArgumentsIndex() == | 114 DCHECK_EQ(PushAppliedArgumentsIndex(), feedback_vector->GetIndex(slot)); |
130 feedback_vector->GetIndex(FeedbackVectorICSlot(0))); | 115 USE(slot); |
131 return feedback_vector; | 116 return feedback_vector; |
132 } | 117 } |
133 | 118 |
134 | 119 |
135 // static | 120 // static |
136 Handle<TypeFeedbackVector> TypeFeedbackVector::Copy( | 121 Handle<TypeFeedbackVector> TypeFeedbackVector::Copy( |
137 Isolate* isolate, Handle<TypeFeedbackVector> vector) { | 122 Isolate* isolate, Handle<TypeFeedbackVector> vector) { |
138 Handle<TypeFeedbackVector> result; | 123 Handle<TypeFeedbackVector> result; |
139 result = Handle<TypeFeedbackVector>::cast( | 124 result = Handle<TypeFeedbackVector>::cast( |
140 isolate->factory()->CopyFixedArray(Handle<FixedArray>::cast(vector))); | 125 isolate->factory()->CopyFixedArray(Handle<FixedArray>::cast(vector))); |
141 return result; | 126 return result; |
142 } | 127 } |
143 | 128 |
144 | 129 |
145 bool TypeFeedbackVector::SpecDiffersFrom( | 130 bool TypeFeedbackVector::SpecDiffersFrom( |
146 const FeedbackVectorSpec* other_spec) const { | 131 const FeedbackVectorSpec* other_spec) const { |
147 if (other_spec->slots() != Slots() || other_spec->ic_slots() != ICSlots()) { | 132 if (other_spec->slots() != Slots()) { |
148 return true; | 133 return true; |
149 } | 134 } |
150 | 135 |
151 int ic_slots = ICSlots(); | 136 int slots = Slots(); |
152 for (int i = 0; i < ic_slots; i++) { | 137 for (int i = 0; i < slots; i++) { |
153 if (GetKind(FeedbackVectorICSlot(i)) != other_spec->GetKind(i)) { | 138 if (GetKind(FeedbackVectorSlot(i)) != other_spec->GetKind(i)) { |
154 return true; | 139 return true; |
155 } | 140 } |
156 } | 141 } |
157 return false; | 142 return false; |
158 } | 143 } |
159 | 144 |
160 | 145 |
161 // This logic is copied from | 146 // This logic is copied from |
162 // StaticMarkingVisitor<StaticVisitor>::VisitCodeTarget. | 147 // StaticMarkingVisitor<StaticVisitor>::VisitCodeTarget. |
163 static bool ClearLogic(Heap* heap) { | 148 static bool ClearLogic(Isolate* isolate) { |
164 return FLAG_cleanup_code_caches_at_gc && | 149 return FLAG_cleanup_code_caches_at_gc && isolate->serializer_enabled(); |
165 heap->isolate()->serializer_enabled(); | |
166 } | 150 } |
167 | 151 |
168 | 152 |
169 void TypeFeedbackVector::ClearSlotsImpl(SharedFunctionInfo* shared, | 153 void TypeFeedbackVector::ClearSlotsImpl(SharedFunctionInfo* shared, |
170 bool force_clear) { | 154 bool force_clear) { |
171 int slots = Slots(); | 155 Isolate* isolate = GetIsolate(); |
172 Heap* heap = GetIsolate()->heap(); | |
173 | 156 |
174 if (!force_clear && !ClearLogic(heap)) return; | 157 if (!force_clear && !ClearLogic(isolate)) return; |
175 | 158 |
176 Object* uninitialized_sentinel = | 159 Object* uninitialized_sentinel = |
177 TypeFeedbackVector::RawUninitializedSentinel(heap); | 160 TypeFeedbackVector::RawUninitializedSentinel(isolate); |
178 for (int i = 0; i < slots; i++) { | |
179 FeedbackVectorSlot slot(i); | |
180 Object* obj = Get(slot); | |
181 if (obj->IsHeapObject()) { | |
182 InstanceType instance_type = | |
183 HeapObject::cast(obj)->map()->instance_type(); | |
184 // AllocationSites are exempt from clearing. They don't store Maps | |
185 // or Code pointers which can cause memory leaks if not cleared | |
186 // regularly. | |
187 if (instance_type != ALLOCATION_SITE_TYPE) { | |
188 Set(slot, uninitialized_sentinel, SKIP_WRITE_BARRIER); | |
189 } | |
190 } | |
191 } | |
192 } | |
193 | 161 |
| 162 TypeFeedbackMetadataIterator iter(this); |
| 163 while (iter.HasNext()) { |
| 164 FeedbackVectorSlot slot = iter.Next(); |
| 165 FeedbackVectorSlotKind kind = iter.kind(); |
194 | 166 |
195 void TypeFeedbackVector::ClearICSlotsImpl(SharedFunctionInfo* shared, | |
196 bool force_clear) { | |
197 Heap* heap = GetIsolate()->heap(); | |
198 | |
199 if (!force_clear && !ClearLogic(heap)) return; | |
200 | |
201 int slots = ICSlots(); | |
202 Code* host = shared->code(); | |
203 Object* uninitialized_sentinel = | |
204 TypeFeedbackVector::RawUninitializedSentinel(heap); | |
205 for (int i = 0; i < slots; i++) { | |
206 FeedbackVectorICSlot slot(i); | |
207 Object* obj = Get(slot); | 167 Object* obj = Get(slot); |
208 if (obj != uninitialized_sentinel) { | 168 if (obj != uninitialized_sentinel) { |
209 FeedbackVectorSlotKind kind = GetKind(slot); | |
210 switch (kind) { | 169 switch (kind) { |
211 case FeedbackVectorSlotKind::CALL_IC: { | 170 case FeedbackVectorSlotKind::CALL_IC: { |
212 CallICNexus nexus(this, slot); | 171 CallICNexus nexus(this, slot); |
213 nexus.Clear(host); | 172 nexus.Clear(shared->code()); |
214 break; | 173 break; |
215 } | 174 } |
216 case FeedbackVectorSlotKind::LOAD_IC: { | 175 case FeedbackVectorSlotKind::LOAD_IC: { |
217 LoadICNexus nexus(this, slot); | 176 LoadICNexus nexus(this, slot); |
218 nexus.Clear(host); | 177 nexus.Clear(shared->code()); |
219 break; | 178 break; |
220 } | 179 } |
221 case FeedbackVectorSlotKind::KEYED_LOAD_IC: { | 180 case FeedbackVectorSlotKind::KEYED_LOAD_IC: { |
222 KeyedLoadICNexus nexus(this, slot); | 181 KeyedLoadICNexus nexus(this, slot); |
223 nexus.Clear(host); | 182 nexus.Clear(shared->code()); |
224 break; | 183 break; |
225 } | 184 } |
226 case FeedbackVectorSlotKind::STORE_IC: { | 185 case FeedbackVectorSlotKind::STORE_IC: { |
227 DCHECK(FLAG_vector_stores); | 186 DCHECK(FLAG_vector_stores); |
228 StoreICNexus nexus(this, slot); | 187 StoreICNexus nexus(this, slot); |
229 nexus.Clear(host); | 188 nexus.Clear(shared->code()); |
230 break; | 189 break; |
231 } | 190 } |
232 case FeedbackVectorSlotKind::KEYED_STORE_IC: { | 191 case FeedbackVectorSlotKind::KEYED_STORE_IC: { |
233 DCHECK(FLAG_vector_stores); | 192 DCHECK(FLAG_vector_stores); |
234 KeyedStoreICNexus nexus(this, slot); | 193 KeyedStoreICNexus nexus(this, slot); |
235 nexus.Clear(host); | 194 nexus.Clear(shared->code()); |
236 break; | 195 break; |
237 } | 196 } |
238 case FeedbackVectorSlotKind::UNUSED: | 197 case FeedbackVectorSlotKind::GENERAL: { |
| 198 if (obj->IsHeapObject()) { |
| 199 InstanceType instance_type = |
| 200 HeapObject::cast(obj)->map()->instance_type(); |
| 201 // AllocationSites are exempt from clearing. They don't store Maps |
| 202 // or Code pointers which can cause memory leaks if not cleared |
| 203 // regularly. |
| 204 if (instance_type != ALLOCATION_SITE_TYPE) { |
| 205 Set(slot, uninitialized_sentinel, SKIP_WRITE_BARRIER); |
| 206 } |
| 207 } |
| 208 break; |
| 209 } |
| 210 case FeedbackVectorSlotKind::INVALID: |
239 case FeedbackVectorSlotKind::KINDS_NUMBER: | 211 case FeedbackVectorSlotKind::KINDS_NUMBER: |
240 UNREACHABLE(); | 212 UNREACHABLE(); |
241 break; | 213 break; |
242 } | 214 } |
243 } | 215 } |
244 } | 216 } |
245 } | 217 } |
246 | 218 |
247 | 219 |
248 // static | 220 // static |
249 void TypeFeedbackVector::ClearAllKeyedStoreICs(Isolate* isolate) { | 221 void TypeFeedbackVector::ClearAllKeyedStoreICs(Isolate* isolate) { |
250 DCHECK(FLAG_vector_stores); | 222 DCHECK(FLAG_vector_stores); |
251 SharedFunctionInfo::Iterator iterator(isolate); | 223 SharedFunctionInfo::Iterator iterator(isolate); |
252 SharedFunctionInfo* shared; | 224 SharedFunctionInfo* shared; |
253 while ((shared = iterator.Next())) { | 225 while ((shared = iterator.Next())) { |
254 TypeFeedbackVector* vector = shared->feedback_vector(); | 226 TypeFeedbackVector* vector = shared->feedback_vector(); |
255 vector->ClearKeyedStoreICs(shared); | 227 vector->ClearKeyedStoreICs(shared); |
256 } | 228 } |
257 } | 229 } |
258 | 230 |
259 | 231 |
260 void TypeFeedbackVector::ClearKeyedStoreICs(SharedFunctionInfo* shared) { | 232 void TypeFeedbackVector::ClearKeyedStoreICs(SharedFunctionInfo* shared) { |
261 Heap* heap = GetIsolate()->heap(); | 233 Isolate* isolate = GetIsolate(); |
262 | 234 |
263 int slots = ICSlots(); | |
264 Code* host = shared->code(); | 235 Code* host = shared->code(); |
265 Object* uninitialized_sentinel = | 236 Object* uninitialized_sentinel = |
266 TypeFeedbackVector::RawUninitializedSentinel(heap); | 237 TypeFeedbackVector::RawUninitializedSentinel(isolate); |
267 for (int i = 0; i < slots; i++) { | 238 |
268 FeedbackVectorICSlot slot(i); | 239 TypeFeedbackMetadataIterator iter(this); |
| 240 while (iter.HasNext()) { |
| 241 FeedbackVectorSlot slot = iter.Next(); |
| 242 FeedbackVectorSlotKind kind = iter.kind(); |
| 243 if (kind != FeedbackVectorSlotKind::KEYED_STORE_IC) continue; |
269 Object* obj = Get(slot); | 244 Object* obj = Get(slot); |
270 if (obj != uninitialized_sentinel) { | 245 if (obj != uninitialized_sentinel) { |
271 FeedbackVectorSlotKind kind = GetKind(slot); | 246 DCHECK(FLAG_vector_stores); |
272 if (kind == FeedbackVectorSlotKind::KEYED_STORE_IC) { | 247 KeyedStoreICNexus nexus(this, slot); |
273 DCHECK(FLAG_vector_stores); | 248 nexus.Clear(host); |
274 KeyedStoreICNexus nexus(this, slot); | |
275 nexus.Clear(host); | |
276 } | |
277 } | 249 } |
278 } | 250 } |
279 } | 251 } |
280 | 252 |
281 | 253 |
282 // static | 254 // static |
283 Handle<TypeFeedbackVector> TypeFeedbackVector::DummyVector(Isolate* isolate) { | 255 Handle<TypeFeedbackVector> TypeFeedbackVector::DummyVector(Isolate* isolate) { |
284 return Handle<TypeFeedbackVector>::cast(isolate->factory()->dummy_vector()); | 256 return isolate->factory()->dummy_vector(); |
285 } | 257 } |
286 | 258 |
287 | 259 |
288 const char* TypeFeedbackVector::Kind2String(FeedbackVectorSlotKind kind) { | 260 const char* TypeFeedbackVector::Kind2String(FeedbackVectorSlotKind kind) { |
289 switch (kind) { | 261 switch (kind) { |
290 case FeedbackVectorSlotKind::UNUSED: | 262 case FeedbackVectorSlotKind::INVALID: |
291 return "UNUSED"; | 263 return "INVALID"; |
292 case FeedbackVectorSlotKind::CALL_IC: | 264 case FeedbackVectorSlotKind::CALL_IC: |
293 return "CALL_IC"; | 265 return "CALL_IC"; |
294 case FeedbackVectorSlotKind::LOAD_IC: | 266 case FeedbackVectorSlotKind::LOAD_IC: |
295 return "LOAD_IC"; | 267 return "LOAD_IC"; |
296 case FeedbackVectorSlotKind::KEYED_LOAD_IC: | 268 case FeedbackVectorSlotKind::KEYED_LOAD_IC: |
297 return "KEYED_LOAD_IC"; | 269 return "KEYED_LOAD_IC"; |
298 case FeedbackVectorSlotKind::STORE_IC: | 270 case FeedbackVectorSlotKind::STORE_IC: |
299 return "STORE_IC"; | 271 return "STORE_IC"; |
300 case FeedbackVectorSlotKind::KEYED_STORE_IC: | 272 case FeedbackVectorSlotKind::KEYED_STORE_IC: |
301 return "KEYED_STORE_IC"; | 273 return "KEYED_STORE_IC"; |
| 274 case FeedbackVectorSlotKind::GENERAL: |
| 275 return "STUB"; |
302 case FeedbackVectorSlotKind::KINDS_NUMBER: | 276 case FeedbackVectorSlotKind::KINDS_NUMBER: |
303 break; | 277 break; |
304 } | 278 } |
305 UNREACHABLE(); | 279 UNREACHABLE(); |
306 return "?"; | 280 return "?"; |
307 } | 281 } |
308 | 282 |
309 | 283 |
310 Handle<FixedArray> FeedbackNexus::EnsureArrayOfSize(int length) { | 284 Handle<FixedArray> FeedbackNexus::EnsureArrayOfSize(int length) { |
311 Isolate* isolate = GetIsolate(); | 285 Isolate* isolate = GetIsolate(); |
(...skipping 519 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
831 return mode; | 805 return mode; |
832 } | 806 } |
833 | 807 |
834 | 808 |
835 IcCheckType KeyedStoreICNexus::GetKeyType() const { | 809 IcCheckType KeyedStoreICNexus::GetKeyType() const { |
836 // The structure of the vector slots tells us the type. | 810 // The structure of the vector slots tells us the type. |
837 return GetFeedback()->IsName() ? PROPERTY : ELEMENT; | 811 return GetFeedback()->IsName() ? PROPERTY : ELEMENT; |
838 } | 812 } |
839 } // namespace internal | 813 } // namespace internal |
840 } // namespace v8 | 814 } // namespace v8 |
OLD | NEW |