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

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

Issue 2874423003: [csa] Add ToLength and ToString variants with inlined fast checks (Closed)
Patch Set: ToString Created 3 years, 7 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/builtins/builtins-regexp-gen.cc ('k') | src/code-stub-assembler.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 2017 the V8 project authors. All rights reserved. 1 // Copyright 2017 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-regexp-gen.h" 5 #include "src/builtins/builtins-regexp-gen.h"
6 #include "src/builtins/builtins-utils-gen.h" 6 #include "src/builtins/builtins-utils-gen.h"
7 #include "src/builtins/builtins.h" 7 #include "src/builtins/builtins.h"
8 #include "src/code-factory.h" 8 #include "src/code-factory.h"
9 #include "src/code-stub-assembler.h" 9 #include "src/code-stub-assembler.h"
10 #include "src/objects.h" 10 #include "src/objects.h"
(...skipping 714 matching lines...) Expand 10 before | Expand all | Expand 10 after
725 725
726 // Check that {receiver} is coercible to Object and convert it to a String. 726 // Check that {receiver} is coercible to Object and convert it to a String.
727 receiver = ToThisString(context, receiver, "String.prototype.concat"); 727 receiver = ToThisString(context, receiver, "String.prototype.concat");
728 728
729 // Concatenate all the arguments passed to this builtin. 729 // Concatenate all the arguments passed to this builtin.
730 VARIABLE(var_result, MachineRepresentation::kTagged); 730 VARIABLE(var_result, MachineRepresentation::kTagged);
731 var_result.Bind(receiver); 731 var_result.Bind(receiver);
732 arguments.ForEach( 732 arguments.ForEach(
733 CodeStubAssembler::VariableList({&var_result}, zone()), 733 CodeStubAssembler::VariableList({&var_result}, zone()),
734 [this, context, &var_result](Node* arg) { 734 [this, context, &var_result](Node* arg) {
735 arg = CallStub(CodeFactory::ToString(isolate()), context, arg); 735 arg = ToString_Inline(context, arg);
736 var_result.Bind(CallStub(CodeFactory::StringAdd(isolate()), context, 736 var_result.Bind(CallStub(CodeFactory::StringAdd(isolate()), context,
737 var_result.value(), arg)); 737 var_result.value(), arg));
738 }); 738 });
739 arguments.PopAndReturn(var_result.value()); 739 arguments.PopAndReturn(var_result.value());
740 } 740 }
741 741
742 void StringBuiltinsAssembler::StringIndexOf( 742 void StringBuiltinsAssembler::StringIndexOf(
743 Node* const subject_string, Node* const subject_instance_type, 743 Node* const subject_string, Node* const subject_instance_type,
744 Node* const search_string, Node* const search_instance_type, 744 Node* const search_string, Node* const search_instance_type,
745 Node* const position, std::function<void(Node*)> f_return) { 745 Node* const position, std::function<void(Node*)> f_return) {
(...skipping 396 matching lines...) Expand 10 before | Expand all | Expand 10 after
1142 1142
1143 Node* const smi_zero = SmiConstant(0); 1143 Node* const smi_zero = SmiConstant(0);
1144 1144
1145 RequireObjectCoercible(context, receiver, "String.prototype.replace"); 1145 RequireObjectCoercible(context, receiver, "String.prototype.replace");
1146 1146
1147 // Redirect to replacer method if {search[@@replace]} is not undefined. 1147 // Redirect to replacer method if {search[@@replace]} is not undefined.
1148 1148
1149 MaybeCallFunctionAtSymbol( 1149 MaybeCallFunctionAtSymbol(
1150 context, search, isolate()->factory()->replace_symbol(), 1150 context, search, isolate()->factory()->replace_symbol(),
1151 [=]() { 1151 [=]() {
1152 Callable tostring_callable = CodeFactory::ToString(isolate()); 1152 Node* const subject_string = ToString_Inline(context, receiver);
1153 Node* const subject_string =
1154 CallStub(tostring_callable, context, receiver);
1155 1153
1156 Callable replace_callable = CodeFactory::RegExpReplace(isolate()); 1154 Callable replace_callable = CodeFactory::RegExpReplace(isolate());
1157 return CallStub(replace_callable, context, search, subject_string, 1155 return CallStub(replace_callable, context, search, subject_string,
1158 replace); 1156 replace);
1159 }, 1157 },
1160 [=](Node* fn) { 1158 [=](Node* fn) {
1161 Callable call_callable = CodeFactory::Call(isolate()); 1159 Callable call_callable = CodeFactory::Call(isolate());
1162 return CallJS(call_callable, context, fn, search, receiver, replace); 1160 return CallJS(call_callable, context, fn, search, receiver, replace);
1163 }); 1161 });
1164 1162
1165 // Convert {receiver} and {search} to strings. 1163 // Convert {receiver} and {search} to strings.
1166 1164
1167 Callable tostring_callable = CodeFactory::ToString(isolate());
1168 Callable indexof_callable = CodeFactory::StringIndexOf(isolate()); 1165 Callable indexof_callable = CodeFactory::StringIndexOf(isolate());
1169 1166
1170 Node* const subject_string = CallStub(tostring_callable, context, receiver); 1167 Node* const subject_string = ToString_Inline(context, receiver);
1171 Node* const search_string = CallStub(tostring_callable, context, search); 1168 Node* const search_string = ToString_Inline(context, search);
1172 1169
1173 Node* const subject_length = LoadStringLength(subject_string); 1170 Node* const subject_length = LoadStringLength(subject_string);
1174 Node* const search_length = LoadStringLength(search_string); 1171 Node* const search_length = LoadStringLength(search_string);
1175 1172
1176 // Fast-path single-char {search}, long cons {receiver}, and simple string 1173 // Fast-path single-char {search}, long cons {receiver}, and simple string
1177 // {replace}. 1174 // {replace}.
1178 { 1175 {
1179 Label next(this); 1176 Label next(this);
1180 1177
1181 GotoIfNot(SmiEqual(search_length, SmiConstant(1)), &next); 1178 GotoIfNot(SmiEqual(search_length, SmiConstant(1)), &next);
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
1215 1212
1216 // The spec requires to perform ToString(replace) if the {replace} is not 1213 // The spec requires to perform ToString(replace) if the {replace} is not
1217 // callable even if we are going to exit here. 1214 // callable even if we are going to exit here.
1218 // Since ToString() being applied to Smi does not have side effects for 1215 // Since ToString() being applied to Smi does not have side effects for
1219 // numbers we can skip it. 1216 // numbers we can skip it.
1220 GotoIf(TaggedIsSmi(replace), &return_subject); 1217 GotoIf(TaggedIsSmi(replace), &return_subject);
1221 GotoIf(IsCallableMap(LoadMap(replace)), &return_subject); 1218 GotoIf(IsCallableMap(LoadMap(replace)), &return_subject);
1222 1219
1223 // TODO(jgruber): Could introduce ToStringSideeffectsStub which only 1220 // TODO(jgruber): Could introduce ToStringSideeffectsStub which only
1224 // performs observable parts of ToString. 1221 // performs observable parts of ToString.
1225 CallStub(tostring_callable, context, replace); 1222 ToString_Inline(context, replace);
1226 Goto(&return_subject); 1223 Goto(&return_subject);
1227 1224
1228 BIND(&return_subject); 1225 BIND(&return_subject);
1229 Return(subject_string); 1226 Return(subject_string);
1230 1227
1231 BIND(&next); 1228 BIND(&next);
1232 } 1229 }
1233 1230
1234 Node* const match_end_index = SmiAdd(match_start_index, search_length); 1231 Node* const match_end_index = SmiAdd(match_start_index, search_length);
1235 1232
(...skipping 22 matching lines...) Expand all
1258 GotoIf(TaggedIsSmi(replace), &if_notcallablereplace); 1255 GotoIf(TaggedIsSmi(replace), &if_notcallablereplace);
1259 Branch(IsCallableMap(LoadMap(replace)), &if_iscallablereplace, 1256 Branch(IsCallableMap(LoadMap(replace)), &if_iscallablereplace,
1260 &if_notcallablereplace); 1257 &if_notcallablereplace);
1261 1258
1262 BIND(&if_iscallablereplace); 1259 BIND(&if_iscallablereplace);
1263 { 1260 {
1264 Callable call_callable = CodeFactory::Call(isolate()); 1261 Callable call_callable = CodeFactory::Call(isolate());
1265 Node* const replacement = 1262 Node* const replacement =
1266 CallJS(call_callable, context, replace, UndefinedConstant(), 1263 CallJS(call_callable, context, replace, UndefinedConstant(),
1267 search_string, match_start_index, subject_string); 1264 search_string, match_start_index, subject_string);
1268 Node* const replacement_string = 1265 Node* const replacement_string = ToString_Inline(context, replacement);
1269 CallStub(tostring_callable, context, replacement);
1270 var_result.Bind(CallStub(stringadd_callable, context, var_result.value(), 1266 var_result.Bind(CallStub(stringadd_callable, context, var_result.value(),
1271 replacement_string)); 1267 replacement_string));
1272 Goto(&out); 1268 Goto(&out);
1273 } 1269 }
1274 1270
1275 BIND(&if_notcallablereplace); 1271 BIND(&if_notcallablereplace);
1276 { 1272 {
1277 Node* const replace_string = CallStub(tostring_callable, context, replace); 1273 Node* const replace_string = ToString_Inline(context, replace);
1278 Node* const replacement = 1274 Node* const replacement =
1279 GetSubstitution(context, subject_string, match_start_index, 1275 GetSubstitution(context, subject_string, match_start_index,
1280 match_end_index, replace_string); 1276 match_end_index, replace_string);
1281 var_result.Bind( 1277 var_result.Bind(
1282 CallStub(stringadd_callable, context, var_result.value(), replacement)); 1278 CallStub(stringadd_callable, context, var_result.value(), replacement));
1283 Goto(&out); 1279 Goto(&out);
1284 } 1280 }
1285 1281
1286 BIND(&out); 1282 BIND(&out);
1287 { 1283 {
(...skipping 16 matching lines...) Expand all
1304 1300
1305 Node* const smi_zero = SmiConstant(0); 1301 Node* const smi_zero = SmiConstant(0);
1306 1302
1307 RequireObjectCoercible(context, receiver, "String.prototype.split"); 1303 RequireObjectCoercible(context, receiver, "String.prototype.split");
1308 1304
1309 // Redirect to splitter method if {separator[@@split]} is not undefined. 1305 // Redirect to splitter method if {separator[@@split]} is not undefined.
1310 1306
1311 MaybeCallFunctionAtSymbol( 1307 MaybeCallFunctionAtSymbol(
1312 context, separator, isolate()->factory()->split_symbol(), 1308 context, separator, isolate()->factory()->split_symbol(),
1313 [=]() { 1309 [=]() {
1314 Callable tostring_callable = CodeFactory::ToString(isolate()); 1310 Node* const subject_string = ToString_Inline(context, receiver);
1315 Node* const subject_string =
1316 CallStub(tostring_callable, context, receiver);
1317 1311
1318 Callable split_callable = CodeFactory::RegExpSplit(isolate()); 1312 Callable split_callable = CodeFactory::RegExpSplit(isolate());
1319 return CallStub(split_callable, context, separator, subject_string, 1313 return CallStub(split_callable, context, separator, subject_string,
1320 limit); 1314 limit);
1321 }, 1315 },
1322 [=](Node* fn) { 1316 [=](Node* fn) {
1323 Callable call_callable = CodeFactory::Call(isolate()); 1317 Callable call_callable = CodeFactory::Call(isolate());
1324 return CallJS(call_callable, context, fn, separator, receiver, limit); 1318 return CallJS(call_callable, context, fn, separator, receiver, limit);
1325 }); 1319 });
1326 1320
1327 // String and integer conversions. 1321 // String and integer conversions.
1328 // TODO(jgruber): The old implementation used Uint32Max instead of SmiMax - 1322 // TODO(jgruber): The old implementation used Uint32Max instead of SmiMax -
1329 // but AFAIK there should not be a difference since arrays are capped at Smi 1323 // but AFAIK there should not be a difference since arrays are capped at Smi
1330 // lengths. 1324 // lengths.
1331 1325
1332 Callable tostring_callable = CodeFactory::ToString(isolate()); 1326 Node* const subject_string = ToString_Inline(context, receiver);
1333 Node* const subject_string = CallStub(tostring_callable, context, receiver);
1334 Node* const limit_number = 1327 Node* const limit_number =
1335 Select(IsUndefined(limit), [=]() { return SmiConstant(Smi::kMaxValue); }, 1328 Select(IsUndefined(limit), [=]() { return SmiConstant(Smi::kMaxValue); },
1336 [=]() { return ToUint32(context, limit); }, 1329 [=]() { return ToUint32(context, limit); },
1337 MachineRepresentation::kTagged); 1330 MachineRepresentation::kTagged);
1338 Node* const separator_string = 1331 Node* const separator_string = ToString_Inline(context, separator);
1339 CallStub(tostring_callable, context, separator);
1340 1332
1341 // Shortcut for {limit} == 0. 1333 // Shortcut for {limit} == 0.
1342 { 1334 {
1343 Label next(this); 1335 Label next(this);
1344 GotoIfNot(SmiEqual(limit_number, smi_zero), &next); 1336 GotoIfNot(SmiEqual(limit_number, smi_zero), &next);
1345 1337
1346 const ElementsKind kind = FAST_ELEMENTS; 1338 const ElementsKind kind = FAST_ELEMENTS;
1347 Node* const native_context = LoadNativeContext(context); 1339 Node* const native_context = LoadNativeContext(context);
1348 Node* const array_map = LoadJSArrayElementsMap(kind, native_context); 1340 Node* const array_map = LoadJSArrayElementsMap(kind, native_context);
1349 1341
(...skipping 435 matching lines...) Expand 10 before | Expand all | Expand 10 after
1785 CallRuntime(Runtime::kThrowIncompatibleMethodReceiver, context, 1777 CallRuntime(Runtime::kThrowIncompatibleMethodReceiver, context,
1786 HeapConstant(factory()->NewStringFromAsciiChecked( 1778 HeapConstant(factory()->NewStringFromAsciiChecked(
1787 "String Iterator.prototype.next", TENURED)), 1779 "String Iterator.prototype.next", TENURED)),
1788 iterator); 1780 iterator);
1789 Unreachable(); 1781 Unreachable();
1790 } 1782 }
1791 } 1783 }
1792 1784
1793 } // namespace internal 1785 } // namespace internal
1794 } // namespace v8 1786 } // namespace v8
OLDNEW
« no previous file with comments | « src/builtins/builtins-regexp-gen.cc ('k') | src/code-stub-assembler.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698