[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}
This commit is contained in:
parent
f528509be9
commit
d6121fd1a3
@ -11373,7 +11373,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);
|
||||
@ -11861,7 +11862,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);
|
||||
|
||||
@ -12197,9 +12199,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);
|
||||
@ -12208,9 +12213,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);
|
||||
}
|
||||
|
||||
@ -12219,10 +12221,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);
|
||||
@ -12248,10 +12246,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);
|
||||
@ -12272,17 +12267,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);
|
||||
}
|
||||
}
|
||||
|
||||
@ -12293,7 +12286,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);
|
||||
{
|
||||
@ -12301,7 +12294,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);
|
||||
|
||||
@ -12331,92 +12324,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 {lhs} is a BigInt.
|
||||
Label if_lhsisbigint(this), if_lhsisnotbigint(this);
|
||||
Branch(IsBigIntInstanceType(lhs_instance_type), &if_lhsisbigint,
|
||||
&if_lhsisnotbigint);
|
||||
|
||||
// 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);
|
||||
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_not_equivalent_types);
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
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);
|
||||
|
||||
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_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_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));
|
||||
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);
|
||||
}
|
||||
|
||||
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_lhsissymbol);
|
||||
{
|
||||
GotoIfNot(IsSymbolInstanceType(rhs_instance_type), &if_notequal);
|
||||
var_type_feedback->Bind(
|
||||
SmiConstant(CompareOperationFeedback::kSymbol));
|
||||
Goto(&if_notequal);
|
||||
}
|
||||
} else {
|
||||
Goto(&if_notequal);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -12433,10 +12428,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);
|
||||
@ -12454,17 +12447,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);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -12475,6 +12465,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());
|
||||
|
Loading…
Reference in New Issue
Block a user