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

Side by Side Diff: src/ic.cc

Issue 171683007: Unify monomorphic and polymorphic cases in IC::PatchCache. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Rebase and add IsTransitionOfMonomorphicTarget from r19537 Created 6 years, 9 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 | Annotate | Revision Log
« no previous file with comments | « src/ic.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 606 matching lines...) Expand 10 before | Expand all | Expand 10 after
617 } 617 }
618 618
619 619
620 bool IC::UpdatePolymorphicIC(Handle<HeapType> type, 620 bool IC::UpdatePolymorphicIC(Handle<HeapType> type,
621 Handle<String> name, 621 Handle<String> name,
622 Handle<Code> code) { 622 Handle<Code> code) {
623 if (!code->is_handler()) return false; 623 if (!code->is_handler()) return false;
624 TypeHandleList types; 624 TypeHandleList types;
625 CodeHandleList handlers; 625 CodeHandleList handlers;
626 626
627 int number_of_valid_types;
628 int handler_to_overwrite = -1;
629
630 target()->FindAllTypes(&types); 627 target()->FindAllTypes(&types);
631 int number_of_types = types.length(); 628 int number_of_types = types.length();
632 number_of_valid_types = number_of_types; 629 int deprecated_types = 0;
630 int handler_to_overwrite = -1;
633 631
634 for (int i = 0; i < number_of_types; i++) { 632 for (int i = 0; i < number_of_types; i++) {
635 Handle<HeapType> current_type = types.at(i); 633 Handle<HeapType> current_type = types.at(i);
636 // Filter out deprecated maps to ensure their instances get migrated.
637 if (current_type->IsClass() && current_type->AsClass()->is_deprecated()) { 634 if (current_type->IsClass() && current_type->AsClass()->is_deprecated()) {
638 number_of_valid_types--; 635 // Filter out deprecated maps to ensure their instances get migrated.
639 // If the receiver type is already in the polymorphic IC, this indicates 636 ++deprecated_types;
640 // there was a prototoype chain failure. In that case, just overwrite the
641 // handler.
642 } else if (type->IsCurrently(current_type)) { 637 } else if (type->IsCurrently(current_type)) {
643 ASSERT(handler_to_overwrite == -1); 638 // If the receiver type is already in the polymorphic IC, this indicates
644 number_of_valid_types--; 639 // there was a prototoype chain failure. In that case, just overwrite the
640 // handler.
641 handler_to_overwrite = i;
642 } else if (handler_to_overwrite == -1 &&
643 current_type->IsClass() &&
644 type->IsClass() &&
645 IsTransitionOfMonomorphicTarget(*current_type->AsClass(),
646 *type->AsClass())) {
645 handler_to_overwrite = i; 647 handler_to_overwrite = i;
646 } 648 }
647 } 649 }
648 650
651 int number_of_valid_types =
652 number_of_types - deprecated_types - (handler_to_overwrite != -1);
653
649 if (number_of_valid_types >= 4) return false; 654 if (number_of_valid_types >= 4) return false;
650 if (number_of_types == 0) return false; 655 if (number_of_types == 0) return false;
651 if (!target()->FindHandlers(&handlers, types.length())) return false; 656 if (!target()->FindHandlers(&handlers, types.length())) return false;
652 657
653 number_of_valid_types++; 658 number_of_valid_types++;
654 if (handler_to_overwrite >= 0) { 659 if (handler_to_overwrite >= 0) {
655 handlers.Set(handler_to_overwrite, code); 660 handlers.Set(handler_to_overwrite, code);
661 if (!type->IsCurrently(types.at(handler_to_overwrite))) {
662 types.Set(handler_to_overwrite, type);
663 }
656 } else { 664 } else {
657 types.Add(type); 665 types.Add(type);
658 handlers.Add(code); 666 handlers.Add(code);
659 } 667 }
660 668
661 Handle<Code> ic = isolate()->stub_cache()->ComputePolymorphicIC( 669 Handle<Code> ic = isolate()->stub_cache()->ComputePolymorphicIC(
662 kind(), &types, &handlers, number_of_valid_types, name, extra_ic_state()); 670 kind(), &types, &handlers, number_of_valid_types, name, extra_ic_state());
663 set_target(*ic); 671 set_target(*ic);
664 return true; 672 return true;
665 } 673 }
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after
720 TypeHandleList types; 728 TypeHandleList types;
721 CodeHandleList handlers; 729 CodeHandleList handlers;
722 target()->FindAllTypes(&types); 730 target()->FindAllTypes(&types);
723 if (!target()->FindHandlers(&handlers, types.length())) return; 731 if (!target()->FindHandlers(&handlers, types.length())) return;
724 for (int i = 0; i < types.length(); i++) { 732 for (int i = 0; i < types.length(); i++) {
725 UpdateMegamorphicCache(*types.at(i), *name, *handlers.at(i)); 733 UpdateMegamorphicCache(*types.at(i), *name, *handlers.at(i));
726 } 734 }
727 } 735 }
728 736
729 737
730 bool IC::IsTransitionOfMonomorphicTarget(Handle<HeapType> type) { 738 bool IC::IsTransitionOfMonomorphicTarget(Map* source_map, Map* target_map) {
731 if (!type->IsClass()) return false; 739 if (source_map == NULL) return true;
732 Map* receiver_map = *type->AsClass(); 740 if (target_map == NULL) return false;
733 Map* current_map = target()->FindFirstMap(); 741 ElementsKind target_elements_kind = target_map->elements_kind();
734 ElementsKind receiver_elements_kind = receiver_map->elements_kind();
735 bool more_general_transition = 742 bool more_general_transition =
736 IsMoreGeneralElementsKindTransition( 743 IsMoreGeneralElementsKindTransition(
737 current_map->elements_kind(), receiver_elements_kind); 744 source_map->elements_kind(), target_elements_kind);
738 Map* transitioned_map = more_general_transition 745 Map* transitioned_map = more_general_transition
739 ? current_map->LookupElementsTransitionMap(receiver_elements_kind) 746 ? source_map->LookupElementsTransitionMap(target_elements_kind)
740 : NULL; 747 : NULL;
741 748
742 return transitioned_map == receiver_map; 749 return transitioned_map == target_map;
743 } 750 }
744 751
745 752
746 void IC::PatchCache(Handle<HeapType> type, 753 void IC::PatchCache(Handle<HeapType> type,
747 Handle<String> name, 754 Handle<String> name,
748 Handle<Code> code) { 755 Handle<Code> code) {
749 switch (state()) { 756 switch (state()) {
750 case UNINITIALIZED: 757 case UNINITIALIZED:
751 case PREMONOMORPHIC: 758 case PREMONOMORPHIC:
752 case MONOMORPHIC_PROTOTYPE_FAILURE: 759 case MONOMORPHIC_PROTOTYPE_FAILURE:
753 UpdateMonomorphicIC(type, code, name); 760 UpdateMonomorphicIC(type, code, name);
754 break; 761 break;
755 case MONOMORPHIC: { 762 case MONOMORPHIC: // Fall through.
756 // For now, call stubs are allowed to rewrite to the same stub. This
757 // happens e.g., when the field does not contain a function.
758 ASSERT(!target().is_identical_to(code));
759 Code* old_handler = target()->FindFirstHandler();
760 if (old_handler == *code && IsTransitionOfMonomorphicTarget(type)) {
761 UpdateMonomorphicIC(type, code, name);
762 break;
763 }
764 // Fall through.
765 }
766 case POLYMORPHIC: 763 case POLYMORPHIC:
767 if (!target()->is_keyed_stub()) { 764 if (!target()->is_keyed_stub()) {
768 if (UpdatePolymorphicIC(type, name, code)) break; 765 if (UpdatePolymorphicIC(type, name, code)) break;
769 CopyICToMegamorphicCache(name); 766 CopyICToMegamorphicCache(name);
770 } 767 }
771 set_target(*megamorphic_stub()); 768 set_target(*megamorphic_stub());
772 // Fall through. 769 // Fall through.
773 case MEGAMORPHIC: 770 case MEGAMORPHIC:
774 UpdateMegamorphicCache(*type, *name, *code); 771 UpdateMegamorphicCache(*type, *name, *code);
775 break; 772 break;
(...skipping 674 matching lines...) Expand 10 before | Expand all | Expand 10 after
1450 KeyedAccessStoreMode old_store_mode = 1447 KeyedAccessStoreMode old_store_mode =
1451 KeyedStoreIC::GetKeyedAccessStoreMode(target()->extra_ic_state()); 1448 KeyedStoreIC::GetKeyedAccessStoreMode(target()->extra_ic_state());
1452 Handle<Map> previous_receiver_map = target_receiver_maps.at(0); 1449 Handle<Map> previous_receiver_map = target_receiver_maps.at(0);
1453 if (state() == MONOMORPHIC) { 1450 if (state() == MONOMORPHIC) {
1454 Handle<Map> transitioned_receiver_map = receiver_map; 1451 Handle<Map> transitioned_receiver_map = receiver_map;
1455 if (IsTransitionStoreMode(store_mode)) { 1452 if (IsTransitionStoreMode(store_mode)) {
1456 transitioned_receiver_map = ComputeTransitionedMap(receiver, store_mode); 1453 transitioned_receiver_map = ComputeTransitionedMap(receiver, store_mode);
1457 } 1454 }
1458 if ((receiver_map.is_identical_to(previous_receiver_map) && 1455 if ((receiver_map.is_identical_to(previous_receiver_map) &&
1459 IsTransitionStoreMode(store_mode)) || 1456 IsTransitionStoreMode(store_mode)) ||
1460 IsTransitionOfMonomorphicTarget( 1457 IsTransitionOfMonomorphicTarget(*previous_receiver_map,
1461 MapToType<HeapType>(transitioned_receiver_map, isolate()))) { 1458 *transitioned_receiver_map)) {
1462 // If the "old" and "new" maps are in the same elements map family, or 1459 // If the "old" and "new" maps are in the same elements map family, or
1463 // if they at least come from the same origin for a transitioning store, 1460 // if they at least come from the same origin for a transitioning store,
1464 // stay MONOMORPHIC and use the map for the most generic ElementsKind. 1461 // stay MONOMORPHIC and use the map for the most generic ElementsKind.
1465 store_mode = GetNonTransitioningStoreMode(store_mode); 1462 store_mode = GetNonTransitioningStoreMode(store_mode);
1466 return isolate()->stub_cache()->ComputeKeyedStoreElement( 1463 return isolate()->stub_cache()->ComputeKeyedStoreElement(
1467 transitioned_receiver_map, strict_mode(), store_mode); 1464 transitioned_receiver_map, strict_mode(), store_mode);
1468 } else if (*previous_receiver_map == receiver->map() && 1465 } else if (*previous_receiver_map == receiver->map() &&
1469 old_store_mode == STANDARD_STORE && 1466 old_store_mode == STANDARD_STORE &&
1470 (store_mode == STORE_AND_GROW_NO_TRANSITION || 1467 (store_mode == STORE_AND_GROW_NO_TRANSITION ||
1471 store_mode == STORE_NO_TRANSITION_IGNORE_OUT_OF_BOUNDS || 1468 store_mode == STORE_NO_TRANSITION_IGNORE_OUT_OF_BOUNDS ||
(...skipping 1365 matching lines...) Expand 10 before | Expand all | Expand 10 after
2837 #undef ADDR 2834 #undef ADDR
2838 }; 2835 };
2839 2836
2840 2837
2841 Address IC::AddressFromUtilityId(IC::UtilityId id) { 2838 Address IC::AddressFromUtilityId(IC::UtilityId id) {
2842 return IC_utilities[id]; 2839 return IC_utilities[id];
2843 } 2840 }
2844 2841
2845 2842
2846 } } // namespace v8::internal 2843 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/ic.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698