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

Side by Side Diff: src/compiler/js-native-context-specialization.cc

Issue 1417973006: [turbofan] Non-dictionary prototype maps are always stable. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Created 5 years, 1 month 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
« no previous file with comments | « src/compiler/js-native-context-specialization.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 2015 the V8 project authors. All rights reserved. 1 // Copyright 2015 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/compiler/js-native-context-specialization.h" 5 #include "src/compiler/js-native-context-specialization.h"
6 6
7 #include "src/accessors.h" 7 #include "src/accessors.h"
8 #include "src/compilation-dependencies.h" 8 #include "src/compilation-dependencies.h"
9 #include "src/compiler/access-builder.h" 9 #include "src/compiler/access-builder.h"
10 #include "src/compiler/js-graph.h" 10 #include "src/compiler/js-graph.h"
(...skipping 551 matching lines...) Expand 10 before | Expand all | Expand 10 after
562 (this_control_count == 1) 562 (this_control_count == 1)
563 ? this_controls.front() 563 ? this_controls.front()
564 : graph()->NewNode(common()->Merge(this_control_count), 564 : graph()->NewNode(common()->Merge(this_control_count),
565 this_control_count, &this_controls.front()); 565 this_control_count, &this_controls.front());
566 } 566 }
567 567
568 // Determine actual holder and perform prototype chain checks. 568 // Determine actual holder and perform prototype chain checks.
569 Handle<JSObject> holder; 569 Handle<JSObject> holder;
570 if (access_info.holder().ToHandle(&holder)) { 570 if (access_info.holder().ToHandle(&holder)) {
571 this_value = jsgraph()->Constant(holder); 571 this_value = jsgraph()->Constant(holder);
572 for (auto i = access_info.receiver_type()->Classes(); !i.Done(); 572 AssumePrototypesStable(receiver_type, holder);
573 i.Advance()) {
574 Handle<Map> map = i.Current();
575 PrototypeIterator j(map);
576 while (true) {
577 // Check that the {prototype} still has the same map. For stable
578 // maps, we can add a stability dependency on the prototype map;
579 // for everything else we need to perform a map check at runtime.
580 Handle<JSReceiver> prototype =
581 PrototypeIterator::GetCurrent<JSReceiver>(j);
582 if (prototype->map()->is_stable()) {
583 dependencies()->AssumeMapStable(
584 handle(prototype->map(), isolate()));
585 } else {
586 Node* prototype_map = this_effect = graph()->NewNode(
587 simplified()->LoadField(AccessBuilder::ForMap()),
588 jsgraph()->Constant(prototype), this_effect, this_control);
589 Node* check = graph()->NewNode(
590 simplified()->ReferenceEqual(Type::Internal()), prototype_map,
591 jsgraph()->Constant(handle(prototype->map(), isolate())));
592 Node* branch = graph()->NewNode(common()->Branch(BranchHint::kTrue),
593 check, this_control);
594 exit_controls.push_back(
595 graph()->NewNode(common()->IfFalse(), branch));
596 this_control = graph()->NewNode(common()->IfTrue(), branch);
597 }
598 // Stop once we get to the holder.
599 if (prototype.is_identical_to(holder)) break;
600 j.Advance();
601 }
602 }
603 } 573 }
604 574
605 // Generate the actual property access. 575 // Generate the actual property access.
606 if (access_info.IsDataConstant()) { 576 if (access_info.IsDataConstant()) {
607 this_value = jsgraph()->Constant(access_info.constant()); 577 this_value = jsgraph()->Constant(access_info.constant());
608 } else { 578 } else {
609 // TODO(bmeurer): This is sort of adhoc, and must be refactored into some 579 // TODO(bmeurer): This is sort of adhoc, and must be refactored into some
610 // common code once we also have support for stores. 580 // common code once we also have support for stores.
611 DCHECK(access_info.IsDataField()); 581 DCHECK(access_info.IsDataField());
612 FieldIndex const field_index = access_info.field_index(); 582 FieldIndex const field_index = access_info.field_index();
(...skipping 162 matching lines...) Expand 10 before | Expand all | Expand 10 after
775 this_control = 745 this_control =
776 (this_control_count == 1) 746 (this_control_count == 1)
777 ? this_controls.front() 747 ? this_controls.front()
778 : graph()->NewNode(common()->Merge(this_control_count), 748 : graph()->NewNode(common()->Merge(this_control_count),
779 this_control_count, &this_controls.front()); 749 this_control_count, &this_controls.front());
780 } 750 }
781 751
782 // Determine actual holder and perform prototype chain checks. 752 // Determine actual holder and perform prototype chain checks.
783 Handle<JSObject> holder; 753 Handle<JSObject> holder;
784 if (access_info.holder().ToHandle(&holder)) { 754 if (access_info.holder().ToHandle(&holder)) {
785 for (auto i = access_info.receiver_type()->Classes(); !i.Done(); 755 AssumePrototypesStable(receiver_type, holder);
786 i.Advance()) {
787 Handle<Map> map = i.Current();
788 PrototypeIterator j(map);
789 while (true) {
790 // Check that the {prototype} still has the same map. For stable
791 // maps, we can add a stability dependency on the prototype map;
792 // for everything else we need to perform a map check at runtime.
793 Handle<JSReceiver> prototype =
794 PrototypeIterator::GetCurrent<JSReceiver>(j);
795 if (prototype->map()->is_stable()) {
796 dependencies()->AssumeMapStable(
797 handle(prototype->map(), isolate()));
798 } else {
799 Node* prototype_map = this_effect = graph()->NewNode(
800 simplified()->LoadField(AccessBuilder::ForMap()),
801 jsgraph()->Constant(prototype), this_effect, this_control);
802 Node* check = graph()->NewNode(
803 simplified()->ReferenceEqual(Type::Internal()), prototype_map,
804 jsgraph()->Constant(handle(prototype->map(), isolate())));
805 Node* branch = graph()->NewNode(common()->Branch(BranchHint::kTrue),
806 check, this_control);
807 exit_controls.push_back(
808 graph()->NewNode(common()->IfFalse(), branch));
809 this_control = graph()->NewNode(common()->IfTrue(), branch);
810 }
811 // Stop once we get to the holder.
812 if (prototype.is_identical_to(holder)) break;
813 j.Advance();
814 }
815 }
816 } 756 }
817 757
Toon Verwaest 2015/10/23 13:45:40 What Object.prototype.x? Object.prototype has a nu
Benedikt Meurer 2015/10/23 13:56:26 NotFound case is not implemented.
818 // Generate the actual property access. 758 // Generate the actual property access.
819 if (access_info.IsDataConstant()) { 759 if (access_info.IsDataConstant()) {
820 Node* check = 760 Node* check =
821 graph()->NewNode(simplified()->ReferenceEqual(Type::Tagged()), value, 761 graph()->NewNode(simplified()->ReferenceEqual(Type::Tagged()), value,
822 jsgraph()->Constant(access_info.constant())); 762 jsgraph()->Constant(access_info.constant()));
823 Node* branch = graph()->NewNode(common()->Branch(BranchHint::kTrue), 763 Node* branch = graph()->NewNode(common()->Branch(BranchHint::kTrue),
824 check, this_control); 764 check, this_control);
825 exit_controls.push_back(graph()->NewNode(common()->IfFalse(), branch)); 765 exit_controls.push_back(graph()->NewNode(common()->IfFalse(), branch));
826 this_control = graph()->NewNode(common()->IfTrue(), branch); 766 this_control = graph()->NewNode(common()->IfTrue(), branch);
827 } else { 767 } else {
(...skipping 116 matching lines...) Expand 10 before | Expand all | Expand 10 after
944 } 884 }
945 Handle<Context> script_context = ScriptContextTable::GetContext( 885 Handle<Context> script_context = ScriptContextTable::GetContext(
946 script_context_table, lookup_result.context_index); 886 script_context_table, lookup_result.context_index);
947 result->context = script_context; 887 result->context = script_context;
948 result->immutable = IsImmutableVariableMode(lookup_result.mode); 888 result->immutable = IsImmutableVariableMode(lookup_result.mode);
949 result->index = lookup_result.slot_index; 889 result->index = lookup_result.slot_index;
950 return true; 890 return true;
951 } 891 }
952 892
953 893
894 void JSNativeContextSpecialization::AssumePrototypesStable(
895 Type* receiver_type, Handle<JSObject> holder) {
896 // Determine actual holder and perform prototype chain checks.
897 for (auto i = receiver_type->Classes(); !i.Done(); i.Advance()) {
898 Handle<Map> const map = i.Current();
899 for (PrototypeIterator j(map);; j.Advance()) {
Jarin 2015/10/23 13:09:34 Does not it make sense to dcheck that we are not a
900 // Check that the {prototype} still has the same map. All prototype
901 // maps are guaranteed to be stable, so it's sufficient to add a
902 // stability dependency here.
903 Handle<JSReceiver> const prototype =
904 PrototypeIterator::GetCurrent<JSReceiver>(j);
905 dependencies()->AssumeMapStable(handle(prototype->map(), isolate()));
906 // Stop once we get to the holder.
907 if (prototype.is_identical_to(holder)) break;
908 }
909 }
910 }
911
912
954 Graph* JSNativeContextSpecialization::graph() const { 913 Graph* JSNativeContextSpecialization::graph() const {
955 return jsgraph()->graph(); 914 return jsgraph()->graph();
956 } 915 }
957 916
958 917
959 Isolate* JSNativeContextSpecialization::isolate() const { 918 Isolate* JSNativeContextSpecialization::isolate() const {
960 return jsgraph()->isolate(); 919 return jsgraph()->isolate();
961 } 920 }
962 921
963 922
(...skipping 17 matching lines...) Expand all
981 } 940 }
982 941
983 942
984 SimplifiedOperatorBuilder* JSNativeContextSpecialization::simplified() const { 943 SimplifiedOperatorBuilder* JSNativeContextSpecialization::simplified() const {
985 return jsgraph()->simplified(); 944 return jsgraph()->simplified();
986 } 945 }
987 946
988 } // namespace compiler 947 } // namespace compiler
989 } // namespace internal 948 } // namespace internal
990 } // namespace v8 949 } // namespace v8
OLDNEW
« no previous file with comments | « src/compiler/js-native-context-specialization.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698