Chromium Code Reviews

Side by Side Diff: src/builtins/builtins-string.cc

Issue 2549773002: Internalize strings in-place (Closed)
Patch Set: fix performance Created 3 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments.
Jump to:
View unified diff |
OLDNEW
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...)
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...)
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...)
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...)
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
OLDNEW

Powered by Google App Engine