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

Side by Side Diff: src/compiler/js-typed-lowering.cc

Issue 2609013002: [turbofan] Use InternalizedString feedback abstract/strict equality comparisons. (Closed)
Patch Set: Created 3 years, 11 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
« no previous file with comments | « src/compiler/js-operator.cc ('k') | src/compiler/opcodes.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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/compiler/js-typed-lowering.h" 5 #include "src/compiler/js-typed-lowering.h"
6 6
7 #include "src/ast/modules.h" 7 #include "src/ast/modules.h"
8 #include "src/builtins/builtins-utils.h" 8 #include "src/builtins/builtins-utils.h"
9 #include "src/code-factory.h" 9 #include "src/code-factory.h"
10 #include "src/compilation-dependencies.h" 10 #include "src/compilation-dependencies.h"
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after
63 return true; 63 return true;
64 case CompareOperationHint::kNumber: 64 case CompareOperationHint::kNumber:
65 *hint = NumberOperationHint::kNumber; 65 *hint = NumberOperationHint::kNumber;
66 return true; 66 return true;
67 case CompareOperationHint::kNumberOrOddball: 67 case CompareOperationHint::kNumberOrOddball:
68 *hint = NumberOperationHint::kNumberOrOddball; 68 *hint = NumberOperationHint::kNumberOrOddball;
69 return true; 69 return true;
70 case CompareOperationHint::kAny: 70 case CompareOperationHint::kAny:
71 case CompareOperationHint::kNone: 71 case CompareOperationHint::kNone:
72 case CompareOperationHint::kString: 72 case CompareOperationHint::kString:
73 case CompareOperationHint::kInternalizedString:
73 break; 74 break;
74 } 75 }
75 } 76 }
76 return false; 77 return false;
77 } 78 }
78 79
80 bool IsInternalizedStringCompareOperation() {
81 if (lowering_->flags() & JSTypedLowering::kDeoptimizationEnabled) {
82 DCHECK_EQ(1, node_->op()->EffectOutputCount());
83 return (CompareOperationHintOf(node_->op()) ==
84 CompareOperationHint::kInternalizedString) &&
85 BothInputsMaybe(Type::InternalizedString());
86 }
87 return false;
88 }
89
79 // Check if a string addition will definitely result in creating a ConsString, 90 // Check if a string addition will definitely result in creating a ConsString,
80 // i.e. if the combined length of the resulting string exceeds the ConsString 91 // i.e. if the combined length of the resulting string exceeds the ConsString
81 // minimum length. 92 // minimum length.
82 bool ShouldCreateConsString() { 93 bool ShouldCreateConsString() {
83 DCHECK_EQ(IrOpcode::kJSAdd, node_->opcode()); 94 DCHECK_EQ(IrOpcode::kJSAdd, node_->opcode());
84 if (BothInputsAre(Type::String()) || 95 if (BothInputsAre(Type::String()) ||
85 ((lowering_->flags() & JSTypedLowering::kDeoptimizationEnabled) && 96 ((lowering_->flags() & JSTypedLowering::kDeoptimizationEnabled) &&
86 BinaryOperationHintOf(node_->op()) == BinaryOperationHint::kString)) { 97 BinaryOperationHintOf(node_->op()) == BinaryOperationHint::kString)) {
87 HeapObjectBinopMatcher m(node_); 98 HeapObjectBinopMatcher m(node_);
88 if (m.right().HasValue() && m.right().Value()->IsString()) { 99 if (m.right().HasValue() && m.right().Value()->IsString()) {
89 Handle<String> right_string = Handle<String>::cast(m.right().Value()); 100 Handle<String> right_string = Handle<String>::cast(m.right().Value());
90 if (right_string->length() >= ConsString::kMinLength) return true; 101 if (right_string->length() >= ConsString::kMinLength) return true;
91 } 102 }
92 if (m.left().HasValue() && m.left().Value()->IsString()) { 103 if (m.left().HasValue() && m.left().Value()->IsString()) {
93 Handle<String> left_string = Handle<String>::cast(m.left().Value()); 104 Handle<String> left_string = Handle<String>::cast(m.left().Value());
94 if (left_string->length() >= ConsString::kMinLength) { 105 if (left_string->length() >= ConsString::kMinLength) {
95 // The invariant for ConsString requires the left hand side to be 106 // The invariant for ConsString requires the left hand side to be
96 // a sequential or external string if the right hand side is the 107 // a sequential or external string if the right hand side is the
97 // empty string. Since we don't know anything about the right hand 108 // empty string. Since we don't know anything about the right hand
98 // side here, we must ensure that the left hand side satisfy the 109 // side here, we must ensure that the left hand side satisfy the
99 // constraints independent of the right hand side. 110 // constraints independent of the right hand side.
100 return left_string->IsSeqString() || left_string->IsExternalString(); 111 return left_string->IsSeqString() || left_string->IsExternalString();
101 } 112 }
102 } 113 }
103 } 114 }
104 return false; 115 return false;
105 } 116 }
106 117
118 // Checks that both inputs are InternalizedString, and if we don't know
119 // statically that one side is already an InternalizedString, insert a
120 // CheckInternalizedString node.
121 void CheckInputsToInternalizedString() {
122 if (!left_type()->Is(Type::UniqueName())) {
123 Node* left_input = graph()->NewNode(
124 simplified()->CheckInternalizedString(), left(), effect(), control());
125 node_->ReplaceInput(0, left_input);
126 update_effect(left_input);
127 }
128 if (!right_type()->Is(Type::UniqueName())) {
129 Node* right_input =
130 graph()->NewNode(simplified()->CheckInternalizedString(), right(),
131 effect(), control());
132 node_->ReplaceInput(1, right_input);
133 update_effect(right_input);
134 }
135 }
136
107 void ConvertInputsToNumber() { 137 void ConvertInputsToNumber() {
108 // To convert the inputs to numbers, we have to provide frame states 138 // To convert the inputs to numbers, we have to provide frame states
109 // for lazy bailouts in the ToNumber conversions. 139 // for lazy bailouts in the ToNumber conversions.
110 // We use a little hack here: we take the frame state before the binary 140 // We use a little hack here: we take the frame state before the binary
111 // operation and use it to construct the frame states for the conversion 141 // operation and use it to construct the frame states for the conversion
112 // so that after the deoptimization, the binary operation IC gets 142 // so that after the deoptimization, the binary operation IC gets
113 // already converted values from full code. This way we are sure that we 143 // already converted values from full code. This way we are sure that we
114 // will not re-do any of the side effects. 144 // will not re-do any of the side effects.
115 145
116 Node* left_input = nullptr; 146 Node* left_input = nullptr;
(...skipping 193 matching lines...) Expand 10 before | Expand all | Expand 10 after
310 } 340 }
311 341
312 bool LeftInputIs(Type* t) { return left_type()->Is(t); } 342 bool LeftInputIs(Type* t) { return left_type()->Is(t); }
313 343
314 bool RightInputIs(Type* t) { return right_type()->Is(t); } 344 bool RightInputIs(Type* t) { return right_type()->Is(t); }
315 345
316 bool OneInputIs(Type* t) { return LeftInputIs(t) || RightInputIs(t); } 346 bool OneInputIs(Type* t) { return LeftInputIs(t) || RightInputIs(t); }
317 347
318 bool BothInputsAre(Type* t) { return LeftInputIs(t) && RightInputIs(t); } 348 bool BothInputsAre(Type* t) { return LeftInputIs(t) && RightInputIs(t); }
319 349
350 bool BothInputsMaybe(Type* t) {
351 return left_type()->Maybe(t) && right_type()->Maybe(t);
352 }
353
320 bool OneInputCannotBe(Type* t) { 354 bool OneInputCannotBe(Type* t) {
321 return !left_type()->Maybe(t) || !right_type()->Maybe(t); 355 return !left_type()->Maybe(t) || !right_type()->Maybe(t);
322 } 356 }
323 357
324 bool NeitherInputCanBe(Type* t) { 358 bool NeitherInputCanBe(Type* t) {
325 return !left_type()->Maybe(t) && !right_type()->Maybe(t); 359 return !left_type()->Maybe(t) && !right_type()->Maybe(t);
326 } 360 }
327 361
328 Node* effect() { return NodeProperties::GetEffectInput(node_); } 362 Node* effect() { return NodeProperties::GetEffectInput(node_); }
329 Node* control() { return NodeProperties::GetControlInput(node_); } 363 Node* control() { return NodeProperties::GetControlInput(node_); }
(...skipping 514 matching lines...) Expand 10 before | Expand all | Expand 10 after
844 } 878 }
845 return NoChange(); 879 return NoChange();
846 } 880 }
847 881
848 Reduction JSTypedLowering::ReduceJSEqual(Node* node, bool invert) { 882 Reduction JSTypedLowering::ReduceJSEqual(Node* node, bool invert) {
849 Reduction const reduction = ReduceJSEqualTypeOf(node, invert); 883 Reduction const reduction = ReduceJSEqualTypeOf(node, invert);
850 if (reduction.Changed()) return reduction; 884 if (reduction.Changed()) return reduction;
851 885
852 JSBinopReduction r(this, node); 886 JSBinopReduction r(this, node);
853 887
888 if (r.BothInputsAre(Type::UniqueName())) {
889 return r.ChangeToPureOperator(simplified()->ReferenceEqual(), invert);
890 }
891 if (r.IsInternalizedStringCompareOperation()) {
892 r.CheckInputsToInternalizedString();
893 return r.ChangeToPureOperator(simplified()->ReferenceEqual(), invert);
894 }
854 if (r.BothInputsAre(Type::String())) { 895 if (r.BothInputsAre(Type::String())) {
855 return r.ChangeToPureOperator(simplified()->StringEqual(), invert); 896 return r.ChangeToPureOperator(simplified()->StringEqual(), invert);
856 } 897 }
857 if (r.BothInputsAre(Type::Boolean())) { 898 if (r.BothInputsAre(Type::Boolean())) {
858 return r.ChangeToPureOperator(simplified()->ReferenceEqual(), invert); 899 return r.ChangeToPureOperator(simplified()->ReferenceEqual(), invert);
859 } 900 }
860 if (r.BothInputsAre(Type::Receiver())) { 901 if (r.BothInputsAre(Type::Receiver())) {
861 return r.ChangeToPureOperator(simplified()->ReferenceEqual(), invert); 902 return r.ChangeToPureOperator(simplified()->ReferenceEqual(), invert);
862 } 903 }
863 if (r.OneInputIs(Type::Undetectable())) { 904 if (r.OneInputIs(Type::Undetectable())) {
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after
927 } 968 }
928 if (r.OneInputIs(Type::Object())) { 969 if (r.OneInputIs(Type::Object())) {
929 return r.ChangeToPureOperator(simplified()->ReferenceEqual(), invert); 970 return r.ChangeToPureOperator(simplified()->ReferenceEqual(), invert);
930 } 971 }
931 if (r.OneInputIs(Type::Receiver())) { 972 if (r.OneInputIs(Type::Receiver())) {
932 return r.ChangeToPureOperator(simplified()->ReferenceEqual(), invert); 973 return r.ChangeToPureOperator(simplified()->ReferenceEqual(), invert);
933 } 974 }
934 if (r.BothInputsAre(Type::Unique())) { 975 if (r.BothInputsAre(Type::Unique())) {
935 return r.ChangeToPureOperator(simplified()->ReferenceEqual(), invert); 976 return r.ChangeToPureOperator(simplified()->ReferenceEqual(), invert);
936 } 977 }
978 if (r.IsInternalizedStringCompareOperation()) {
979 r.CheckInputsToInternalizedString();
980 return r.ChangeToPureOperator(simplified()->ReferenceEqual(), invert);
981 }
937 if (r.BothInputsAre(Type::String())) { 982 if (r.BothInputsAre(Type::String())) {
938 return r.ChangeToPureOperator(simplified()->StringEqual(), invert); 983 return r.ChangeToPureOperator(simplified()->StringEqual(), invert);
939 } 984 }
940 985
941 NumberOperationHint hint; 986 NumberOperationHint hint;
942 if (r.BothInputsAre(Type::Signed32()) || 987 if (r.BothInputsAre(Type::Signed32()) ||
943 r.BothInputsAre(Type::Unsigned32())) { 988 r.BothInputsAre(Type::Unsigned32())) {
944 return r.ChangeToPureOperator(simplified()->NumberEqual(), invert); 989 return r.ChangeToPureOperator(simplified()->NumberEqual(), invert);
945 } else if (r.GetCompareNumberOperationHint(&hint)) { 990 } else if (r.GetCompareNumberOperationHint(&hint)) {
946 return r.ChangeToSpeculativeOperator( 991 return r.ChangeToSpeculativeOperator(
(...skipping 1368 matching lines...) Expand 10 before | Expand all | Expand 10 after
2315 } 2360 }
2316 2361
2317 2362
2318 CompilationDependencies* JSTypedLowering::dependencies() const { 2363 CompilationDependencies* JSTypedLowering::dependencies() const {
2319 return dependencies_; 2364 return dependencies_;
2320 } 2365 }
2321 2366
2322 } // namespace compiler 2367 } // namespace compiler
2323 } // namespace internal 2368 } // namespace internal
2324 } // namespace v8 2369 } // namespace v8
OLDNEW
« no previous file with comments | « src/compiler/js-operator.cc ('k') | src/compiler/opcodes.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698