Commit 93d1508d authored by Shiyu Zhang's avatar Shiyu Zhang Committed by Commit Bot

[builtins] Reimplement ToString as CSA to optimize performance

Currently, if input types are not string or number, ToString builtin
will fall into runtime and a loop of ToPrimitive and type-checks is
done in runtime, which is slow.

This CL reimplements ToString to add support for that ToPrimitive and
type-checks loop in CSA instead of runtime to improve performance. This
will benefit Array.prototype.toString/join a lot when the array elements
are objects.

This Cl improves the performance of Speedometer2.0 EmberJS-Debug case
by ~14% on Atom.

Change-Id: I27c2669097be1e542e30119cdffcf79c0d16a0eb
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/1498698
Commit-Queue: Shiyu Zhang <shiyu.zhang@intel.com>
Reviewed-by: 's avatarBenedikt Meurer <bmeurer@chromium.org>
Reviewed-by: 's avatarJakob Gruber <jgruber@chromium.org>
Cr-Commit-Position: refs/heads/master@{#60144}
parent ac8e98e4
...@@ -7752,37 +7752,64 @@ TNode<Number> CodeStubAssembler::ToUint32(SloppyTNode<Context> context, ...@@ -7752,37 +7752,64 @@ TNode<Number> CodeStubAssembler::ToUint32(SloppyTNode<Context> context,
TNode<String> CodeStubAssembler::ToString(SloppyTNode<Context> context, TNode<String> CodeStubAssembler::ToString(SloppyTNode<Context> context,
SloppyTNode<Object> input) { SloppyTNode<Object> input) {
Label is_number(this); TVARIABLE(Object, result, input);
Label runtime(this, Label::kDeferred), done(this); Label loop(this, &result), done(this);
VARIABLE(result, MachineRepresentation::kTagged); Goto(&loop);
GotoIf(TaggedIsSmi(input), &is_number); BIND(&loop);
{
TNode<Map> input_map = LoadMap(CAST(input)); // Load the current {input} value.
TNode<Int32T> input_instance_type = LoadMapInstanceType(input_map); TNode<Object> input = result.value();
result.Bind(input); // Dispatch based on the type of the {input.}
Label if_inputisnumber(this), if_inputisoddball(this),
if_inputissymbol(this), if_inputisreceiver(this, Label::kDeferred),
runtime(this, Label::kDeferred);
GotoIf(TaggedIsSmi(input), &if_inputisnumber);
TNode<Int32T> input_instance_type = LoadInstanceType(CAST(input));
GotoIf(IsStringInstanceType(input_instance_type), &done); GotoIf(IsStringInstanceType(input_instance_type), &done);
GotoIf(IsJSReceiverInstanceType(input_instance_type), &if_inputisreceiver);
GotoIf(IsHeapNumberInstanceType(input_instance_type), &if_inputisnumber);
GotoIf(IsOddballInstanceType(input_instance_type), &if_inputisoddball);
Branch(IsSymbolInstanceType(input_instance_type), &if_inputissymbol,
&runtime);
Label not_heap_number(this); BIND(&if_inputisnumber);
Branch(IsHeapNumberMap(input_map), &is_number, &not_heap_number); {
// Convert the Number {input} to a String.
BIND(&is_number);
TNode<Number> number_input = CAST(input); TNode<Number> number_input = CAST(input);
result.Bind(NumberToString(number_input)); result = NumberToString(number_input);
Goto(&done); Goto(&done);
}
BIND(&not_heap_number); BIND(&if_inputisoddball);
{ {
GotoIfNot(InstanceTypeEqual(input_instance_type, ODDBALL_TYPE), &runtime); // Just return the {input}'s string representation.
result.Bind(LoadObjectField(CAST(input), Oddball::kToStringOffset)); result = LoadObjectField(CAST(input), Oddball::kToStringOffset);
Goto(&done); Goto(&done);
} }
BIND(&if_inputissymbol);
{
// Throw a type error when {input} is a Symbol.
ThrowTypeError(context, MessageTemplate::kSymbolToString);
}
BIND(&if_inputisreceiver);
{
// Convert the JSReceiver {input} to a primitive first,
// and then run the loop again with the new {input},
// which is then a primitive value.
result = CallBuiltin(Builtins::kNonPrimitiveToPrimitive_String, context,
input);
Goto(&loop);
}
BIND(&runtime); BIND(&runtime);
{ {
result.Bind(CallRuntime(Runtime::kToString, context, input)); result = CallRuntime(Runtime::kToString, context, input);
Goto(&done); Goto(&done);
} }
}
BIND(&done); BIND(&done);
return CAST(result.value()); return CAST(result.value());
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment