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/v8.h" | 5 #include "src/v8.h" |
6 | 6 |
7 #include "src/ic/ic.h" | 7 #include "src/ic/ic.h" |
8 #include "src/ic/ic-state.h" | 8 #include "src/ic/ic-state.h" |
9 #include "src/objects.h" | 9 #include "src/objects.h" |
10 #include "src/type-feedback-vector-inl.h" | 10 #include "src/type-feedback-vector-inl.h" |
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
69 | 69 |
70 VectorICKind b = FromCodeKind(kind); | 70 VectorICKind b = FromCodeKind(kind); |
71 int index = VectorICComputer::index(kReservedIndexCount, slot.ToInt()); | 71 int index = VectorICComputer::index(kReservedIndexCount, slot.ToInt()); |
72 int data = Smi::cast(get(index))->value(); | 72 int data = Smi::cast(get(index))->value(); |
73 int new_data = VectorICComputer::encode(data, slot.ToInt(), b); | 73 int new_data = VectorICComputer::encode(data, slot.ToInt(), b); |
74 set(index, Smi::FromInt(new_data)); | 74 set(index, Smi::FromInt(new_data)); |
75 } | 75 } |
76 | 76 |
77 | 77 |
78 // static | 78 // static |
79 Handle<TypeFeedbackVector> TypeFeedbackVector::Allocate(Isolate* isolate, | 79 Handle<TypeFeedbackVector> TypeFeedbackVector::Allocate( |
80 int slot_count, | 80 Isolate* isolate, const FeedbackVectorSpec& spec) { |
81 int ic_slot_count) { | 81 const int slot_count = spec.slots(); |
82 int index_count = | 82 const int ic_slot_count = spec.ic_slots(); |
| 83 const int index_count = |
83 FLAG_vector_ics ? VectorICComputer::word_count(ic_slot_count) : 0; | 84 FLAG_vector_ics ? VectorICComputer::word_count(ic_slot_count) : 0; |
84 int length = slot_count + ic_slot_count + index_count + kReservedIndexCount; | 85 const int length = |
| 86 slot_count + ic_slot_count + index_count + kReservedIndexCount; |
85 if (length == kReservedIndexCount) { | 87 if (length == kReservedIndexCount) { |
86 return Handle<TypeFeedbackVector>::cast( | 88 return Handle<TypeFeedbackVector>::cast( |
87 isolate->factory()->empty_fixed_array()); | 89 isolate->factory()->empty_fixed_array()); |
88 } | 90 } |
89 | 91 |
90 Handle<FixedArray> array = isolate->factory()->NewFixedArray(length, TENURED); | 92 Handle<FixedArray> array = isolate->factory()->NewFixedArray(length, TENURED); |
91 if (ic_slot_count > 0) { | 93 if (ic_slot_count > 0) { |
92 array->set(kFirstICSlotIndex, | 94 array->set(kFirstICSlotIndex, |
93 Smi::FromInt(slot_count + index_count + kReservedIndexCount)); | 95 Smi::FromInt(slot_count + index_count + kReservedIndexCount)); |
94 } else { | 96 } else { |
95 array->set(kFirstICSlotIndex, Smi::FromInt(length)); | 97 array->set(kFirstICSlotIndex, Smi::FromInt(length)); |
96 } | 98 } |
97 array->set(kWithTypesIndex, Smi::FromInt(0)); | 99 array->set(kWithTypesIndex, Smi::FromInt(0)); |
98 array->set(kGenericCountIndex, Smi::FromInt(0)); | 100 array->set(kGenericCountIndex, Smi::FromInt(0)); |
99 // Fill the indexes with zeros. | |
100 for (int i = 0; i < index_count; i++) { | |
101 array->set(kReservedIndexCount + i, Smi::FromInt(0)); | |
102 } | |
103 | 101 |
104 // Ensure we can skip the write barrier | 102 // Ensure we can skip the write barrier |
105 Handle<Object> uninitialized_sentinel = UninitializedSentinel(isolate); | 103 Handle<Object> uninitialized_sentinel = UninitializedSentinel(isolate); |
106 DCHECK_EQ(isolate->heap()->uninitialized_symbol(), *uninitialized_sentinel); | 104 DCHECK_EQ(isolate->heap()->uninitialized_symbol(), *uninitialized_sentinel); |
107 for (int i = kReservedIndexCount + index_count; i < length; i++) { | 105 for (int i = kReservedIndexCount + index_count; i < length; i++) { |
108 array->set(i, *uninitialized_sentinel, SKIP_WRITE_BARRIER); | 106 array->set(i, *uninitialized_sentinel, SKIP_WRITE_BARRIER); |
109 } | 107 } |
110 return Handle<TypeFeedbackVector>::cast(array); | 108 |
| 109 Handle<TypeFeedbackVector> vector = Handle<TypeFeedbackVector>::cast(array); |
| 110 if (FLAG_vector_ics) { |
| 111 for (int i = 0; i < ic_slot_count; i++) { |
| 112 vector->SetKind(FeedbackVectorICSlot(i), spec.GetKind(i)); |
| 113 } |
| 114 } |
| 115 return vector; |
111 } | 116 } |
112 | 117 |
113 | 118 |
114 // static | 119 // static |
115 Handle<TypeFeedbackVector> TypeFeedbackVector::Copy( | 120 Handle<TypeFeedbackVector> TypeFeedbackVector::Copy( |
116 Isolate* isolate, Handle<TypeFeedbackVector> vector) { | 121 Isolate* isolate, Handle<TypeFeedbackVector> vector) { |
117 Handle<TypeFeedbackVector> result; | 122 Handle<TypeFeedbackVector> result; |
118 result = Handle<TypeFeedbackVector>::cast( | 123 result = Handle<TypeFeedbackVector>::cast( |
119 isolate->factory()->CopyFixedArray(Handle<FixedArray>::cast(vector))); | 124 isolate->factory()->CopyFixedArray(Handle<FixedArray>::cast(vector))); |
120 return result; | 125 return result; |
121 } | 126 } |
122 | 127 |
123 | 128 |
| 129 // This logic is copied from |
| 130 // StaticMarkingVisitor<StaticVisitor>::VisitCodeTarget. |
| 131 // TODO(mvstanton): with weak handling of all vector ics, this logic should |
| 132 // actually be completely eliminated and we no longer need to clear the |
| 133 // vector ICs. |
| 134 static bool ClearLogic(Heap* heap, int ic_age, Code::Kind kind, |
| 135 InlineCacheState state) { |
| 136 if (FLAG_cleanup_code_caches_at_gc && |
| 137 (kind == Code::CALL_IC || state == MEGAMORPHIC || state == GENERIC || |
| 138 state == POLYMORPHIC || heap->flush_monomorphic_ics() || |
| 139 // TODO(mvstanton): is this ic_age granular enough? it comes from |
| 140 // the SharedFunctionInfo which may change on a different schedule |
| 141 // than ic targets. |
| 142 // ic_age != heap->global_ic_age() || |
| 143 // is_invalidated_weak_stub || |
| 144 heap->isolate()->serializer_enabled())) { |
| 145 return true; |
| 146 } |
| 147 return false; |
| 148 } |
| 149 |
| 150 |
124 void TypeFeedbackVector::ClearSlots(SharedFunctionInfo* shared) { | 151 void TypeFeedbackVector::ClearSlots(SharedFunctionInfo* shared) { |
125 int slots = Slots(); | 152 int slots = Slots(); |
126 Isolate* isolate = GetIsolate(); | 153 Isolate* isolate = GetIsolate(); |
127 Object* uninitialized_sentinel = | 154 Object* uninitialized_sentinel = |
128 TypeFeedbackVector::RawUninitializedSentinel(isolate->heap()); | 155 TypeFeedbackVector::RawUninitializedSentinel(isolate->heap()); |
129 | 156 |
130 for (int i = 0; i < slots; i++) { | 157 for (int i = 0; i < slots; i++) { |
131 FeedbackVectorSlot slot(i); | 158 FeedbackVectorSlot slot(i); |
132 Object* obj = Get(slot); | 159 Object* obj = Get(slot); |
133 if (obj->IsHeapObject()) { | 160 if (obj->IsHeapObject()) { |
134 InstanceType instance_type = | 161 InstanceType instance_type = |
135 HeapObject::cast(obj)->map()->instance_type(); | 162 HeapObject::cast(obj)->map()->instance_type(); |
136 // AllocationSites are exempt from clearing. They don't store Maps | 163 // AllocationSites are exempt from clearing. They don't store Maps |
137 // or Code pointers which can cause memory leaks if not cleared | 164 // or Code pointers which can cause memory leaks if not cleared |
138 // regularly. | 165 // regularly. |
139 if (instance_type != ALLOCATION_SITE_TYPE) { | 166 if (instance_type != ALLOCATION_SITE_TYPE) { |
140 Set(slot, uninitialized_sentinel, SKIP_WRITE_BARRIER); | 167 Set(slot, uninitialized_sentinel, SKIP_WRITE_BARRIER); |
141 } | 168 } |
142 } | 169 } |
143 } | 170 } |
144 | 171 |
145 slots = ICSlots(); | 172 slots = ICSlots(); |
146 if (slots == 0) return; | 173 if (slots == 0) return; |
147 | 174 |
148 // Now clear vector-based ICs. They are all CallICs. | 175 // Now clear vector-based ICs. |
149 // Try and pass the containing code (the "host"). | 176 // Try and pass the containing code (the "host"). |
| 177 Heap* heap = isolate->heap(); |
150 Code* host = shared->code(); | 178 Code* host = shared->code(); |
| 179 // I'm not sure yet if this ic age is the correct one. |
| 180 int ic_age = shared->ic_age(); |
151 for (int i = 0; i < slots; i++) { | 181 for (int i = 0; i < slots; i++) { |
152 FeedbackVectorICSlot slot(i); | 182 FeedbackVectorICSlot slot(i); |
153 Object* obj = Get(slot); | 183 Object* obj = Get(slot); |
154 if (obj != uninitialized_sentinel) { | 184 if (obj != uninitialized_sentinel) { |
155 // TODO(mvstanton): To make this code work with --vector-ics, | 185 Code::Kind kind = GetKind(slot); |
156 // additional Nexus types must be created. | 186 if (kind == Code::CALL_IC) { |
157 DCHECK(!FLAG_vector_ics); | 187 CallICNexus nexus(this, slot); |
158 DCHECK(GetKind(slot) == Code::CALL_IC); | 188 if (ClearLogic(heap, ic_age, kind, nexus.StateFromFeedback())) { |
159 CallICNexus nexus(this, slot); | 189 nexus.Clear(host); |
160 ICUtility::Clear(isolate, Code::CALL_IC, host, &nexus); | 190 } |
| 191 } else if (kind == Code::LOAD_IC) { |
| 192 LoadICNexus nexus(this, slot); |
| 193 if (ClearLogic(heap, ic_age, kind, nexus.StateFromFeedback())) { |
| 194 nexus.Clear(host); |
| 195 } |
| 196 } else if (kind == Code::KEYED_LOAD_IC) { |
| 197 KeyedLoadICNexus nexus(this, slot); |
| 198 if (ClearLogic(heap, ic_age, kind, nexus.StateFromFeedback())) { |
| 199 nexus.Clear(host); |
| 200 } |
| 201 } |
161 } | 202 } |
162 } | 203 } |
163 } | 204 } |
164 | 205 |
165 | 206 |
166 Handle<FixedArray> FeedbackNexus::EnsureArrayOfSize(int length) { | 207 Handle<FixedArray> FeedbackNexus::EnsureArrayOfSize(int length) { |
167 Isolate* isolate = GetIsolate(); | 208 Isolate* isolate = GetIsolate(); |
168 Handle<Object> feedback = handle(GetFeedback(), isolate); | 209 Handle<Object> feedback = handle(GetFeedback(), isolate); |
169 if (!feedback->IsFixedArray() || | 210 if (!feedback->IsFixedArray() || |
170 FixedArray::cast(*feedback)->length() != length) { | 211 FixedArray::cast(*feedback)->length() != length) { |
(...skipping 12 matching lines...) Expand all Loading... |
183 int receiver_count = types->length(); | 224 int receiver_count = types->length(); |
184 for (int current = 0; current < receiver_count; ++current) { | 225 for (int current = 0; current < receiver_count; ++current) { |
185 Handle<HeapType> type = types->at(current); | 226 Handle<HeapType> type = types->at(current); |
186 Handle<Map> map = IC::TypeToMap(*type, isolate); | 227 Handle<Map> map = IC::TypeToMap(*type, isolate); |
187 array->set(start_index + (current * 2), *map); | 228 array->set(start_index + (current * 2), *map); |
188 array->set(start_index + (current * 2 + 1), *handlers->at(current)); | 229 array->set(start_index + (current * 2 + 1), *handlers->at(current)); |
189 } | 230 } |
190 } | 231 } |
191 | 232 |
192 | 233 |
| 234 InlineCacheState LoadICNexus::StateFromFeedback() const { |
| 235 Isolate* isolate = GetIsolate(); |
| 236 Object* feedback = GetFeedback(); |
| 237 if (feedback == *vector()->UninitializedSentinel(isolate)) { |
| 238 return UNINITIALIZED; |
| 239 } else if (feedback == *vector()->MegamorphicSentinel(isolate)) { |
| 240 return MEGAMORPHIC; |
| 241 } else if (feedback == *vector()->PremonomorphicSentinel(isolate)) { |
| 242 return PREMONOMORPHIC; |
| 243 } else if (feedback->IsFixedArray()) { |
| 244 FixedArray* array = FixedArray::cast(feedback); |
| 245 int length = array->length(); |
| 246 DCHECK(length >= 2); |
| 247 return length == 2 ? MONOMORPHIC : POLYMORPHIC; |
| 248 } |
| 249 |
| 250 return UNINITIALIZED; |
| 251 } |
| 252 |
| 253 |
| 254 InlineCacheState KeyedLoadICNexus::StateFromFeedback() const { |
| 255 Isolate* isolate = GetIsolate(); |
| 256 Object* feedback = GetFeedback(); |
| 257 if (feedback == *vector()->UninitializedSentinel(isolate)) { |
| 258 return UNINITIALIZED; |
| 259 } else if (feedback == *vector()->PremonomorphicSentinel(isolate)) { |
| 260 return PREMONOMORPHIC; |
| 261 } else if (feedback == *vector()->MegamorphicSentinel(isolate)) { |
| 262 return MEGAMORPHIC; |
| 263 } else if (feedback == *vector()->GenericSentinel(isolate)) { |
| 264 return GENERIC; |
| 265 } else if (feedback->IsFixedArray()) { |
| 266 FixedArray* array = FixedArray::cast(feedback); |
| 267 int length = array->length(); |
| 268 DCHECK(length >= 3); |
| 269 return length == 3 ? MONOMORPHIC : POLYMORPHIC; |
| 270 } |
| 271 |
| 272 return UNINITIALIZED; |
| 273 } |
| 274 |
| 275 |
193 InlineCacheState CallICNexus::StateFromFeedback() const { | 276 InlineCacheState CallICNexus::StateFromFeedback() const { |
194 Isolate* isolate = GetIsolate(); | 277 Isolate* isolate = GetIsolate(); |
195 InlineCacheState state = UNINITIALIZED; | |
196 Object* feedback = GetFeedback(); | 278 Object* feedback = GetFeedback(); |
197 | 279 |
198 if (feedback == *vector()->MegamorphicSentinel(isolate)) { | 280 if (feedback == *vector()->MegamorphicSentinel(isolate)) { |
199 state = GENERIC; | 281 return GENERIC; |
200 } else if (feedback->IsAllocationSite() || feedback->IsJSFunction()) { | 282 } else if (feedback->IsAllocationSite() || feedback->IsJSFunction()) { |
201 state = MONOMORPHIC; | 283 return MONOMORPHIC; |
202 } else { | |
203 CHECK(feedback == *vector()->UninitializedSentinel(isolate)); | |
204 } | 284 } |
205 | 285 |
206 return state; | 286 CHECK(feedback == *vector()->UninitializedSentinel(isolate)); |
| 287 return UNINITIALIZED; |
207 } | 288 } |
208 | 289 |
209 | 290 |
| 291 void CallICNexus::Clear(Code* host) { CallIC::Clear(GetIsolate(), host, this); } |
| 292 |
| 293 |
210 void CallICNexus::ConfigureGeneric() { | 294 void CallICNexus::ConfigureGeneric() { |
211 SetFeedback(*vector()->MegamorphicSentinel(GetIsolate()), SKIP_WRITE_BARRIER); | 295 SetFeedback(*vector()->MegamorphicSentinel(GetIsolate()), SKIP_WRITE_BARRIER); |
212 } | 296 } |
213 | 297 |
214 | 298 |
215 void CallICNexus::ConfigureMonomorphicArray() { | 299 void CallICNexus::ConfigureMonomorphicArray() { |
216 Object* feedback = GetFeedback(); | 300 Object* feedback = GetFeedback(); |
217 if (!feedback->IsAllocationSite()) { | 301 if (!feedback->IsAllocationSite()) { |
218 Handle<AllocationSite> new_site = | 302 Handle<AllocationSite> new_site = |
219 GetIsolate()->factory()->NewAllocationSite(); | 303 GetIsolate()->factory()->NewAllocationSite(); |
220 SetFeedback(*new_site); | 304 SetFeedback(*new_site); |
221 } | 305 } |
222 } | 306 } |
223 | 307 |
224 | 308 |
225 void CallICNexus::ConfigureUninitialized() { | 309 void CallICNexus::ConfigureUninitialized() { |
226 SetFeedback(*vector()->UninitializedSentinel(GetIsolate()), | 310 SetFeedback(*vector()->UninitializedSentinel(GetIsolate()), |
227 SKIP_WRITE_BARRIER); | 311 SKIP_WRITE_BARRIER); |
228 } | 312 } |
229 | 313 |
230 | 314 |
231 void CallICNexus::ConfigureMonomorphic(Handle<JSFunction> function) { | 315 void CallICNexus::ConfigureMonomorphic(Handle<JSFunction> function) { |
232 SetFeedback(*function); | 316 SetFeedback(*function); |
233 } | 317 } |
234 | 318 |
235 | 319 |
| 320 void KeyedLoadICNexus::ConfigureGeneric() { |
| 321 SetFeedback(*vector()->GenericSentinel(GetIsolate()), SKIP_WRITE_BARRIER); |
| 322 } |
| 323 |
| 324 |
| 325 void KeyedLoadICNexus::ConfigureMegamorphic() { |
| 326 SetFeedback(*vector()->MegamorphicSentinel(GetIsolate()), SKIP_WRITE_BARRIER); |
| 327 } |
| 328 |
| 329 |
| 330 void LoadICNexus::ConfigureMegamorphic() { |
| 331 SetFeedback(*vector()->MegamorphicSentinel(GetIsolate()), SKIP_WRITE_BARRIER); |
| 332 } |
| 333 |
| 334 |
| 335 void LoadICNexus::ConfigurePremonomorphic() { |
| 336 SetFeedback(*vector()->PremonomorphicSentinel(GetIsolate()), |
| 337 SKIP_WRITE_BARRIER); |
| 338 } |
| 339 |
| 340 |
| 341 void KeyedLoadICNexus::ConfigurePremonomorphic() { |
| 342 SetFeedback(*vector()->PremonomorphicSentinel(GetIsolate()), |
| 343 SKIP_WRITE_BARRIER); |
| 344 } |
| 345 |
| 346 |
| 347 void LoadICNexus::ConfigureMonomorphic(Handle<HeapType> type, |
| 348 Handle<Code> handler) { |
| 349 Handle<FixedArray> array = EnsureArrayOfSize(2); |
| 350 Handle<Map> receiver_map = IC::TypeToMap(*type, GetIsolate()); |
| 351 array->set(0, *receiver_map); |
| 352 array->set(1, *handler); |
| 353 } |
| 354 |
| 355 |
| 356 void KeyedLoadICNexus::ConfigureMonomorphic(Handle<Name> name, |
| 357 Handle<HeapType> type, |
| 358 Handle<Code> handler) { |
| 359 Handle<FixedArray> array = EnsureArrayOfSize(3); |
| 360 Handle<Map> receiver_map = IC::TypeToMap(*type, GetIsolate()); |
| 361 if (name.is_null()) { |
| 362 array->set(0, Smi::FromInt(0)); |
| 363 } else { |
| 364 array->set(0, *name); |
| 365 } |
| 366 array->set(1, *receiver_map); |
| 367 array->set(2, *handler); |
| 368 } |
| 369 |
| 370 |
| 371 void LoadICNexus::ConfigurePolymorphic(TypeHandleList* types, |
| 372 CodeHandleList* handlers) { |
| 373 int receiver_count = types->length(); |
| 374 EnsureArrayOfSize(receiver_count * 2); |
| 375 InstallHandlers(0, types, handlers); |
| 376 } |
| 377 |
| 378 |
| 379 void KeyedLoadICNexus::ConfigurePolymorphic(Handle<Name> name, |
| 380 TypeHandleList* types, |
| 381 CodeHandleList* handlers) { |
| 382 int receiver_count = types->length(); |
| 383 Handle<FixedArray> array = EnsureArrayOfSize(1 + receiver_count * 2); |
| 384 if (name.is_null()) { |
| 385 array->set(0, Smi::FromInt(0)); |
| 386 } else { |
| 387 array->set(0, *name); |
| 388 } |
| 389 InstallHandlers(1, types, handlers); |
| 390 } |
| 391 |
| 392 |
236 int FeedbackNexus::ExtractMaps(int start_index, MapHandleList* maps) const { | 393 int FeedbackNexus::ExtractMaps(int start_index, MapHandleList* maps) const { |
237 Isolate* isolate = GetIsolate(); | 394 Isolate* isolate = GetIsolate(); |
238 Object* feedback = GetFeedback(); | 395 Object* feedback = GetFeedback(); |
239 if (feedback->IsFixedArray()) { | 396 if (feedback->IsFixedArray()) { |
240 FixedArray* array = FixedArray::cast(feedback); | 397 FixedArray* array = FixedArray::cast(feedback); |
241 // The array should be of the form [<optional name>], then | 398 // The array should be of the form [<optional name>], then |
242 // [map, handler, map, handler, ... ] | 399 // [map, handler, map, handler, ... ] |
243 DCHECK(array->length() >= (2 + start_index)); | 400 DCHECK(array->length() >= (2 + start_index)); |
244 for (int i = start_index; i < array->length(); i += 2) { | 401 for (int i = start_index; i < array->length(); i += 2) { |
245 Map* map = Map::cast(array->get(i)); | 402 Map* map = Map::cast(array->get(i)); |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
282 DCHECK(array->length() >= (2 + start_index)); | 439 DCHECK(array->length() >= (2 + start_index)); |
283 for (int i = start_index; i < array->length(); i += 2) { | 440 for (int i = start_index; i < array->length(); i += 2) { |
284 Code* code = Code::cast(array->get(i + 1)); | 441 Code* code = Code::cast(array->get(i + 1)); |
285 DCHECK(code->kind() == Code::HANDLER); | 442 DCHECK(code->kind() == Code::HANDLER); |
286 code_list->Add(handle(code)); | 443 code_list->Add(handle(code)); |
287 count++; | 444 count++; |
288 } | 445 } |
289 } | 446 } |
290 return count == length; | 447 return count == length; |
291 } | 448 } |
| 449 |
| 450 |
| 451 int LoadICNexus::ExtractMaps(MapHandleList* maps) const { |
| 452 return FeedbackNexus::ExtractMaps(0, maps); |
| 453 } |
| 454 |
| 455 |
| 456 void LoadICNexus::Clear(Code* host) { LoadIC::Clear(GetIsolate(), host, this); } |
| 457 |
| 458 |
| 459 void KeyedLoadICNexus::Clear(Code* host) { |
| 460 KeyedLoadIC::Clear(GetIsolate(), host, this); |
| 461 } |
| 462 |
| 463 |
| 464 int KeyedLoadICNexus::ExtractMaps(MapHandleList* maps) const { |
| 465 return FeedbackNexus::ExtractMaps(1, maps); |
| 466 } |
| 467 |
| 468 |
| 469 MaybeHandle<Code> LoadICNexus::FindHandlerForMap(Handle<Map> map) const { |
| 470 return FeedbackNexus::FindHandlerForMap(0, map); |
| 471 } |
| 472 |
| 473 |
| 474 MaybeHandle<Code> KeyedLoadICNexus::FindHandlerForMap(Handle<Map> map) const { |
| 475 return FeedbackNexus::FindHandlerForMap(1, map); |
| 476 } |
| 477 |
| 478 |
| 479 bool LoadICNexus::FindHandlers(CodeHandleList* code_list, int length) const { |
| 480 return FeedbackNexus::FindHandlers(0, code_list, length); |
| 481 } |
| 482 |
| 483 |
| 484 bool KeyedLoadICNexus::FindHandlers(CodeHandleList* code_list, |
| 485 int length) const { |
| 486 return FeedbackNexus::FindHandlers(1, code_list, length); |
| 487 } |
| 488 |
| 489 |
| 490 Name* KeyedLoadICNexus::FindFirstName() const { |
| 491 Object* feedback = GetFeedback(); |
| 492 if (feedback->IsFixedArray()) { |
| 493 FixedArray* array = FixedArray::cast(feedback); |
| 494 DCHECK(array->length() >= 3); |
| 495 Object* name = array->get(0); |
| 496 if (name->IsName()) return Name::cast(name); |
| 497 } |
| 498 return NULL; |
| 499 } |
292 } | 500 } |
293 } // namespace v8::internal | 501 } // namespace v8::internal |
OLD | NEW |