Commit b890d8c4 authored by rmcilroy's avatar rmcilroy Committed by Commit bot

[Interpreter] Inline test and compare binary ops.

This inlines the test and compare binary operations into Ignition.
With this CL all binary ops are inlined into Ignition's bytecode
handlers.

Some blocks were shuffled around in Equals/NotEquals stubs to avoid
creating frames unecessarily. Some labels were also marked as non-
deferred in both Equals/NotEquals and the AbstractRelationalComparison
stubs for the same reason.

BUG=v8:4280
LOG=N

Review-Url: https://codereview.chromium.org/2013573004
Cr-Commit-Position: refs/heads/master@{#36542}
parent 34c202a0
......@@ -1827,15 +1827,16 @@ compiler::Node* DecStub::Generate(CodeStubAssembler* assembler,
return result_var.value();
}
void InstanceOfStub::GenerateAssembly(CodeStubAssembler* assembler) const {
// static
compiler::Node* InstanceOfStub::Generate(CodeStubAssembler* assembler,
compiler::Node* object,
compiler::Node* callable,
compiler::Node* context) {
typedef CodeStubAssembler::Label Label;
typedef compiler::Node Node;
Node* object = assembler->Parameter(0);
Node* callable = assembler->Parameter(1);
Node* context = assembler->Parameter(2);
typedef CodeStubAssembler::Variable Variable;
Label return_runtime(assembler, Label::kDeferred);
Label return_runtime(assembler, Label::kDeferred), end(assembler);
Variable result(assembler, MachineRepresentation::kTagged);
// Check if no one installed @@hasInstance somewhere.
assembler->GotoUnless(
......@@ -1857,11 +1858,19 @@ void InstanceOfStub::GenerateAssembly(CodeStubAssembler* assembler) const {
&return_runtime);
// Use the inline OrdinaryHasInstance directly.
assembler->Return(assembler->OrdinaryHasInstance(context, callable, object));
result.Bind(assembler->OrdinaryHasInstance(context, callable, object));
assembler->Goto(&end);
// TODO(bmeurer): Use GetPropertyStub here once available.
assembler->Bind(&return_runtime);
assembler->TailCallRuntime(Runtime::kInstanceOf, context, object, callable);
{
result.Bind(assembler->CallRuntime(Runtime::kInstanceOf, context, object,
callable));
assembler->Goto(&end);
}
assembler->Bind(&end);
return result.value();
}
namespace {
......@@ -1873,15 +1882,15 @@ enum RelationalComparisonMode {
kGreaterThanOrEqual
};
void GenerateAbstractRelationalComparison(CodeStubAssembler* assembler,
RelationalComparisonMode mode) {
compiler::Node* GenerateAbstractRelationalComparison(
CodeStubAssembler* assembler, RelationalComparisonMode mode,
compiler::Node* lhs, compiler::Node* rhs, compiler::Node* context) {
typedef CodeStubAssembler::Label Label;
typedef compiler::Node Node;
typedef CodeStubAssembler::Variable Variable;
Node* context = assembler->Parameter(2);
Label return_true(assembler), return_false(assembler);
Label return_true(assembler), return_false(assembler), end(assembler);
Variable result(assembler, MachineRepresentation::kTagged);
// Shared entry for floating point comparison.
Label do_fcmp(assembler);
......@@ -1894,14 +1903,14 @@ void GenerateAbstractRelationalComparison(CodeStubAssembler* assembler,
var_rhs(assembler, MachineRepresentation::kTagged);
Variable* loop_vars[2] = {&var_lhs, &var_rhs};
Label loop(assembler, 2, loop_vars);
var_lhs.Bind(assembler->Parameter(0));
var_rhs.Bind(assembler->Parameter(1));
var_lhs.Bind(lhs);
var_rhs.Bind(rhs);
assembler->Goto(&loop);
assembler->Bind(&loop);
{
// Load the current {lhs} and {rhs} values.
Node* lhs = var_lhs.value();
Node* rhs = var_rhs.value();
lhs = var_lhs.value();
rhs = var_rhs.value();
// Check if the {lhs} is a Smi or a HeapObject.
Label if_lhsissmi(assembler), if_lhsisnotsmi(assembler);
......@@ -2074,7 +2083,7 @@ void GenerateAbstractRelationalComparison(CodeStubAssembler* assembler,
Node* rhs_instance_type = assembler->LoadMapInstanceType(rhs_map);
// Check if {rhs} is also a String.
Label if_rhsisstring(assembler),
Label if_rhsisstring(assembler, Label::kDeferred),
if_rhsisnotstring(assembler, Label::kDeferred);
assembler->Branch(assembler->Int32LessThan(
rhs_instance_type, assembler->Int32Constant(
......@@ -2086,24 +2095,29 @@ void GenerateAbstractRelationalComparison(CodeStubAssembler* assembler,
// Both {lhs} and {rhs} are strings.
switch (mode) {
case kLessThan:
assembler->TailCallStub(
result.Bind(assembler->CallStub(
CodeFactory::StringLessThan(assembler->isolate()),
context, lhs, rhs);
context, lhs, rhs));
assembler->Goto(&end);
break;
case kLessThanOrEqual:
assembler->TailCallStub(
result.Bind(assembler->CallStub(
CodeFactory::StringLessThanOrEqual(assembler->isolate()),
context, lhs, rhs);
context, lhs, rhs));
assembler->Goto(&end);
break;
case kGreaterThan:
assembler->TailCallStub(
result.Bind(assembler->CallStub(
CodeFactory::StringGreaterThan(assembler->isolate()),
context, lhs, rhs);
context, lhs, rhs));
assembler->Goto(&end);
break;
case kGreaterThanOrEqual:
assembler->TailCallStub(CodeFactory::StringGreaterThanOrEqual(
result.Bind(
assembler->CallStub(CodeFactory::StringGreaterThanOrEqual(
assembler->isolate()),
context, lhs, rhs);
context, lhs, rhs));
assembler->Goto(&end);
break;
}
}
......@@ -2208,10 +2222,19 @@ void GenerateAbstractRelationalComparison(CodeStubAssembler* assembler,
}
assembler->Bind(&return_true);
assembler->Return(assembler->BooleanConstant(true));
{
result.Bind(assembler->BooleanConstant(true));
assembler->Goto(&end);
}
assembler->Bind(&return_false);
assembler->Return(assembler->BooleanConstant(false));
{
result.Bind(assembler->BooleanConstant(false));
assembler->Goto(&end);
}
assembler->Bind(&end);
return result.value();
}
enum ResultMode { kDontNegateResult, kNegateResult };
......@@ -2340,7 +2363,9 @@ void GenerateEqual_Simd128Value_HeapObject(
}
// ES6 section 7.2.12 Abstract Equality Comparison
void GenerateEqual(CodeStubAssembler* assembler, ResultMode mode) {
compiler::Node* GenerateEqual(CodeStubAssembler* assembler, ResultMode mode,
compiler::Node* lhs, compiler::Node* rhs,
compiler::Node* context) {
// This is a slightly optimized version of Object::Equals represented as
// scheduled TurboFan graph utilizing the CodeStubAssembler. Whenever you
// change something functionality wise in here, remember to update the
......@@ -2349,9 +2374,9 @@ void GenerateEqual(CodeStubAssembler* assembler, ResultMode mode) {
typedef compiler::Node Node;
typedef CodeStubAssembler::Variable Variable;
Node* context = assembler->Parameter(2);
Label if_equal(assembler), if_notequal(assembler);
Label if_equal(assembler), if_notequal(assembler),
do_rhsstringtonumber(assembler, Label::kDeferred), end(assembler);
Variable result(assembler, MachineRepresentation::kTagged);
// Shared entry for floating point comparison.
Label do_fcmp(assembler);
......@@ -2364,14 +2389,14 @@ void GenerateEqual(CodeStubAssembler* assembler, ResultMode mode) {
var_rhs(assembler, MachineRepresentation::kTagged);
Variable* loop_vars[2] = {&var_lhs, &var_rhs};
Label loop(assembler, 2, loop_vars);
var_lhs.Bind(assembler->Parameter(0));
var_rhs.Bind(assembler->Parameter(1));
var_lhs.Bind(lhs);
var_rhs.Bind(rhs);
assembler->Goto(&loop);
assembler->Bind(&loop);
{
// Load the current {lhs} and {rhs} values.
Node* lhs = var_lhs.value();
Node* rhs = var_rhs.value();
lhs = var_lhs.value();
rhs = var_rhs.value();
// Check if {lhs} and {rhs} refer to the same object.
Label if_same(assembler), if_notsame(assembler);
......@@ -2399,6 +2424,8 @@ void GenerateEqual(CodeStubAssembler* assembler, ResultMode mode) {
&if_rhsisnotsmi);
assembler->Bind(&if_rhsissmi);
// We have already checked for {lhs} and {rhs} being the same value, so
// if both are Smis when we get here they must not be equal.
assembler->Goto(&if_notequal);
assembler->Bind(&if_rhsisnotsmi);
......@@ -2408,8 +2435,7 @@ void GenerateEqual(CodeStubAssembler* assembler, ResultMode mode) {
// Check if {rhs} is a HeapNumber.
Node* number_map = assembler->HeapNumberMapConstant();
Label if_rhsisnumber(assembler),
if_rhsisnotnumber(assembler, Label::kDeferred);
Label if_rhsisnumber(assembler), if_rhsisnotnumber(assembler);
assembler->Branch(assembler->WordEqual(rhs_map, number_map),
&if_rhsisnumber, &if_rhsisnotnumber);
......@@ -2429,7 +2455,7 @@ void GenerateEqual(CodeStubAssembler* assembler, ResultMode mode) {
// Check if the {rhs} is a String.
Label if_rhsisstring(assembler, Label::kDeferred),
if_rhsisnotstring(assembler, Label::kDeferred);
if_rhsisnotstring(assembler);
assembler->Branch(assembler->Int32LessThan(
rhs_instance_type, assembler->Int32Constant(
FIRST_NONSTRING_TYPE)),
......@@ -2437,19 +2463,17 @@ void GenerateEqual(CodeStubAssembler* assembler, ResultMode mode) {
assembler->Bind(&if_rhsisstring);
{
// Convert the {rhs} to a Number.
Callable callable =
CodeFactory::StringToNumber(assembler->isolate());
var_rhs.Bind(assembler->CallStub(callable, context, rhs));
assembler->Goto(&loop);
// The {rhs} is a String and the {lhs} is a Smi; we need
// to convert the {rhs} to a Number and compare the output to
// the Number on the {lhs}.
assembler->Goto(&do_rhsstringtonumber);
}
assembler->Bind(&if_rhsisnotstring);
{
// Check if the {rhs} is a Boolean.
Node* boolean_map = assembler->BooleanMapConstant();
Label if_rhsisboolean(assembler, Label::kDeferred),
if_rhsisnotboolean(assembler, Label::kDeferred);
Label if_rhsisboolean(assembler), if_rhsisnotboolean(assembler);
assembler->Branch(assembler->WordEqual(rhs_map, boolean_map),
&if_rhsisboolean, &if_rhsisnotboolean);
......@@ -2466,7 +2490,7 @@ void GenerateEqual(CodeStubAssembler* assembler, ResultMode mode) {
// Check if the {rhs} is a Receiver.
STATIC_ASSERT(LAST_JS_RECEIVER_TYPE == LAST_TYPE);
Label if_rhsisreceiver(assembler, Label::kDeferred),
if_rhsisnotreceiver(assembler, Label::kDeferred);
if_rhsisnotreceiver(assembler);
assembler->Branch(
assembler->Int32LessThanOrEqual(
assembler->Int32Constant(FIRST_JS_RECEIVER_TYPE),
......@@ -2550,8 +2574,8 @@ void GenerateEqual(CodeStubAssembler* assembler, ResultMode mode) {
assembler->Bind(&if_lhsisstring);
{
// Check if {rhs} is also a String.
Label if_rhsisstring(assembler),
if_rhsisnotstring(assembler, Label::kDeferred);
Label if_rhsisstring(assembler, Label::kDeferred),
if_rhsisnotstring(assembler);
assembler->Branch(assembler->Int32LessThan(
rhs_instance_type, assembler->Int32Constant(
FIRST_NONSTRING_TYPE)),
......@@ -2565,7 +2589,8 @@ void GenerateEqual(CodeStubAssembler* assembler, ResultMode mode) {
(mode == kDontNegateResult)
? CodeFactory::StringEqual(assembler->isolate())
: CodeFactory::StringNotEqual(assembler->isolate());
assembler->TailCallStub(callable, context, lhs, rhs);
result.Bind(assembler->CallStub(callable, context, lhs, rhs));
assembler->Goto(&end);
}
assembler->Bind(&if_rhsisnotstring);
......@@ -2583,8 +2608,7 @@ void GenerateEqual(CodeStubAssembler* assembler, ResultMode mode) {
assembler->Bind(&if_lhsisnumber);
{
// Check if {rhs} is also a HeapNumber.
Label if_rhsisnumber(assembler),
if_rhsisnotnumber(assembler, Label::kDeferred);
Label if_rhsisnumber(assembler), if_rhsisnotnumber(assembler);
assembler->Branch(
assembler->Word32Equal(lhs_instance_type, rhs_instance_type),
&if_rhsisnumber, &if_rhsisnotnumber);
......@@ -2614,16 +2638,13 @@ void GenerateEqual(CodeStubAssembler* assembler, ResultMode mode) {
// The {rhs} is a String and the {lhs} is a HeapNumber; we need
// to convert the {rhs} to a Number and compare the output to
// the Number on the {lhs}.
Callable callable =
CodeFactory::StringToNumber(assembler->isolate());
var_rhs.Bind(assembler->CallStub(callable, context, rhs));
assembler->Goto(&loop);
assembler->Goto(&do_rhsstringtonumber);
}
assembler->Bind(&if_rhsisnotstring);
{
// Check if the {rhs} is a JSReceiver.
Label if_rhsisreceiver(assembler, Label::kDeferred),
Label if_rhsisreceiver(assembler),
if_rhsisnotreceiver(assembler);
STATIC_ASSERT(LAST_TYPE == LAST_JS_RECEIVER_TYPE);
assembler->Branch(
......@@ -2715,8 +2736,7 @@ void GenerateEqual(CodeStubAssembler* assembler, ResultMode mode) {
assembler->Bind(&if_lhsissymbol);
{
// Check if the {rhs} is a JSReceiver.
Label if_rhsisreceiver(assembler, Label::kDeferred),
if_rhsisnotreceiver(assembler);
Label if_rhsisreceiver(assembler), if_rhsisnotreceiver(assembler);
STATIC_ASSERT(LAST_TYPE == LAST_JS_RECEIVER_TYPE);
assembler->Branch(
assembler->Int32LessThanOrEqual(
......@@ -2763,8 +2783,7 @@ void GenerateEqual(CodeStubAssembler* assembler, ResultMode mode) {
assembler->Bind(&if_rhsisnotsimd128value);
{
// Check if the {rhs} is a JSReceiver.
Label if_rhsisreceiver(assembler, Label::kDeferred),
if_rhsisnotreceiver(assembler);
Label if_rhsisreceiver(assembler), if_rhsisnotreceiver(assembler);
STATIC_ASSERT(LAST_TYPE == LAST_JS_RECEIVER_TYPE);
assembler->Branch(
assembler->Int32LessThanOrEqual(
......@@ -2849,6 +2868,13 @@ void GenerateEqual(CodeStubAssembler* assembler, ResultMode mode) {
}
}
}
assembler->Bind(&do_rhsstringtonumber);
{
Callable callable = CodeFactory::StringToNumber(assembler->isolate());
var_rhs.Bind(assembler->CallStub(callable, context, rhs));
assembler->Goto(&loop);
}
}
assembler->Bind(&do_fcmp);
......@@ -2862,13 +2888,25 @@ void GenerateEqual(CodeStubAssembler* assembler, ResultMode mode) {
}
assembler->Bind(&if_equal);
assembler->Return(assembler->BooleanConstant(mode == kDontNegateResult));
{
result.Bind(assembler->BooleanConstant(mode == kDontNegateResult));
assembler->Goto(&end);
}
assembler->Bind(&if_notequal);
assembler->Return(assembler->BooleanConstant(mode == kNegateResult));
{
result.Bind(assembler->BooleanConstant(mode == kNegateResult));
assembler->Goto(&end);
}
assembler->Bind(&end);
return result.value();
}
void GenerateStrictEqual(CodeStubAssembler* assembler, ResultMode mode) {
compiler::Node* GenerateStrictEqual(CodeStubAssembler* assembler,
ResultMode mode, compiler::Node* lhs,
compiler::Node* rhs,
compiler::Node* context) {
// Here's pseudo-code for the algorithm below in case of kDontNegateResult
// mode; for kNegateResult mode we properly negate the result.
//
......@@ -2918,13 +2956,11 @@ void GenerateStrictEqual(CodeStubAssembler* assembler, ResultMode mode) {
// }
typedef CodeStubAssembler::Label Label;
typedef CodeStubAssembler::Variable Variable;
typedef compiler::Node Node;
Node* lhs = assembler->Parameter(0);
Node* rhs = assembler->Parameter(1);
Node* context = assembler->Parameter(2);
Label if_equal(assembler), if_notequal(assembler);
Label if_equal(assembler), if_notequal(assembler), end(assembler);
Variable result(assembler, MachineRepresentation::kTagged);
// Check if {lhs} and {rhs} refer to the same object.
Label if_same(assembler), if_notsame(assembler);
......@@ -3029,7 +3065,8 @@ void GenerateStrictEqual(CodeStubAssembler* assembler, ResultMode mode) {
Node* rhs_instance_type = assembler->LoadInstanceType(rhs);
// Check if {rhs} is also a String.
Label if_rhsisstring(assembler), if_rhsisnotstring(assembler);
Label if_rhsisstring(assembler, Label::kDeferred),
if_rhsisnotstring(assembler);
assembler->Branch(assembler->Int32LessThan(
rhs_instance_type, assembler->Int32Constant(
FIRST_NONSTRING_TYPE)),
......@@ -3041,7 +3078,8 @@ void GenerateStrictEqual(CodeStubAssembler* assembler, ResultMode mode) {
(mode == kDontNegateResult)
? CodeFactory::StringEqual(assembler->isolate())
: CodeFactory::StringNotEqual(assembler->isolate());
assembler->TailCallStub(callable, context, lhs, rhs);
result.Bind(assembler->CallStub(callable, context, lhs, rhs));
assembler->Goto(&end);
}
assembler->Bind(&if_rhsisnotstring);
......@@ -3118,10 +3156,19 @@ void GenerateStrictEqual(CodeStubAssembler* assembler, ResultMode mode) {
}
assembler->Bind(&if_equal);
assembler->Return(assembler->BooleanConstant(mode == kDontNegateResult));
{
result.Bind(assembler->BooleanConstant(mode == kDontNegateResult));
assembler->Goto(&end);
}
assembler->Bind(&if_notequal);
assembler->Return(assembler->BooleanConstant(mode == kNegateResult));
{
result.Bind(assembler->BooleanConstant(mode == kNegateResult));
assembler->Goto(&end);
}
assembler->Bind(&end);
return result.value();
}
void GenerateStringRelationalComparison(CodeStubAssembler* assembler,
......@@ -3501,37 +3548,69 @@ void LoadApiGetterStub::GenerateAssembly(CodeStubAssembler* assembler) const {
holder, callback);
}
void LessThanStub::GenerateAssembly(CodeStubAssembler* assembler) const {
GenerateAbstractRelationalComparison(assembler, kLessThan);
// static
compiler::Node* LessThanStub::Generate(CodeStubAssembler* assembler,
compiler::Node* lhs, compiler::Node* rhs,
compiler::Node* context) {
return GenerateAbstractRelationalComparison(assembler, kLessThan, lhs, rhs,
context);
}
void LessThanOrEqualStub::GenerateAssembly(CodeStubAssembler* assembler) const {
GenerateAbstractRelationalComparison(assembler, kLessThanOrEqual);
// static
compiler::Node* LessThanOrEqualStub::Generate(CodeStubAssembler* assembler,
compiler::Node* lhs,
compiler::Node* rhs,
compiler::Node* context) {
return GenerateAbstractRelationalComparison(assembler, kLessThanOrEqual, lhs,
rhs, context);
}
void GreaterThanStub::GenerateAssembly(CodeStubAssembler* assembler) const {
GenerateAbstractRelationalComparison(assembler, kGreaterThan);
// static
compiler::Node* GreaterThanStub::Generate(CodeStubAssembler* assembler,
compiler::Node* lhs,
compiler::Node* rhs,
compiler::Node* context) {
return GenerateAbstractRelationalComparison(assembler, kGreaterThan, lhs, rhs,
context);
}
void GreaterThanOrEqualStub::GenerateAssembly(
CodeStubAssembler* assembler) const {
GenerateAbstractRelationalComparison(assembler, kGreaterThanOrEqual);
// static
compiler::Node* GreaterThanOrEqualStub::Generate(CodeStubAssembler* assembler,
compiler::Node* lhs,
compiler::Node* rhs,
compiler::Node* context) {
return GenerateAbstractRelationalComparison(assembler, kGreaterThanOrEqual,
lhs, rhs, context);
}
void EqualStub::GenerateAssembly(CodeStubAssembler* assembler) const {
GenerateEqual(assembler, kDontNegateResult);
// static
compiler::Node* EqualStub::Generate(CodeStubAssembler* assembler,
compiler::Node* lhs, compiler::Node* rhs,
compiler::Node* context) {
return GenerateEqual(assembler, kDontNegateResult, lhs, rhs, context);
}
void NotEqualStub::GenerateAssembly(CodeStubAssembler* assembler) const {
GenerateEqual(assembler, kNegateResult);
// static
compiler::Node* NotEqualStub::Generate(CodeStubAssembler* assembler,
compiler::Node* lhs, compiler::Node* rhs,
compiler::Node* context) {
return GenerateEqual(assembler, kNegateResult, lhs, rhs, context);
}
void StrictEqualStub::GenerateAssembly(CodeStubAssembler* assembler) const {
GenerateStrictEqual(assembler, kDontNegateResult);
// static
compiler::Node* StrictEqualStub::Generate(CodeStubAssembler* assembler,
compiler::Node* lhs,
compiler::Node* rhs,
compiler::Node* context) {
return GenerateStrictEqual(assembler, kDontNegateResult, lhs, rhs, context);
}
void StrictNotEqualStub::GenerateAssembly(CodeStubAssembler* assembler) const {
GenerateStrictEqual(assembler, kNegateResult);
// static
compiler::Node* StrictNotEqualStub::Generate(CodeStubAssembler* assembler,
compiler::Node* lhs,
compiler::Node* rhs,
compiler::Node* context) {
return GenerateStrictEqual(assembler, kNegateResult, lhs, rhs, context);
}
void StringEqualStub::GenerateAssembly(CodeStubAssembler* assembler) const {
......@@ -4198,17 +4277,17 @@ void TypeofStub::GenerateAheadOfTime(Isolate* isolate) {
stub.GetCode();
}
void HasPropertyStub::GenerateAssembly(CodeStubAssembler* assembler) const {
// static
compiler::Node* HasPropertyStub::Generate(CodeStubAssembler* assembler,
compiler::Node* key,
compiler::Node* object,
compiler::Node* context) {
typedef compiler::Node Node;
typedef CodeStubAssembler::Label Label;
typedef CodeStubAssembler::Variable Variable;
Node* key = assembler->Parameter(0);
Node* object = assembler->Parameter(1);
Node* context = assembler->Parameter(2);
Label call_runtime(assembler), return_true(assembler),
return_false(assembler);
Label call_runtime(assembler, Label::kDeferred), return_true(assembler),
return_false(assembler), end(assembler);
// Ensure object is JSReceiver, otherwise call runtime to throw error.
Label if_objectisnotsmi(assembler);
......@@ -4306,14 +4385,29 @@ void HasPropertyStub::GenerateAssembly(CodeStubAssembler* assembler) const {
assembler->Goto(&loop);
}
}
Variable result(assembler, MachineRepresentation::kTagged);
assembler->Bind(&return_true);
assembler->Return(assembler->BooleanConstant(true));
{
result.Bind(assembler->BooleanConstant(true));
assembler->Goto(&end);
}
assembler->Bind(&return_false);
assembler->Return(assembler->BooleanConstant(false));
{
result.Bind(assembler->BooleanConstant(false));
assembler->Goto(&end);
}
assembler->Bind(&call_runtime);
assembler->TailCallRuntime(Runtime::kHasProperty, context, key, object);
{
result.Bind(
assembler->CallRuntime(Runtime::kHasProperty, context, key, object));
assembler->Goto(&end);
}
assembler->Bind(&end);
return result.value();
}
void CreateAllocationSiteStub::GenerateAheadOfTime(Isolate* isolate) {
......
......@@ -810,7 +810,7 @@ class InstanceOfStub final : public TurboFanCodeStub {
private:
DEFINE_CALL_INTERFACE_DESCRIPTOR(Compare);
DEFINE_TURBOFAN_CODE_STUB(InstanceOf, TurboFanCodeStub);
DEFINE_TURBOFAN_BINARY_OP_CODE_STUB(InstanceOf, TurboFanCodeStub);
};
class LessThanStub final : public TurboFanCodeStub {
......@@ -818,7 +818,7 @@ class LessThanStub final : public TurboFanCodeStub {
explicit LessThanStub(Isolate* isolate) : TurboFanCodeStub(isolate) {}
DEFINE_CALL_INTERFACE_DESCRIPTOR(Compare);
DEFINE_TURBOFAN_CODE_STUB(LessThan, TurboFanCodeStub);
DEFINE_TURBOFAN_BINARY_OP_CODE_STUB(LessThan, TurboFanCodeStub);
};
class LessThanOrEqualStub final : public TurboFanCodeStub {
......@@ -826,7 +826,7 @@ class LessThanOrEqualStub final : public TurboFanCodeStub {
explicit LessThanOrEqualStub(Isolate* isolate) : TurboFanCodeStub(isolate) {}
DEFINE_CALL_INTERFACE_DESCRIPTOR(Compare);
DEFINE_TURBOFAN_CODE_STUB(LessThanOrEqual, TurboFanCodeStub);
DEFINE_TURBOFAN_BINARY_OP_CODE_STUB(LessThanOrEqual, TurboFanCodeStub);
};
class GreaterThanStub final : public TurboFanCodeStub {
......@@ -834,7 +834,7 @@ class GreaterThanStub final : public TurboFanCodeStub {
explicit GreaterThanStub(Isolate* isolate) : TurboFanCodeStub(isolate) {}
DEFINE_CALL_INTERFACE_DESCRIPTOR(Compare);
DEFINE_TURBOFAN_CODE_STUB(GreaterThan, TurboFanCodeStub);
DEFINE_TURBOFAN_BINARY_OP_CODE_STUB(GreaterThan, TurboFanCodeStub);
};
class GreaterThanOrEqualStub final : public TurboFanCodeStub {
......@@ -843,7 +843,7 @@ class GreaterThanOrEqualStub final : public TurboFanCodeStub {
: TurboFanCodeStub(isolate) {}
DEFINE_CALL_INTERFACE_DESCRIPTOR(Compare);
DEFINE_TURBOFAN_CODE_STUB(GreaterThanOrEqual, TurboFanCodeStub);
DEFINE_TURBOFAN_BINARY_OP_CODE_STUB(GreaterThanOrEqual, TurboFanCodeStub);
};
class EqualStub final : public TurboFanCodeStub {
......@@ -851,7 +851,7 @@ class EqualStub final : public TurboFanCodeStub {
explicit EqualStub(Isolate* isolate) : TurboFanCodeStub(isolate) {}
DEFINE_CALL_INTERFACE_DESCRIPTOR(Compare);
DEFINE_TURBOFAN_CODE_STUB(Equal, TurboFanCodeStub);
DEFINE_TURBOFAN_BINARY_OP_CODE_STUB(Equal, TurboFanCodeStub);
};
class NotEqualStub final : public TurboFanCodeStub {
......@@ -859,7 +859,7 @@ class NotEqualStub final : public TurboFanCodeStub {
explicit NotEqualStub(Isolate* isolate) : TurboFanCodeStub(isolate) {}
DEFINE_CALL_INTERFACE_DESCRIPTOR(Compare);
DEFINE_TURBOFAN_CODE_STUB(NotEqual, TurboFanCodeStub);
DEFINE_TURBOFAN_BINARY_OP_CODE_STUB(NotEqual, TurboFanCodeStub);
};
class StrictEqualStub final : public TurboFanCodeStub {
......@@ -867,7 +867,7 @@ class StrictEqualStub final : public TurboFanCodeStub {
explicit StrictEqualStub(Isolate* isolate) : TurboFanCodeStub(isolate) {}
DEFINE_CALL_INTERFACE_DESCRIPTOR(Compare);
DEFINE_TURBOFAN_CODE_STUB(StrictEqual, TurboFanCodeStub);
DEFINE_TURBOFAN_BINARY_OP_CODE_STUB(StrictEqual, TurboFanCodeStub);
};
class StrictNotEqualStub final : public TurboFanCodeStub {
......@@ -875,7 +875,7 @@ class StrictNotEqualStub final : public TurboFanCodeStub {
explicit StrictNotEqualStub(Isolate* isolate) : TurboFanCodeStub(isolate) {}
DEFINE_CALL_INTERFACE_DESCRIPTOR(Compare);
DEFINE_TURBOFAN_CODE_STUB(StrictNotEqual, TurboFanCodeStub);
DEFINE_TURBOFAN_BINARY_OP_CODE_STUB(StrictNotEqual, TurboFanCodeStub);
};
class StringEqualStub final : public TurboFanCodeStub {
......@@ -986,7 +986,7 @@ class HasPropertyStub : public TurboFanCodeStub {
explicit HasPropertyStub(Isolate* isolate) : TurboFanCodeStub(isolate) {}
DEFINE_CALL_INTERFACE_DESCRIPTOR(HasProperty);
DEFINE_TURBOFAN_CODE_STUB(HasProperty, TurboFanCodeStub);
DEFINE_TURBOFAN_BINARY_OP_CODE_STUB(HasProperty, TurboFanCodeStub);
};
enum StringAddFlags {
......
......@@ -754,20 +754,6 @@ void Interpreter::DoPopContext(InterpreterAssembler* assembler) {
__ Dispatch();
}
void Interpreter::DoBinaryOp(Callable callable,
InterpreterAssembler* assembler) {
// TODO(bmeurer): Collect definition side type feedback for various
// binary operations.
Node* target = __ HeapConstant(callable.code());
Node* reg_index = __ BytecodeOperandReg(0);
Node* lhs = __ LoadRegister(reg_index);
Node* rhs = __ GetAccumulator();
Node* context = __ GetContext();
Node* result = __ CallStub(callable.descriptor(), target, context, lhs, rhs);
__ SetAccumulator(result);
__ Dispatch();
}
template <class Generator>
void Interpreter::DoBinaryOp(InterpreterAssembler* assembler) {
Node* reg_index = __ BytecodeOperandReg(0);
......@@ -1168,35 +1154,35 @@ void Interpreter::DoNew(InterpreterAssembler* assembler) {
//
// Test if the value in the <src> register equals the accumulator.
void Interpreter::DoTestEqual(InterpreterAssembler* assembler) {
DoBinaryOp(CodeFactory::Equal(isolate_), assembler);
DoBinaryOp<EqualStub>(assembler);
}
// TestNotEqual <src>
//
// Test if the value in the <src> register is not equal to the accumulator.
void Interpreter::DoTestNotEqual(InterpreterAssembler* assembler) {
DoBinaryOp(CodeFactory::NotEqual(isolate_), assembler);
DoBinaryOp<NotEqualStub>(assembler);
}
// TestEqualStrict <src>
//
// Test if the value in the <src> register is strictly equal to the accumulator.
void Interpreter::DoTestEqualStrict(InterpreterAssembler* assembler) {
DoBinaryOp(CodeFactory::StrictEqual(isolate_), assembler);
DoBinaryOp<StrictEqualStub>(assembler);
}
// TestLessThan <src>
//
// Test if the value in the <src> register is less than the accumulator.
void Interpreter::DoTestLessThan(InterpreterAssembler* assembler) {
DoBinaryOp(CodeFactory::LessThan(isolate_), assembler);
DoBinaryOp<LessThanStub>(assembler);
}
// TestGreaterThan <src>
//
// Test if the value in the <src> register is greater than the accumulator.
void Interpreter::DoTestGreaterThan(InterpreterAssembler* assembler) {
DoBinaryOp(CodeFactory::GreaterThan(isolate_), assembler);
DoBinaryOp<GreaterThanStub>(assembler);
}
// TestLessThanOrEqual <src>
......@@ -1204,7 +1190,7 @@ void Interpreter::DoTestGreaterThan(InterpreterAssembler* assembler) {
// Test if the value in the <src> register is less than or equal to the
// accumulator.
void Interpreter::DoTestLessThanOrEqual(InterpreterAssembler* assembler) {
DoBinaryOp(CodeFactory::LessThanOrEqual(isolate_), assembler);
DoBinaryOp<LessThanOrEqualStub>(assembler);
}
// TestGreaterThanOrEqual <src>
......@@ -1212,7 +1198,7 @@ void Interpreter::DoTestLessThanOrEqual(InterpreterAssembler* assembler) {
// Test if the value in the <src> register is greater than or equal to the
// accumulator.
void Interpreter::DoTestGreaterThanOrEqual(InterpreterAssembler* assembler) {
DoBinaryOp(CodeFactory::GreaterThanOrEqual(isolate_), assembler);
DoBinaryOp<GreaterThanOrEqualStub>(assembler);
}
// TestIn <src>
......@@ -1220,7 +1206,7 @@ void Interpreter::DoTestGreaterThanOrEqual(InterpreterAssembler* assembler) {
// Test if the object referenced by the register operand is a property of the
// object referenced by the accumulator.
void Interpreter::DoTestIn(InterpreterAssembler* assembler) {
DoBinaryOp(CodeFactory::HasProperty(isolate_), assembler);
DoBinaryOp<HasPropertyStub>(assembler);
}
// TestInstanceOf <src>
......@@ -1228,7 +1214,7 @@ void Interpreter::DoTestIn(InterpreterAssembler* assembler) {
// Test if the object referenced by the <src> register is an an instance of type
// referenced by the accumulator.
void Interpreter::DoTestInstanceOf(InterpreterAssembler* assembler) {
DoBinaryOp(CodeFactory::InstanceOf(isolate_), assembler);
DoBinaryOp<InstanceOfStub>(assembler);
}
// Jump <imm>
......
......@@ -70,9 +70,6 @@ class Interpreter {
BYTECODE_LIST(DECLARE_BYTECODE_HANDLER_GENERATOR)
#undef DECLARE_BYTECODE_HANDLER_GENERATOR
// Generates code to perform the binary operation via |callable|.
void DoBinaryOp(Callable callable, InterpreterAssembler* assembler);
// Generates code to perform the binary operation via |Generator|.
template <class Generator>
void DoBinaryOp(InterpreterAssembler* assembler);
......
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