Commit 6ee0c87b authored by Ross McIlroy's avatar Ross McIlroy Committed by Commit Bot

Reland "[Interpreter] Ensure Test*Handler don't allocate a frame for fast-path."

This is a reland of d6121fd1

Original change's description:
> [Interpreter] Ensure Test*Handler don't allocate a frame for fast-path.
>
> Avoids allocating a frame for the fast-path in TestEqual, TestEqualStrict and
> TestLess/GreaterThan bytecode handlers. Also changes how feedback is tracked
> to try and avoid needing to keep feedback to "combine" with if it's unecessary
> which reduces the liveranges of the registers holding this data.
>
> This reduces the time needed for a tight loop in Ignition (e.g.,
> while (i < 1000000000) ++i;) from 12.8s to 10.8s.
>
> BUG=v8:9133
>
> Change-Id: I686b9da89541d15d233635db3276de3dad2fa282
> Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/1570020
> Reviewed-by: Jakob Gruber <jgruber@chromium.org>
> Commit-Queue: Ross McIlroy <rmcilroy@chromium.org>
> Cr-Commit-Position: refs/heads/master@{#60906}

TBR=jgruber@chromium.org

Bug: v8:9133
Change-Id: Ie9940d029d412986e6713438630565a98fe3c51c
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/1582401Reviewed-by: 's avatarRoss McIlroy <rmcilroy@chromium.org>
Commit-Queue: Ross McIlroy <rmcilroy@chromium.org>
Cr-Commit-Position: refs/heads/master@{#60989}
parent 20196642
......@@ -11315,7 +11315,8 @@ Node* CodeStubAssembler::RelationalComparison(Operation op, Node* left,
Node* right_map = LoadMap(right);
Label if_left_heapnumber(this), if_left_bigint(this, Label::kDeferred),
if_left_string(this), if_left_other(this, Label::kDeferred);
if_left_string(this, Label::kDeferred),
if_left_other(this, Label::kDeferred);
GotoIf(IsHeapNumberMap(left_map), &if_left_heapnumber);
Node* left_instance_type = LoadMapInstanceType(left_map);
GotoIf(IsBigIntInstanceType(left_instance_type), &if_left_bigint);
......@@ -11803,7 +11804,8 @@ Node* CodeStubAssembler::Equal(Node* left, Node* right, Node* context,
{
GotoIf(TaggedIsSmi(right), &use_symmetry);
Label if_left_symbol(this), if_left_number(this), if_left_string(this),
Label if_left_symbol(this), if_left_number(this),
if_left_string(this, Label::kDeferred),
if_left_bigint(this, Label::kDeferred), if_left_oddball(this),
if_left_receiver(this);
......@@ -12139,9 +12141,12 @@ Node* CodeStubAssembler::StrictEqual(Node* lhs, Node* rhs,
// }
// }
Label if_equal(this), if_notequal(this), end(this);
Label if_equal(this), if_notequal(this), if_not_equivalent_types(this),
end(this);
VARIABLE(result, MachineRepresentation::kTagged);
OverwriteFeedback(var_type_feedback, CompareOperationFeedback::kNone);
// Check if {lhs} and {rhs} refer to the same object.
Label if_same(this), if_notsame(this);
Branch(WordEqual(lhs, rhs), &if_same, &if_notsame);
......@@ -12150,9 +12155,6 @@ Node* CodeStubAssembler::StrictEqual(Node* lhs, Node* rhs,
{
// The {lhs} and {rhs} reference the exact same value, yet we need special
// treatment for HeapNumber, as NaN is not equal to NaN.
if (var_type_feedback != nullptr) {
var_type_feedback->Bind(SmiConstant(CompareOperationFeedback::kNone));
}
GenerateEqual_Same(lhs, &if_equal, &if_notequal, var_type_feedback);
}
......@@ -12161,10 +12163,6 @@ Node* CodeStubAssembler::StrictEqual(Node* lhs, Node* rhs,
// The {lhs} and {rhs} reference different objects, yet for Smi, HeapNumber,
// BigInt and String they can still be considered equal.
if (var_type_feedback != nullptr) {
var_type_feedback->Bind(SmiConstant(CompareOperationFeedback::kAny));
}
// Check if {lhs} is a Smi or a HeapObject.
Label if_lhsissmi(this), if_lhsisnotsmi(this);
Branch(TaggedIsSmi(lhs), &if_lhsissmi, &if_lhsisnotsmi);
......@@ -12190,10 +12188,7 @@ Node* CodeStubAssembler::StrictEqual(Node* lhs, Node* rhs,
Node* lhs_value = LoadHeapNumberValue(lhs);
Node* rhs_value = SmiToFloat64(rhs);
if (var_type_feedback != nullptr) {
var_type_feedback->Bind(
SmiConstant(CompareOperationFeedback::kNumber));
}
CombineFeedback(var_type_feedback, CompareOperationFeedback::kNumber);
// Perform a floating point comparison of {lhs} and {rhs}.
Branch(Float64Equal(lhs_value, rhs_value), &if_equal, &if_notequal);
......@@ -12214,17 +12209,15 @@ Node* CodeStubAssembler::StrictEqual(Node* lhs, Node* rhs,
Node* lhs_value = LoadHeapNumberValue(lhs);
Node* rhs_value = LoadHeapNumberValue(rhs);
if (var_type_feedback != nullptr) {
var_type_feedback->Bind(
SmiConstant(CompareOperationFeedback::kNumber));
}
CombineFeedback(var_type_feedback,
CompareOperationFeedback::kNumber);
// Perform a floating point comparison of {lhs} and {rhs}.
Branch(Float64Equal(lhs_value, rhs_value), &if_equal, &if_notequal);
}
BIND(&if_rhsisnotnumber);
Goto(&if_notequal);
Goto(&if_not_equivalent_types);
}
}
......@@ -12235,7 +12228,7 @@ Node* CodeStubAssembler::StrictEqual(Node* lhs, Node* rhs,
Branch(TaggedIsSmi(rhs), &if_rhsissmi, &if_rhsisnotsmi);
BIND(&if_rhsissmi);
Goto(&if_notequal);
Goto(&if_not_equivalent_types);
BIND(&if_rhsisnotsmi);
{
......@@ -12243,7 +12236,7 @@ Node* CodeStubAssembler::StrictEqual(Node* lhs, Node* rhs,
Node* lhs_instance_type = LoadMapInstanceType(lhs_map);
// Check if {lhs} is a String.
Label if_lhsisstring(this), if_lhsisnotstring(this);
Label if_lhsisstring(this, Label::kDeferred), if_lhsisnotstring(this);
Branch(IsStringInstanceType(lhs_instance_type), &if_lhsisstring,
&if_lhsisnotstring);
......@@ -12273,92 +12266,94 @@ Node* CodeStubAssembler::StrictEqual(Node* lhs, Node* rhs,
}
BIND(&if_rhsisnotstring);
Goto(&if_notequal);
Goto(&if_not_equivalent_types);
}
BIND(&if_lhsisnotstring);
// Check if {lhs} is a BigInt.
Label if_lhsisbigint(this), if_lhsisnotbigint(this);
Branch(IsBigIntInstanceType(lhs_instance_type), &if_lhsisbigint,
&if_lhsisnotbigint);
BIND(&if_lhsisbigint);
{
// Load the instance type of {rhs}.
Node* rhs_instance_type = LoadInstanceType(rhs);
// Check if {rhs} is also a BigInt.
Label if_rhsisbigint(this, Label::kDeferred),
if_rhsisnotbigint(this);
Branch(IsBigIntInstanceType(rhs_instance_type), &if_rhsisbigint,
&if_rhsisnotbigint);
// Check if {lhs} is a BigInt.
Label if_lhsisbigint(this), if_lhsisnotbigint(this);
Branch(IsBigIntInstanceType(lhs_instance_type), &if_lhsisbigint,
&if_lhsisnotbigint);
BIND(&if_rhsisbigint);
BIND(&if_lhsisbigint);
{
if (var_type_feedback != nullptr) {
var_type_feedback->Bind(
SmiConstant(CompareOperationFeedback::kBigInt));
// Load the instance type of {rhs}.
Node* rhs_instance_type = LoadInstanceType(rhs);
// Check if {rhs} is also a BigInt.
Label if_rhsisbigint(this, Label::kDeferred),
if_rhsisnotbigint(this);
Branch(IsBigIntInstanceType(rhs_instance_type), &if_rhsisbigint,
&if_rhsisnotbigint);
BIND(&if_rhsisbigint);
{
CombineFeedback(var_type_feedback,
CompareOperationFeedback::kBigInt);
result.Bind(CallRuntime(Runtime::kBigIntEqualToBigInt,
NoContextConstant(), lhs, rhs));
Goto(&end);
}
result.Bind(CallRuntime(Runtime::kBigIntEqualToBigInt,
NoContextConstant(), lhs, rhs));
Goto(&end);
}
BIND(&if_rhsisnotbigint);
Goto(&if_notequal);
}
BIND(&if_lhsisnotbigint);
if (var_type_feedback != nullptr) {
// Load the instance type of {rhs}.
Node* rhs_map = LoadMap(rhs);
Node* rhs_instance_type = LoadMapInstanceType(rhs_map);
Label if_lhsissymbol(this), if_lhsisreceiver(this),
if_lhsisoddball(this);
GotoIf(IsJSReceiverInstanceType(lhs_instance_type),
&if_lhsisreceiver);
GotoIf(IsBooleanMap(lhs_map), &if_notequal);
GotoIf(IsOddballInstanceType(lhs_instance_type), &if_lhsisoddball);
Branch(IsSymbolInstanceType(lhs_instance_type), &if_lhsissymbol,
&if_notequal);
BIND(&if_lhsisreceiver);
{
GotoIf(IsBooleanMap(rhs_map), &if_notequal);
var_type_feedback->Bind(
SmiConstant(CompareOperationFeedback::kReceiver));
GotoIf(IsJSReceiverInstanceType(rhs_instance_type), &if_notequal);
var_type_feedback->Bind(SmiConstant(
CompareOperationFeedback::kReceiverOrNullOrUndefined));
GotoIf(IsOddballInstanceType(rhs_instance_type), &if_notequal);
var_type_feedback->Bind(
SmiConstant(CompareOperationFeedback::kAny));
Goto(&if_notequal);
BIND(&if_rhsisnotbigint);
Goto(&if_not_equivalent_types);
}
BIND(&if_lhsisoddball);
{
STATIC_ASSERT(LAST_PRIMITIVE_TYPE == ODDBALL_TYPE);
GotoIf(IsBooleanMap(rhs_map), &if_notequal);
GotoIf(
Int32LessThan(rhs_instance_type, Int32Constant(ODDBALL_TYPE)),
&if_notequal);
var_type_feedback->Bind(SmiConstant(
CompareOperationFeedback::kReceiverOrNullOrUndefined));
Goto(&if_notequal);
}
BIND(&if_lhsisnotbigint);
if (var_type_feedback != nullptr) {
// Load the instance type of {rhs}.
Node* rhs_map = LoadMap(rhs);
Node* rhs_instance_type = LoadMapInstanceType(rhs_map);
Label if_lhsissymbol(this), if_lhsisreceiver(this),
if_lhsisoddball(this);
GotoIf(IsJSReceiverInstanceType(lhs_instance_type),
&if_lhsisreceiver);
GotoIf(IsBooleanMap(lhs_map), &if_not_equivalent_types);
GotoIf(IsOddballInstanceType(lhs_instance_type),
&if_lhsisoddball);
Branch(IsSymbolInstanceType(lhs_instance_type), &if_lhsissymbol,
&if_not_equivalent_types);
BIND(&if_lhsisreceiver);
{
GotoIf(IsBooleanMap(rhs_map), &if_not_equivalent_types);
OverwriteFeedback(var_type_feedback,
CompareOperationFeedback::kReceiver);
GotoIf(IsJSReceiverInstanceType(rhs_instance_type),
&if_notequal);
OverwriteFeedback(
var_type_feedback,
CompareOperationFeedback::kReceiverOrNullOrUndefined);
GotoIf(IsOddballInstanceType(rhs_instance_type), &if_notequal);
Goto(&if_not_equivalent_types);
}
BIND(&if_lhsissymbol);
{
GotoIfNot(IsSymbolInstanceType(rhs_instance_type), &if_notequal);
var_type_feedback->Bind(
SmiConstant(CompareOperationFeedback::kSymbol));
BIND(&if_lhsisoddball);
{
STATIC_ASSERT(LAST_PRIMITIVE_TYPE == ODDBALL_TYPE);
GotoIf(IsBooleanMap(rhs_map), &if_not_equivalent_types);
GotoIf(Int32LessThan(rhs_instance_type,
Int32Constant(ODDBALL_TYPE)),
&if_not_equivalent_types);
OverwriteFeedback(
var_type_feedback,
CompareOperationFeedback::kReceiverOrNullOrUndefined);
Goto(&if_notequal);
}
BIND(&if_lhsissymbol);
{
GotoIfNot(IsSymbolInstanceType(rhs_instance_type),
&if_not_equivalent_types);
OverwriteFeedback(var_type_feedback,
CompareOperationFeedback::kSymbol);
Goto(&if_notequal);
}
} else {
Goto(&if_notequal);
}
} else {
Goto(&if_notequal);
}
}
}
......@@ -12375,10 +12370,8 @@ Node* CodeStubAssembler::StrictEqual(Node* lhs, Node* rhs,
Branch(TaggedIsSmi(rhs), &if_rhsissmi, &if_rhsisnotsmi);
BIND(&if_rhsissmi);
if (var_type_feedback != nullptr) {
var_type_feedback->Bind(
SmiConstant(CompareOperationFeedback::kSignedSmall));
}
CombineFeedback(var_type_feedback,
CompareOperationFeedback::kSignedSmall);
Goto(&if_notequal);
BIND(&if_rhsisnotsmi);
......@@ -12396,17 +12389,14 @@ Node* CodeStubAssembler::StrictEqual(Node* lhs, Node* rhs,
Node* lhs_value = SmiToFloat64(lhs);
Node* rhs_value = LoadHeapNumberValue(rhs);
if (var_type_feedback != nullptr) {
var_type_feedback->Bind(
SmiConstant(CompareOperationFeedback::kNumber));
}
CombineFeedback(var_type_feedback, CompareOperationFeedback::kNumber);
// Perform a floating point comparison of {lhs} and {rhs}.
Branch(Float64Equal(lhs_value, rhs_value), &if_equal, &if_notequal);
}
BIND(&if_rhsisnotnumber);
Goto(&if_notequal);
Goto(&if_not_equivalent_types);
}
}
}
......@@ -12417,6 +12407,12 @@ Node* CodeStubAssembler::StrictEqual(Node* lhs, Node* rhs,
Goto(&end);
}
BIND(&if_not_equivalent_types);
{
OverwriteFeedback(var_type_feedback, CompareOperationFeedback::kAny);
Goto(&if_notequal);
}
BIND(&if_notequal);
{
result.Bind(FalseConstant());
......
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