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