| 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...) Expand 10 before | Expand all | Expand 10 after  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...) Expand 10 before | Expand all | Expand 10 after  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...) Expand 10 before | Expand all | Expand 10 after  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...) Expand 10 before | Expand all | Expand 10 after  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 | 
|---|