OLD | NEW |
1 // Copyright 2016 the V8 project authors. All rights reserved. | 1 // Copyright 2016 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/builtins/builtins-utils.h" | 5 #include "src/builtins/builtins-utils.h" |
6 #include "src/builtins/builtins.h" | 6 #include "src/builtins/builtins.h" |
7 #include "src/code-factory.h" | 7 #include "src/code-factory.h" |
8 #include "src/code-stub-assembler.h" | 8 #include "src/code-stub-assembler.h" |
9 #include "src/regexp/regexp-utils.h" | 9 #include "src/regexp/regexp-utils.h" |
10 | 10 |
(...skipping 59 matching lines...) Loading... |
70 // if (lhs->length() != rhs->length()) return false; | 70 // if (lhs->length() != rhs->length()) return false; |
71 // if (lhs->IsInternalizedString() && rhs->IsInternalizedString()) { | 71 // if (lhs->IsInternalizedString() && rhs->IsInternalizedString()) { |
72 // return false; | 72 // return false; |
73 // } | 73 // } |
74 // if (lhs->IsSeqOneByteString() && rhs->IsSeqOneByteString()) { | 74 // if (lhs->IsSeqOneByteString() && rhs->IsSeqOneByteString()) { |
75 // for (i = 0; i != lhs->length(); ++i) { | 75 // for (i = 0; i != lhs->length(); ++i) { |
76 // if (lhs[i] != rhs[i]) return false; | 76 // if (lhs[i] != rhs[i]) return false; |
77 // } | 77 // } |
78 // return true; | 78 // return true; |
79 // } | 79 // } |
| 80 // if (lhs and/or rhs are indirect strings) { |
| 81 // unwrap them and restart from the beginning; |
| 82 // } |
80 // return %StringEqual(lhs, rhs); | 83 // return %StringEqual(lhs, rhs); |
81 | 84 |
82 Node* lhs = Parameter(0); | 85 Variable var_left(this, MachineRepresentation::kTagged); |
83 Node* rhs = Parameter(1); | 86 Variable var_right(this, MachineRepresentation::kTagged); |
| 87 var_left.Bind(Parameter(0)); |
| 88 var_right.Bind(Parameter(1)); |
84 Node* context = Parameter(2); | 89 Node* context = Parameter(2); |
85 | 90 |
86 Label if_equal(this), if_notequal(this); | 91 Variable* input_vars[2] = {&var_left, &var_right}; |
| 92 Label if_equal(this), if_notequal(this), restart(this, 2, input_vars); |
| 93 Goto(&restart); |
| 94 Bind(&restart); |
| 95 Node* lhs = var_left.value(); |
| 96 Node* rhs = var_right.value(); |
87 | 97 |
88 // Fast check to see if {lhs} and {rhs} refer to the same String object. | 98 // Fast check to see if {lhs} and {rhs} refer to the same String object. |
89 GotoIf(WordEqual(lhs, rhs), &if_equal); | 99 GotoIf(WordEqual(lhs, rhs), &if_equal); |
90 | 100 |
91 // Load the length of {lhs} and {rhs}. | 101 // Load the length of {lhs} and {rhs}. |
92 Node* lhs_length = LoadStringLength(lhs); | 102 Node* lhs_length = LoadStringLength(lhs); |
93 Node* rhs_length = LoadStringLength(rhs); | 103 Node* rhs_length = LoadStringLength(rhs); |
94 | 104 |
95 // Strings with different lengths cannot be equal. | 105 // Strings with different lengths cannot be equal. |
96 GotoIf(WordNotEqual(lhs_length, rhs_length), &if_notequal); | 106 GotoIf(WordNotEqual(lhs_length, rhs_length), &if_notequal); |
(...skipping 55 matching lines...) Loading... |
152 Node* lhs_value = Load(MachineType::Uint8(), lhs, offset); | 162 Node* lhs_value = Load(MachineType::Uint8(), lhs, offset); |
153 Node* rhs_value = Load(MachineType::Uint8(), rhs, offset); | 163 Node* rhs_value = Load(MachineType::Uint8(), rhs, offset); |
154 | 164 |
155 // Check if the characters match. | 165 // Check if the characters match. |
156 GotoIf(Word32NotEqual(lhs_value, rhs_value), &if_notequal); | 166 GotoIf(Word32NotEqual(lhs_value, rhs_value), &if_notequal); |
157 | 167 |
158 // Advance to next character. | 168 // Advance to next character. |
159 var_offset.Bind(IntPtrAdd(offset, IntPtrConstant(1))); | 169 var_offset.Bind(IntPtrAdd(offset, IntPtrConstant(1))); |
160 Goto(&loop); | 170 Goto(&loop); |
161 } | 171 } |
162 } | 172 } |
163 | 173 |
164 Bind(&if_notbothonebyteseqstrings); | 174 Bind(&if_notbothonebyteseqstrings); |
165 { | 175 { |
166 // TODO(bmeurer): Add fast case support for flattened cons strings; | 176 // Try to unwrap indirect strings, restart the above attempt on success. |
167 // also add support for two byte string equality checks. | 177 MaybeDerefIndirectStrings(&var_left, lhs_instance_type, &var_right, |
168 Runtime::FunctionId function_id = | 178 rhs_instance_type, &restart); |
169 (mode == ResultMode::kDontNegateResult) | 179 // TODO(bmeurer): Add support for two byte string equality checks. |
170 ? Runtime::kStringEqual | |
171 : Runtime::kStringNotEqual; | |
172 TailCallRuntime(function_id, context, lhs, rhs); | |
173 } | |
174 | 180 |
175 Bind(&if_equal); | 181 Runtime::FunctionId function_id = (mode == ResultMode::kDontNegateResult) |
176 Return(BooleanConstant(mode == ResultMode::kDontNegateResult)); | 182 ? Runtime::kStringEqual |
| 183 : Runtime::kStringNotEqual; |
| 184 TailCallRuntime(function_id, context, lhs, rhs); |
| 185 } |
177 | 186 |
178 Bind(&if_notequal); | 187 Bind(&if_equal); |
179 Return(BooleanConstant(mode == ResultMode::kNegateResult)); | 188 Return(BooleanConstant(mode == ResultMode::kDontNegateResult)); |
| 189 |
| 190 Bind(&if_notequal); |
| 191 Return(BooleanConstant(mode == ResultMode::kNegateResult)); |
180 } | 192 } |
181 | 193 |
182 void StringBuiltinsAssembler::GenerateStringRelationalComparison( | 194 void StringBuiltinsAssembler::GenerateStringRelationalComparison( |
183 RelationalComparisonMode mode) { | 195 RelationalComparisonMode mode) { |
184 Node* lhs = Parameter(0); | 196 Variable var_left(this, MachineRepresentation::kTagged); |
185 Node* rhs = Parameter(1); | 197 Variable var_right(this, MachineRepresentation::kTagged); |
| 198 var_left.Bind(Parameter(0)); |
| 199 var_right.Bind(Parameter(1)); |
186 Node* context = Parameter(2); | 200 Node* context = Parameter(2); |
187 | 201 |
| 202 Variable* input_vars[2] = {&var_left, &var_right}; |
188 Label if_less(this), if_equal(this), if_greater(this); | 203 Label if_less(this), if_equal(this), if_greater(this); |
| 204 Label restart(this, 2, input_vars); |
| 205 Goto(&restart); |
| 206 Bind(&restart); |
189 | 207 |
| 208 Node* lhs = var_left.value(); |
| 209 Node* rhs = var_right.value(); |
190 // Fast check to see if {lhs} and {rhs} refer to the same String object. | 210 // Fast check to see if {lhs} and {rhs} refer to the same String object. |
191 GotoIf(WordEqual(lhs, rhs), &if_equal); | 211 GotoIf(WordEqual(lhs, rhs), &if_equal); |
192 | 212 |
193 // Load instance types of {lhs} and {rhs}. | 213 // Load instance types of {lhs} and {rhs}. |
194 Node* lhs_instance_type = LoadInstanceType(lhs); | 214 Node* lhs_instance_type = LoadInstanceType(lhs); |
195 Node* rhs_instance_type = LoadInstanceType(rhs); | 215 Node* rhs_instance_type = LoadInstanceType(rhs); |
196 | 216 |
197 // Combine the instance types into a single 16-bit value, so we can check | 217 // Combine the instance types into a single 16-bit value, so we can check |
198 // both of them at once. | 218 // both of them at once. |
199 Node* both_instance_types = Word32Or( | 219 Node* both_instance_types = Word32Or( |
(...skipping 67 matching lines...) Loading... |
267 // All characters up to the min length are equal, decide based on | 287 // All characters up to the min length are equal, decide based on |
268 // string length. | 288 // string length. |
269 GotoIf(SmiEqual(lhs_length, rhs_length), &if_equal); | 289 GotoIf(SmiEqual(lhs_length, rhs_length), &if_equal); |
270 BranchIfSmiLessThan(lhs_length, rhs_length, &if_less, &if_greater); | 290 BranchIfSmiLessThan(lhs_length, rhs_length, &if_less, &if_greater); |
271 } | 291 } |
272 } | 292 } |
273 } | 293 } |
274 | 294 |
275 Bind(&if_notbothonebyteseqstrings); | 295 Bind(&if_notbothonebyteseqstrings); |
276 { | 296 { |
277 // TODO(bmeurer): Add fast case support for flattened cons strings; | 297 // Try to unwrap indirect strings, restart the above attempt on success. |
278 // also add support for two byte string relational comparisons. | 298 MaybeDerefIndirectStrings(&var_left, lhs_instance_type, &var_right, |
| 299 rhs_instance_type, &restart); |
| 300 // TODO(bmeurer): Add support for two byte string relational comparisons. |
279 switch (mode) { | 301 switch (mode) { |
280 case RelationalComparisonMode::kLessThan: | 302 case RelationalComparisonMode::kLessThan: |
281 TailCallRuntime(Runtime::kStringLessThan, context, lhs, rhs); | 303 TailCallRuntime(Runtime::kStringLessThan, context, lhs, rhs); |
282 break; | 304 break; |
283 case RelationalComparisonMode::kLessThanOrEqual: | 305 case RelationalComparisonMode::kLessThanOrEqual: |
284 TailCallRuntime(Runtime::kStringLessThanOrEqual, context, lhs, rhs); | 306 TailCallRuntime(Runtime::kStringLessThanOrEqual, context, lhs, rhs); |
285 break; | 307 break; |
286 case RelationalComparisonMode::kGreaterThan: | 308 case RelationalComparisonMode::kGreaterThan: |
287 TailCallRuntime(Runtime::kStringGreaterThan, context, lhs, rhs); | 309 TailCallRuntime(Runtime::kStringGreaterThan, context, lhs, rhs); |
288 break; | 310 break; |
(...skipping 1153 matching lines...) Loading... |
1442 CallRuntime(Runtime::kThrowIncompatibleMethodReceiver, context, | 1464 CallRuntime(Runtime::kThrowIncompatibleMethodReceiver, context, |
1443 HeapConstant(factory()->NewStringFromAsciiChecked( | 1465 HeapConstant(factory()->NewStringFromAsciiChecked( |
1444 "String Iterator.prototype.next", TENURED)), | 1466 "String Iterator.prototype.next", TENURED)), |
1445 iterator); | 1467 iterator); |
1446 Return(result); // Never reached. | 1468 Return(result); // Never reached. |
1447 } | 1469 } |
1448 } | 1470 } |
1449 | 1471 |
1450 } // namespace internal | 1472 } // namespace internal |
1451 } // namespace v8 | 1473 } // namespace v8 |
OLD | NEW |