[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:
Ross McIlroy 2019-04-17 12:59:56 +01:00 committed by Commit Bot
parent f528509be9
commit d6121fd1a3

View File

@ -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());