OLD | NEW |
---|---|
1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project authors. All rights reserved. |
2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
4 // met: | 4 // met: |
5 // | 5 // |
6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
(...skipping 131 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
142 StackFrameIterator it(isolate); | 142 StackFrameIterator it(isolate); |
143 for (int i = 0; i < depth + 1; i++) it.Advance(); | 143 for (int i = 0; i < depth + 1; i++) it.Advance(); |
144 StackFrame* frame = it.frame(); | 144 StackFrame* frame = it.frame(); |
145 ASSERT(fp == frame->fp() && pc_address == frame->pc_address()); | 145 ASSERT(fp == frame->fp() && pc_address == frame->pc_address()); |
146 #endif | 146 #endif |
147 fp_ = fp; | 147 fp_ = fp; |
148 pc_address_ = StackFrame::ResolveReturnAddressLocation(pc_address); | 148 pc_address_ = StackFrame::ResolveReturnAddressLocation(pc_address); |
149 target_ = handle(raw_target(), isolate); | 149 target_ = handle(raw_target(), isolate); |
150 state_ = target_->ic_state(); | 150 state_ = target_->ic_state(); |
151 extra_ic_state_ = target_->extra_ic_state(); | 151 extra_ic_state_ = target_->extra_ic_state(); |
152 target()->FindAllTypes(&types_); | |
153 target()->FindHandlers(&handlers_); | |
154 } | 152 } |
155 | 153 |
156 | 154 |
157 #ifdef ENABLE_DEBUGGER_SUPPORT | 155 #ifdef ENABLE_DEBUGGER_SUPPORT |
158 Address IC::OriginalCodeAddress() const { | 156 Address IC::OriginalCodeAddress() const { |
159 HandleScope scope(isolate()); | 157 HandleScope scope(isolate()); |
160 // Compute the JavaScript frame for the frame pointer of this IC | 158 // Compute the JavaScript frame for the frame pointer of this IC |
161 // structure. We need this to be able to find the function | 159 // structure. We need this to be able to find the function |
162 // corresponding to the frame. | 160 // corresponding to the frame. |
163 StackFrameIterator it(isolate()); | 161 StackFrameIterator it(isolate()); |
(...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
276 | 274 |
277 // The stub is not in the cache. We've ruled out all other kinds of failure | 275 // The stub is not in the cache. We've ruled out all other kinds of failure |
278 // except for proptotype chain changes, a deprecated map, a map that's | 276 // except for proptotype chain changes, a deprecated map, a map that's |
279 // different from the one that the stub expects, elements kind changes, or a | 277 // different from the one that the stub expects, elements kind changes, or a |
280 // constant global property that will become mutable. Threat all those | 278 // constant global property that will become mutable. Threat all those |
281 // situations as prototype failures (stay monomorphic if possible). | 279 // situations as prototype failures (stay monomorphic if possible). |
282 | 280 |
283 // If the IC is shared between multiple receivers (slow dictionary mode), then | 281 // If the IC is shared between multiple receivers (slow dictionary mode), then |
284 // the map cannot be deprecated and the stub invalidated. | 282 // the map cannot be deprecated and the stub invalidated. |
285 if (cache_holder == OWN_MAP) { | 283 if (cache_holder == OWN_MAP) { |
286 Map* old_map = first_map(); | 284 Map* old_map = target()->FindFirstMap(); |
287 if (old_map == *map) return true; | 285 if (old_map == *map) return true; |
288 if (old_map != NULL) { | 286 if (old_map != NULL) { |
289 if (old_map->is_deprecated()) return true; | 287 if (old_map->is_deprecated()) return true; |
290 if (IsMoreGeneralElementsKindTransition(old_map->elements_kind(), | 288 if (IsMoreGeneralElementsKindTransition(old_map->elements_kind(), |
291 map->elements_kind())) { | 289 map->elements_kind())) { |
292 return true; | 290 return true; |
293 } | 291 } |
294 } | 292 } |
295 } | 293 } |
296 | 294 |
297 if (receiver->IsGlobalObject()) { | 295 if (receiver->IsGlobalObject()) { |
298 LookupResult lookup(isolate()); | 296 LookupResult lookup(isolate()); |
299 GlobalObject* global = GlobalObject::cast(*receiver); | 297 GlobalObject* global = GlobalObject::cast(*receiver); |
300 global->LocalLookupRealNamedProperty(*name, &lookup); | 298 global->LocalLookupRealNamedProperty(*name, &lookup); |
301 if (!lookup.IsFound()) return false; | 299 if (!lookup.IsFound()) return false; |
302 PropertyCell* cell = global->GetPropertyCell(&lookup); | 300 PropertyCell* cell = global->GetPropertyCell(&lookup); |
303 return cell->type()->IsConstant(); | 301 return cell->type()->IsConstant(); |
304 } | 302 } |
305 | 303 |
306 return false; | 304 return false; |
307 } | 305 } |
308 | 306 |
309 | 307 |
310 void IC::TryRemoveInvalidHandlers(Handle<Map> map, Handle<String> name) { | 308 void IC::TryRemoveInvalidHandlers(Handle<Map> map, Handle<String> name) { |
311 for (int i = 0; i < handlers()->length(); i++) { | 309 CodeHandleList handlers; |
312 Handle<Code> handler = handlers()->at(i); | 310 target()->FindHandlers(&handlers); |
311 for (int i = 0; i < handlers.length(); i++) { | |
312 Handle<Code> handler = handlers.at(i); | |
313 int index = map->IndexInCodeCache(*name, *handler); | 313 int index = map->IndexInCodeCache(*name, *handler); |
314 if (index >= 0) { | 314 if (index >= 0) { |
315 map->RemoveFromCodeCache(*name, *handler, index); | 315 map->RemoveFromCodeCache(*name, *handler, index); |
316 return; | 316 return; |
317 } | 317 } |
318 } | 318 } |
319 } | 319 } |
320 | 320 |
321 | 321 |
322 void IC::UpdateState(Handle<Object> receiver, Handle<Object> name) { | 322 void IC::UpdateState(Handle<Object> receiver, Handle<Object> name) { |
(...skipping 275 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
598 } | 598 } |
599 receiver_maps->Add(new_receiver_map); | 599 receiver_maps->Add(new_receiver_map); |
600 return true; | 600 return true; |
601 } | 601 } |
602 | 602 |
603 | 603 |
604 bool IC::UpdatePolymorphicIC(Handle<HeapType> type, | 604 bool IC::UpdatePolymorphicIC(Handle<HeapType> type, |
605 Handle<String> name, | 605 Handle<String> name, |
606 Handle<Code> code) { | 606 Handle<Code> code) { |
607 if (!code->is_handler()) return false; | 607 if (!code->is_handler()) return false; |
608 TypeHandleList types; | |
609 CodeHandleList handlers; | |
610 | |
608 int number_of_valid_types; | 611 int number_of_valid_types; |
609 int handler_to_overwrite = -1; | 612 int handler_to_overwrite = -1; |
610 | 613 |
611 int number_of_types = types()->length(); | 614 target()->FindAllTypes(&types); |
615 int number_of_types = types.length(); | |
612 number_of_valid_types = number_of_types; | 616 number_of_valid_types = number_of_types; |
613 | 617 |
614 for (int i = 0; i < number_of_types; i++) { | 618 for (int i = 0; i < number_of_types; i++) { |
615 Handle<HeapType> current_type = types()->at(i); | 619 Handle<HeapType> current_type = types.at(i); |
616 // Filter out deprecated maps to ensure their instances get migrated. | 620 // Filter out deprecated maps to ensure their instances get migrated. |
617 if (current_type->IsClass() && current_type->AsClass()->is_deprecated()) { | 621 if (current_type->IsClass() && current_type->AsClass()->is_deprecated()) { |
618 number_of_valid_types--; | 622 number_of_valid_types--; |
619 // If the receiver type is already in the polymorphic IC, this indicates | 623 // If the receiver type is already in the polymorphic IC, this indicates |
620 // there was a prototoype chain failure. In that case, just overwrite the | 624 // there was a prototoype chain failure. In that case, just overwrite the |
621 // handler. | 625 // handler. |
622 } else if (type->IsCurrently(current_type)) { | 626 } else if (type->IsCurrently(current_type)) { |
623 ASSERT(handler_to_overwrite == -1); | 627 ASSERT(handler_to_overwrite == -1); |
624 number_of_valid_types--; | 628 number_of_valid_types--; |
625 handler_to_overwrite = i; | 629 handler_to_overwrite = i; |
626 } | 630 } |
627 } | 631 } |
628 | 632 |
629 if (number_of_valid_types >= 4) return false; | 633 if (number_of_valid_types >= 4) return false; |
630 if (number_of_types == 0) return false; | 634 if (number_of_types == 0) return false; |
631 if (handlers()->length() < types()->length()) return false; | 635 if (!target()->FindHandlers(&handlers, types.length())) return false; |
632 | 636 |
633 number_of_valid_types++; | 637 number_of_valid_types++; |
634 if (handler_to_overwrite >= 0) { | 638 if (handler_to_overwrite >= 0) { |
635 handlers()->Set(handler_to_overwrite, code); | 639 handlers.Set(handler_to_overwrite, code); |
636 } else { | 640 } else { |
637 types()->Add(type); | 641 types.Add(type); |
638 handlers()->Add(code); | 642 handlers.Add(code); |
639 } | 643 } |
640 | 644 |
641 Handle<Code> ic = isolate()->stub_cache()->ComputePolymorphicIC( | 645 Handle<Code> ic = isolate()->stub_cache()->ComputePolymorphicIC( |
642 kind(), types(), handlers(), number_of_valid_types, | 646 kind(), &types, &handlers, number_of_valid_types, name, extra_ic_state()); |
643 name, extra_ic_state()); | |
644 set_target(*ic); | 647 set_target(*ic); |
645 return true; | 648 return true; |
646 } | 649 } |
647 | 650 |
648 | 651 |
649 Handle<HeapType> IC::CurrentTypeOf(Handle<Object> object, Isolate* isolate) { | 652 Handle<HeapType> IC::CurrentTypeOf(Handle<Object> object, Isolate* isolate) { |
650 return object->IsJSGlobalObject() | 653 return object->IsJSGlobalObject() |
651 ? HeapType::Constant(Handle<JSGlobalObject>::cast(object), isolate) | 654 ? HeapType::Constant(Handle<JSGlobalObject>::cast(object), isolate) |
652 : HeapType::OfCurrently(object, isolate); | 655 : HeapType::OfCurrently(object, isolate); |
653 } | 656 } |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
691 Handle<Code> handler, | 694 Handle<Code> handler, |
692 Handle<String> name) { | 695 Handle<String> name) { |
693 if (!handler->is_handler()) return set_target(*handler); | 696 if (!handler->is_handler()) return set_target(*handler); |
694 Handle<Code> ic = isolate()->stub_cache()->ComputeMonomorphicIC( | 697 Handle<Code> ic = isolate()->stub_cache()->ComputeMonomorphicIC( |
695 kind(), name, type, handler, extra_ic_state()); | 698 kind(), name, type, handler, extra_ic_state()); |
696 set_target(*ic); | 699 set_target(*ic); |
697 } | 700 } |
698 | 701 |
699 | 702 |
700 void IC::CopyICToMegamorphicCache(Handle<String> name) { | 703 void IC::CopyICToMegamorphicCache(Handle<String> name) { |
701 if (handlers()->length() < types()->length()) return; | 704 TypeHandleList types; |
702 for (int i = 0; i < types()->length(); i++) { | 705 CodeHandleList handlers; |
703 UpdateMegamorphicCache(*types()->at(i), *name, *handlers()->at(i)); | 706 target()->FindAllTypes(&types); |
707 if (!target()->FindHandlers(&handlers, types.length())) return; | |
708 for (int i = 0; i < types.length(); i++) { | |
709 UpdateMegamorphicCache(*types.at(i), *name, *handlers.at(i)); | |
704 } | 710 } |
705 } | 711 } |
706 | 712 |
707 | 713 |
708 bool IC::IsTransitionOfMonomorphicTarget(Map* source_map, Map* target_map) { | 714 bool IC::IsTransitionOfMonomorphicTarget(Handle<HeapType> type) { |
709 if (source_map == NULL) return true; | 715 if (!type->IsClass()) return false; |
710 if (target_map == NULL) return false; | 716 Map* receiver_map = *type->AsClass(); |
711 ElementsKind target_elements_kind = target_map->elements_kind(); | 717 Map* current_map = target()->FindFirstMap(); |
712 bool more_general_transition = IsMoreGeneralElementsKindTransition( | 718 ElementsKind receiver_elements_kind = receiver_map->elements_kind(); |
713 source_map->elements_kind(), target_elements_kind); | 719 bool more_general_transition = |
720 IsMoreGeneralElementsKindTransition( | |
721 current_map->elements_kind(), receiver_elements_kind); | |
714 Map* transitioned_map = more_general_transition | 722 Map* transitioned_map = more_general_transition |
715 ? source_map->LookupElementsTransitionMap(target_elements_kind) | 723 ? current_map->LookupElementsTransitionMap(receiver_elements_kind) |
716 : NULL; | 724 : NULL; |
717 return transitioned_map == target_map; | 725 |
726 return transitioned_map == receiver_map; | |
718 } | 727 } |
719 | 728 |
720 | 729 |
721 void IC::PatchCache(Handle<HeapType> type, | 730 void IC::PatchCache(Handle<HeapType> type, |
722 Handle<String> name, | 731 Handle<String> name, |
723 Handle<Code> code) { | 732 Handle<Code> code) { |
724 switch (state()) { | 733 switch (state()) { |
725 case UNINITIALIZED: | 734 case UNINITIALIZED: |
726 case PREMONOMORPHIC: | 735 case PREMONOMORPHIC: |
727 case MONOMORPHIC_PROTOTYPE_FAILURE: | 736 case MONOMORPHIC_PROTOTYPE_FAILURE: |
728 UpdateMonomorphicIC(type, code, name); | 737 UpdateMonomorphicIC(type, code, name); |
729 break; | 738 break; |
730 case MONOMORPHIC: { | 739 case MONOMORPHIC: { |
731 // For now, call stubs are allowed to rewrite to the same stub. This | 740 // For now, call stubs are allowed to rewrite to the same stub. This |
732 // happens e.g., when the field does not contain a function. | 741 // happens e.g., when the field does not contain a function. |
733 ASSERT(!target().is_identical_to(code)); | 742 ASSERT(!target().is_identical_to(code)); |
734 Map* old_map = first_map(); | 743 Code* old_handler = target()->FindFirstHandler(); |
735 Code* old_handler = first_handler(); | 744 if (old_handler == *code && IsTransitionOfMonomorphicTarget(type)) { |
736 Map* map = type->IsClass() ? *type->AsClass() : NULL; | |
737 if (old_handler == *code && | |
738 IsTransitionOfMonomorphicTarget(old_map, map)) { | |
739 UpdateMonomorphicIC(type, code, name); | 745 UpdateMonomorphicIC(type, code, name); |
740 break; | 746 break; |
741 } | 747 } |
742 // Fall through. | 748 // Fall through. |
743 } | 749 } |
744 case POLYMORPHIC: | 750 case POLYMORPHIC: |
745 if (!target()->is_keyed_stub()) { | 751 if (!target()->is_keyed_stub()) { |
746 if (UpdatePolymorphicIC(type, name, code)) break; | 752 if (UpdatePolymorphicIC(type, name, code)) break; |
747 CopyICToMegamorphicCache(name); | 753 CopyICToMegamorphicCache(name); |
748 } | 754 } |
(...skipping 251 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1000 MapHandleList target_receiver_maps; | 1006 MapHandleList target_receiver_maps; |
1001 if (state() == UNINITIALIZED || state() == PREMONOMORPHIC) { | 1007 if (state() == UNINITIALIZED || state() == PREMONOMORPHIC) { |
1002 // Optimistically assume that ICs that haven't reached the MONOMORPHIC state | 1008 // Optimistically assume that ICs that haven't reached the MONOMORPHIC state |
1003 // yet will do so and stay there. | 1009 // yet will do so and stay there. |
1004 return isolate()->stub_cache()->ComputeKeyedLoadElement(receiver_map); | 1010 return isolate()->stub_cache()->ComputeKeyedLoadElement(receiver_map); |
1005 } | 1011 } |
1006 | 1012 |
1007 if (target().is_identical_to(string_stub())) { | 1013 if (target().is_identical_to(string_stub())) { |
1008 target_receiver_maps.Add(isolate()->factory()->string_map()); | 1014 target_receiver_maps.Add(isolate()->factory()->string_map()); |
1009 } else { | 1015 } else { |
1010 GetMapsFromTypes(&target_receiver_maps); | 1016 target()->FindAllMaps(&target_receiver_maps); |
1011 if (target_receiver_maps.length() == 0) { | 1017 if (target_receiver_maps.length() == 0) { |
1012 return isolate()->stub_cache()->ComputeKeyedLoadElement(receiver_map); | 1018 return isolate()->stub_cache()->ComputeKeyedLoadElement(receiver_map); |
1013 } | 1019 } |
1014 } | 1020 } |
1015 | 1021 |
1016 // The first time a receiver is seen that is a transitioned version of the | 1022 // The first time a receiver is seen that is a transitioned version of the |
1017 // previous monomorphic receiver type, assume the new ElementsKind is the | 1023 // previous monomorphic receiver type, assume the new ElementsKind is the |
1018 // monomorphic type. This benefits global arrays that only transition | 1024 // monomorphic type. This benefits global arrays that only transition |
1019 // once, and all call sites accessing them are faster if they remain | 1025 // once, and all call sites accessing them are faster if they remain |
1020 // monomorphic. If this optimistic assumption is not true, the IC will | 1026 // monomorphic. If this optimistic assumption is not true, the IC will |
(...skipping 383 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1404 Handle<Map> receiver_map(receiver->map(), isolate()); | 1410 Handle<Map> receiver_map(receiver->map(), isolate()); |
1405 if (state() == UNINITIALIZED || state() == PREMONOMORPHIC) { | 1411 if (state() == UNINITIALIZED || state() == PREMONOMORPHIC) { |
1406 // Optimistically assume that ICs that haven't reached the MONOMORPHIC state | 1412 // Optimistically assume that ICs that haven't reached the MONOMORPHIC state |
1407 // yet will do so and stay there. | 1413 // yet will do so and stay there. |
1408 Handle<Map> monomorphic_map = ComputeTransitionedMap(receiver, store_mode); | 1414 Handle<Map> monomorphic_map = ComputeTransitionedMap(receiver, store_mode); |
1409 store_mode = GetNonTransitioningStoreMode(store_mode); | 1415 store_mode = GetNonTransitioningStoreMode(store_mode); |
1410 return isolate()->stub_cache()->ComputeKeyedStoreElement( | 1416 return isolate()->stub_cache()->ComputeKeyedStoreElement( |
1411 monomorphic_map, strict_mode(), store_mode); | 1417 monomorphic_map, strict_mode(), store_mode); |
1412 } | 1418 } |
1413 | 1419 |
1420 MapHandleList target_receiver_maps; | |
1421 target()->FindAllMaps(&target_receiver_maps); | |
1422 if (target_receiver_maps.length() == 0) { | |
ulan
2014/02/25 10:18:30
Looks like the regression is caused by this chunk.
| |
1423 // In the case that there is a non-map-specific IC is installed (e.g. keyed | |
1424 // stores into properties in dictionary mode), then there will be not | |
1425 // receiver maps in the target. | |
1426 return generic_stub(); | |
1427 } | |
1428 | |
1414 // There are several special cases where an IC that is MONOMORPHIC can still | 1429 // There are several special cases where an IC that is MONOMORPHIC can still |
1415 // transition to a different GetNonTransitioningStoreMode IC that handles a | 1430 // transition to a different GetNonTransitioningStoreMode IC that handles a |
1416 // superset of the original IC. Handle those here if the receiver map hasn't | 1431 // superset of the original IC. Handle those here if the receiver map hasn't |
1417 // changed or it has transitioned to a more general kind. | 1432 // changed or it has transitioned to a more general kind. |
1418 KeyedAccessStoreMode old_store_mode = | 1433 KeyedAccessStoreMode old_store_mode = |
1419 KeyedStoreIC::GetKeyedAccessStoreMode(target()->extra_ic_state()); | 1434 KeyedStoreIC::GetKeyedAccessStoreMode(target()->extra_ic_state()); |
1435 Handle<Map> previous_receiver_map = target_receiver_maps.at(0); | |
1420 if (state() == MONOMORPHIC) { | 1436 if (state() == MONOMORPHIC) { |
1421 // If the "old" and "new" maps are in the same elements map family, stay | 1437 // If the "old" and "new" maps are in the same elements map family, stay |
1422 // MONOMORPHIC and use the map for the most generic ElementsKind. | 1438 // MONOMORPHIC and use the map for the most generic ElementsKind. |
1423 Handle<Map> transitioned_map = receiver_map; | 1439 Handle<Map> transitioned_receiver_map = receiver_map; |
1424 if (IsTransitionStoreMode(store_mode)) { | 1440 if (IsTransitionStoreMode(store_mode)) { |
1425 transitioned_map = ComputeTransitionedMap(receiver, store_mode); | 1441 transitioned_receiver_map = |
1442 ComputeTransitionedMap(receiver, store_mode); | |
1426 } | 1443 } |
1427 if (IsTransitionOfMonomorphicTarget(first_map(), *transitioned_map)) { | 1444 if (IsTransitionOfMonomorphicTarget( |
1445 MapToType<HeapType>(transitioned_receiver_map, isolate()))) { | |
1428 // Element family is the same, use the "worst" case map. | 1446 // Element family is the same, use the "worst" case map. |
1429 store_mode = GetNonTransitioningStoreMode(store_mode); | 1447 store_mode = GetNonTransitioningStoreMode(store_mode); |
1430 return isolate()->stub_cache()->ComputeKeyedStoreElement( | 1448 return isolate()->stub_cache()->ComputeKeyedStoreElement( |
1431 transitioned_map, strict_mode(), store_mode); | 1449 transitioned_receiver_map, strict_mode(), store_mode); |
1432 } else if (first_map() == receiver->map() && | 1450 } else if (*previous_receiver_map == receiver->map() && |
1433 old_store_mode == STANDARD_STORE && | 1451 old_store_mode == STANDARD_STORE && |
1434 (IsGrowStoreMode(store_mode) || | 1452 (IsGrowStoreMode(store_mode) || |
1435 store_mode == STORE_NO_TRANSITION_IGNORE_OUT_OF_BOUNDS || | 1453 store_mode == STORE_NO_TRANSITION_IGNORE_OUT_OF_BOUNDS || |
1436 store_mode == STORE_NO_TRANSITION_HANDLE_COW)) { | 1454 store_mode == STORE_NO_TRANSITION_HANDLE_COW)) { |
1437 // A "normal" IC that handles stores can switch to a version that can | 1455 // A "normal" IC that handles stores can switch to a version that can |
1438 // grow at the end of the array, handle OOB accesses or copy COW arrays | 1456 // grow at the end of the array, handle OOB accesses or copy COW arrays |
1439 // and still stay MONOMORPHIC. | 1457 // and still stay MONOMORPHIC. |
1440 return isolate()->stub_cache()->ComputeKeyedStoreElement( | 1458 return isolate()->stub_cache()->ComputeKeyedStoreElement( |
1441 receiver_map, strict_mode(), store_mode); | 1459 receiver_map, strict_mode(), store_mode); |
1442 } | 1460 } |
1443 } | 1461 } |
1444 | 1462 |
1445 ASSERT(state() != GENERIC); | 1463 ASSERT(state() != GENERIC); |
1446 | 1464 |
1447 MapHandleList target_receiver_maps; | |
1448 GetMapsFromTypes(&target_receiver_maps); | |
1449 | |
1450 bool map_added = | 1465 bool map_added = |
1451 AddOneReceiverMapIfMissing(&target_receiver_maps, receiver_map); | 1466 AddOneReceiverMapIfMissing(&target_receiver_maps, receiver_map); |
1452 | 1467 |
1453 if (IsTransitionStoreMode(store_mode)) { | 1468 if (IsTransitionStoreMode(store_mode)) { |
1454 Handle<Map> transitioned_receiver_map = | 1469 Handle<Map> transitioned_receiver_map = |
1455 ComputeTransitionedMap(receiver, store_mode); | 1470 ComputeTransitionedMap(receiver, store_mode); |
1456 map_added |= AddOneReceiverMapIfMissing(&target_receiver_maps, | 1471 map_added |= AddOneReceiverMapIfMissing(&target_receiver_maps, |
1457 transitioned_receiver_map); | 1472 transitioned_receiver_map); |
1458 } | 1473 } |
1459 | 1474 |
(...skipping 1236 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2696 // types must be supported as a result of the miss. | 2711 // types must be supported as a result of the miss. |
2697 bool already_monomorphic = stub.IsMonomorphic(); | 2712 bool already_monomorphic = stub.IsMonomorphic(); |
2698 | 2713 |
2699 stub.UpdateStatus(object); | 2714 stub.UpdateStatus(object); |
2700 | 2715 |
2701 NilValue nil = stub.GetNilValue(); | 2716 NilValue nil = stub.GetNilValue(); |
2702 | 2717 |
2703 // Find or create the specialized stub to support the new set of types. | 2718 // Find or create the specialized stub to support the new set of types. |
2704 Handle<Code> code; | 2719 Handle<Code> code; |
2705 if (stub.IsMonomorphic()) { | 2720 if (stub.IsMonomorphic()) { |
2706 Handle<Map> monomorphic_map(already_monomorphic && (first_map() != NULL) | 2721 Handle<Map> monomorphic_map(already_monomorphic |
2707 ? first_map() | 2722 ? target()->FindFirstMap() |
2708 : HeapObject::cast(*object)->map()); | 2723 : HeapObject::cast(*object)->map()); |
2709 code = isolate()->stub_cache()->ComputeCompareNil(monomorphic_map, stub); | 2724 code = isolate()->stub_cache()->ComputeCompareNil(monomorphic_map, stub); |
2710 } else { | 2725 } else { |
2711 code = stub.GetCode(isolate()); | 2726 code = stub.GetCode(isolate()); |
2712 } | 2727 } |
2713 set_target(*code); | 2728 set_target(*code); |
2714 return DoCompareNilSlow(nil, object); | 2729 return DoCompareNilSlow(nil, object); |
2715 } | 2730 } |
2716 | 2731 |
2717 | 2732 |
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2796 #undef ADDR | 2811 #undef ADDR |
2797 }; | 2812 }; |
2798 | 2813 |
2799 | 2814 |
2800 Address IC::AddressFromUtilityId(IC::UtilityId id) { | 2815 Address IC::AddressFromUtilityId(IC::UtilityId id) { |
2801 return IC_utilities[id]; | 2816 return IC_utilities[id]; |
2802 } | 2817 } |
2803 | 2818 |
2804 | 2819 |
2805 } } // namespace v8::internal | 2820 } } // namespace v8::internal |
OLD | NEW |