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 205 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
216 SetFeedback(*array); | 216 SetFeedback(*array); |
217 return array; | 217 return array; |
218 } | 218 } |
219 return Handle<FixedArray>::cast(feedback); | 219 return Handle<FixedArray>::cast(feedback); |
220 } | 220 } |
221 | 221 |
222 | 222 |
223 void FeedbackNexus::InstallHandlers(int start_index, TypeHandleList* types, | 223 void FeedbackNexus::InstallHandlers(int start_index, TypeHandleList* types, |
224 CodeHandleList* handlers) { | 224 CodeHandleList* handlers) { |
225 Isolate* isolate = GetIsolate(); | 225 Isolate* isolate = GetIsolate(); |
226 FixedArray* array = FixedArray::cast(GetFeedback()); | 226 Handle<FixedArray> array = handle(FixedArray::cast(GetFeedback()), isolate); |
227 int receiver_count = types->length(); | 227 int receiver_count = types->length(); |
228 for (int current = 0; current < receiver_count; ++current) { | 228 for (int current = 0; current < receiver_count; ++current) { |
229 Handle<HeapType> type = types->at(current); | 229 Handle<HeapType> type = types->at(current); |
230 Handle<Map> map = IC::TypeToMap(*type, isolate); | 230 Handle<Map> map = IC::TypeToMap(*type, isolate); |
231 array->set(start_index + (current * 2), *map); | 231 Handle<WeakCell> cell = Map::WeakCellForMap(map); |
| 232 array->set(start_index + (current * 2), *cell); |
232 array->set(start_index + (current * 2 + 1), *handlers->at(current)); | 233 array->set(start_index + (current * 2 + 1), *handlers->at(current)); |
233 } | 234 } |
234 } | 235 } |
235 | 236 |
236 | 237 |
237 InlineCacheState LoadICNexus::StateFromFeedback() const { | 238 InlineCacheState LoadICNexus::StateFromFeedback() const { |
238 Isolate* isolate = GetIsolate(); | 239 Isolate* isolate = GetIsolate(); |
239 Object* feedback = GetFeedback(); | 240 Object* feedback = GetFeedback(); |
240 if (feedback == *vector()->UninitializedSentinel(isolate)) { | 241 if (feedback == *vector()->UninitializedSentinel(isolate)) { |
241 return UNINITIALIZED; | 242 return UNINITIALIZED; |
242 } else if (feedback == *vector()->MegamorphicSentinel(isolate)) { | 243 } else if (feedback == *vector()->MegamorphicSentinel(isolate)) { |
243 return MEGAMORPHIC; | 244 return MEGAMORPHIC; |
244 } else if (feedback == *vector()->PremonomorphicSentinel(isolate)) { | 245 } else if (feedback == *vector()->PremonomorphicSentinel(isolate)) { |
245 return PREMONOMORPHIC; | 246 return PREMONOMORPHIC; |
246 } else if (feedback->IsFixedArray()) { | 247 } else if (feedback->IsFixedArray()) { |
| 248 // Determine state purely by our structure, don't check if the maps are |
| 249 // cleared. |
247 FixedArray* array = FixedArray::cast(feedback); | 250 FixedArray* array = FixedArray::cast(feedback); |
248 int length = array->length(); | 251 int length = array->length(); |
249 DCHECK(length >= 2); | 252 DCHECK(length >= 2); |
250 return length == 2 ? MONOMORPHIC : POLYMORPHIC; | 253 return length == 2 ? MONOMORPHIC : POLYMORPHIC; |
251 } | 254 } |
252 | 255 |
253 return UNINITIALIZED; | 256 return UNINITIALIZED; |
254 } | 257 } |
255 | 258 |
256 | 259 |
257 InlineCacheState KeyedLoadICNexus::StateFromFeedback() const { | 260 InlineCacheState KeyedLoadICNexus::StateFromFeedback() const { |
258 Isolate* isolate = GetIsolate(); | 261 Isolate* isolate = GetIsolate(); |
259 Object* feedback = GetFeedback(); | 262 Object* feedback = GetFeedback(); |
260 if (feedback == *vector()->UninitializedSentinel(isolate)) { | 263 if (feedback == *vector()->UninitializedSentinel(isolate)) { |
261 return UNINITIALIZED; | 264 return UNINITIALIZED; |
262 } else if (feedback == *vector()->PremonomorphicSentinel(isolate)) { | 265 } else if (feedback == *vector()->PremonomorphicSentinel(isolate)) { |
263 return PREMONOMORPHIC; | 266 return PREMONOMORPHIC; |
264 } else if (feedback == *vector()->GenericSentinel(isolate)) { | 267 } else if (feedback == *vector()->GenericSentinel(isolate)) { |
265 return GENERIC; | 268 return GENERIC; |
266 } else if (feedback->IsFixedArray()) { | 269 } else if (feedback->IsFixedArray()) { |
| 270 // Determine state purely by our structure, don't check if the maps are |
| 271 // cleared. |
267 FixedArray* array = FixedArray::cast(feedback); | 272 FixedArray* array = FixedArray::cast(feedback); |
268 int length = array->length(); | 273 int length = array->length(); |
269 DCHECK(length >= 3); | 274 DCHECK(length >= 3); |
270 return length == 3 ? MONOMORPHIC : POLYMORPHIC; | 275 return length == 3 ? MONOMORPHIC : POLYMORPHIC; |
271 } | 276 } |
272 | 277 |
273 return UNINITIALIZED; | 278 return UNINITIALIZED; |
274 } | 279 } |
275 | 280 |
276 | 281 |
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
337 void KeyedLoadICNexus::ConfigurePremonomorphic() { | 342 void KeyedLoadICNexus::ConfigurePremonomorphic() { |
338 SetFeedback(*vector()->PremonomorphicSentinel(GetIsolate()), | 343 SetFeedback(*vector()->PremonomorphicSentinel(GetIsolate()), |
339 SKIP_WRITE_BARRIER); | 344 SKIP_WRITE_BARRIER); |
340 } | 345 } |
341 | 346 |
342 | 347 |
343 void LoadICNexus::ConfigureMonomorphic(Handle<HeapType> type, | 348 void LoadICNexus::ConfigureMonomorphic(Handle<HeapType> type, |
344 Handle<Code> handler) { | 349 Handle<Code> handler) { |
345 Handle<FixedArray> array = EnsureArrayOfSize(2); | 350 Handle<FixedArray> array = EnsureArrayOfSize(2); |
346 Handle<Map> receiver_map = IC::TypeToMap(*type, GetIsolate()); | 351 Handle<Map> receiver_map = IC::TypeToMap(*type, GetIsolate()); |
347 array->set(0, *receiver_map); | 352 Handle<WeakCell> cell = Map::WeakCellForMap(receiver_map); |
| 353 array->set(0, *cell); |
348 array->set(1, *handler); | 354 array->set(1, *handler); |
349 } | 355 } |
350 | 356 |
351 | 357 |
352 void KeyedLoadICNexus::ConfigureMonomorphic(Handle<Name> name, | 358 void KeyedLoadICNexus::ConfigureMonomorphic(Handle<Name> name, |
353 Handle<HeapType> type, | 359 Handle<HeapType> type, |
354 Handle<Code> handler) { | 360 Handle<Code> handler) { |
355 Handle<FixedArray> array = EnsureArrayOfSize(3); | 361 Handle<FixedArray> array = EnsureArrayOfSize(3); |
356 Handle<Map> receiver_map = IC::TypeToMap(*type, GetIsolate()); | 362 Handle<Map> receiver_map = IC::TypeToMap(*type, GetIsolate()); |
357 if (name.is_null()) { | 363 if (name.is_null()) { |
358 array->set(0, Smi::FromInt(0)); | 364 array->set(0, Smi::FromInt(0)); |
359 } else { | 365 } else { |
360 array->set(0, *name); | 366 array->set(0, *name); |
361 } | 367 } |
362 array->set(1, *receiver_map); | 368 Handle<WeakCell> cell = Map::WeakCellForMap(receiver_map); |
| 369 array->set(1, *cell); |
363 array->set(2, *handler); | 370 array->set(2, *handler); |
364 } | 371 } |
365 | 372 |
366 | 373 |
367 void LoadICNexus::ConfigurePolymorphic(TypeHandleList* types, | 374 void LoadICNexus::ConfigurePolymorphic(TypeHandleList* types, |
368 CodeHandleList* handlers) { | 375 CodeHandleList* handlers) { |
369 int receiver_count = types->length(); | 376 int receiver_count = types->length(); |
370 EnsureArrayOfSize(receiver_count * 2); | 377 EnsureArrayOfSize(receiver_count * 2); |
371 InstallHandlers(0, types, handlers); | 378 InstallHandlers(0, types, handlers); |
372 } | 379 } |
(...skipping 10 matching lines...) Expand all Loading... |
383 array->set(0, *name); | 390 array->set(0, *name); |
384 } | 391 } |
385 InstallHandlers(1, types, handlers); | 392 InstallHandlers(1, types, handlers); |
386 } | 393 } |
387 | 394 |
388 | 395 |
389 int FeedbackNexus::ExtractMaps(int start_index, MapHandleList* maps) const { | 396 int FeedbackNexus::ExtractMaps(int start_index, MapHandleList* maps) const { |
390 Isolate* isolate = GetIsolate(); | 397 Isolate* isolate = GetIsolate(); |
391 Object* feedback = GetFeedback(); | 398 Object* feedback = GetFeedback(); |
392 if (feedback->IsFixedArray()) { | 399 if (feedback->IsFixedArray()) { |
| 400 int found = 0; |
393 FixedArray* array = FixedArray::cast(feedback); | 401 FixedArray* array = FixedArray::cast(feedback); |
394 // The array should be of the form [<optional name>], then | 402 // The array should be of the form [<optional name>], then |
395 // [map, handler, map, handler, ... ] | 403 // [map, handler, map, handler, ... ] |
396 DCHECK(array->length() >= (2 + start_index)); | 404 DCHECK(array->length() >= (2 + start_index)); |
397 for (int i = start_index; i < array->length(); i += 2) { | 405 for (int i = start_index; i < array->length(); i += 2) { |
398 Map* map = Map::cast(array->get(i)); | 406 WeakCell* cell = WeakCell::cast(array->get(i)); |
399 maps->Add(handle(map, isolate)); | 407 if (!cell->cleared()) { |
| 408 Map* map = Map::cast(cell->value()); |
| 409 maps->Add(handle(map, isolate)); |
| 410 found++; |
| 411 } |
400 } | 412 } |
401 return (array->length() - start_index) / 2; | 413 return found; |
402 } | 414 } |
403 | 415 |
404 return 0; | 416 return 0; |
405 } | 417 } |
406 | 418 |
407 | 419 |
408 MaybeHandle<Code> FeedbackNexus::FindHandlerForMap(int start_index, | 420 MaybeHandle<Code> FeedbackNexus::FindHandlerForMap(int start_index, |
409 Handle<Map> map) const { | 421 Handle<Map> map) const { |
410 Object* feedback = GetFeedback(); | 422 Object* feedback = GetFeedback(); |
411 if (feedback->IsFixedArray()) { | 423 if (feedback->IsFixedArray()) { |
412 FixedArray* array = FixedArray::cast(feedback); | 424 FixedArray* array = FixedArray::cast(feedback); |
413 for (int i = start_index; i < array->length(); i += 2) { | 425 for (int i = start_index; i < array->length(); i += 2) { |
414 Map* array_map = Map::cast(array->get(i)); | 426 WeakCell* cell = WeakCell::cast(array->get(i)); |
415 if (array_map == *map) { | 427 if (!cell->cleared()) { |
416 Code* code = Code::cast(array->get(i + 1)); | 428 Map* array_map = Map::cast(cell->value()); |
417 DCHECK(code->kind() == Code::HANDLER); | 429 if (array_map == *map) { |
418 return handle(code); | 430 Code* code = Code::cast(array->get(i + 1)); |
| 431 DCHECK(code->kind() == Code::HANDLER); |
| 432 return handle(code); |
| 433 } |
419 } | 434 } |
420 } | 435 } |
421 } | 436 } |
422 | 437 |
423 return MaybeHandle<Code>(); | 438 return MaybeHandle<Code>(); |
424 } | 439 } |
425 | 440 |
426 | 441 |
427 bool FeedbackNexus::FindHandlers(int start_index, CodeHandleList* code_list, | 442 bool FeedbackNexus::FindHandlers(int start_index, CodeHandleList* code_list, |
428 int length) const { | 443 int length) const { |
429 Object* feedback = GetFeedback(); | 444 Object* feedback = GetFeedback(); |
430 int count = 0; | 445 int count = 0; |
431 if (feedback->IsFixedArray()) { | 446 if (feedback->IsFixedArray()) { |
432 FixedArray* array = FixedArray::cast(feedback); | 447 FixedArray* array = FixedArray::cast(feedback); |
433 // The array should be of the form [<optional name>], then | 448 // The array should be of the form [<optional name>], then |
434 // [map, handler, map, handler, ... ] | 449 // [map, handler, map, handler, ... ]. Be sure to skip handlers whose maps |
| 450 // have been cleared. |
435 DCHECK(array->length() >= (2 + start_index)); | 451 DCHECK(array->length() >= (2 + start_index)); |
436 for (int i = start_index; i < array->length(); i += 2) { | 452 for (int i = start_index; i < array->length(); i += 2) { |
437 Code* code = Code::cast(array->get(i + 1)); | 453 WeakCell* cell = WeakCell::cast(array->get(i)); |
438 DCHECK(code->kind() == Code::HANDLER); | 454 if (!cell->cleared()) { |
439 code_list->Add(handle(code)); | 455 Code* code = Code::cast(array->get(i + 1)); |
440 count++; | 456 DCHECK(code->kind() == Code::HANDLER); |
| 457 code_list->Add(handle(code)); |
| 458 count++; |
| 459 } |
441 } | 460 } |
442 } | 461 } |
443 return count == length; | 462 return count == length; |
444 } | 463 } |
445 | 464 |
446 | 465 |
447 int LoadICNexus::ExtractMaps(MapHandleList* maps) const { | 466 int LoadICNexus::ExtractMaps(MapHandleList* maps) const { |
448 return FeedbackNexus::ExtractMaps(0, maps); | 467 return FeedbackNexus::ExtractMaps(0, maps); |
449 } | 468 } |
450 | 469 |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
488 if (feedback->IsFixedArray()) { | 507 if (feedback->IsFixedArray()) { |
489 FixedArray* array = FixedArray::cast(feedback); | 508 FixedArray* array = FixedArray::cast(feedback); |
490 DCHECK(array->length() >= 3); | 509 DCHECK(array->length() >= 3); |
491 Object* name = array->get(0); | 510 Object* name = array->get(0); |
492 if (name->IsName()) return Name::cast(name); | 511 if (name->IsName()) return Name::cast(name); |
493 } | 512 } |
494 return NULL; | 513 return NULL; |
495 } | 514 } |
496 } | 515 } |
497 } // namespace v8::internal | 516 } // namespace v8::internal |
OLD | NEW |