| Index: test/unittests/compiler/instruction-selector-unittest.cc
|
| diff --git a/test/unittests/compiler/instruction-selector-unittest.cc b/test/unittests/compiler/instruction-selector-unittest.cc
|
| index 645b0f689b7a32961295d288b20ab6a983e242c0..4f0aba1067f9efb526b13df7ed452d76a2de4505 100644
|
| --- a/test/unittests/compiler/instruction-selector-unittest.cc
|
| +++ b/test/unittests/compiler/instruction-selector-unittest.cc
|
| @@ -4,6 +4,7 @@
|
|
|
| #include "test/unittests/compiler/instruction-selector-unittest.h"
|
|
|
| +#include "src/code-stubs.h"
|
| #include "src/compiler/graph.h"
|
| #include "src/compiler/schedule.h"
|
| #include "src/flags.h"
|
| @@ -590,6 +591,53 @@ TARGET_TEST_F(InstructionSelectorTest,
|
| EXPECT_EQ(index, s.size());
|
| }
|
|
|
| +
|
| +// -----------------------------------------------------------------------------
|
| +// Tail calls.
|
| +
|
| +TARGET_TEST_F(InstructionSelectorTest, TailCall) {
|
| + for (int mode = 0; mode < 2; ++mode) {
|
| + bool supports_tail_calls = FLAG_turbo_tail_calls && (mode == 0);
|
| +
|
| + StreamBuilder m(this, kMachAnyTagged);
|
| + Node* start = m.graph()->start();
|
| + Node* undefined = m.UndefinedConstant();
|
| +
|
| + StringLengthStub stub(isolate());
|
| + CallDescriptor* desc = Linkage::GetStubCallDescriptor(
|
| + isolate(), zone(), stub.GetCallInterfaceDescriptor(), 0,
|
| + supports_tail_calls ? CallDescriptor::kSupportsTailCalls
|
| + : CallDescriptor::kNoFlags,
|
| + Operator::kNoProperties);
|
| + Node* stub_node = m.NewNode(m.common()->HeapConstant(
|
| + Unique<Code>::CreateUninitialized(stub.GetCode())));
|
| +
|
| + Node* call = m.NewNode(m.common()->Call(desc), stub_node, undefined,
|
| + undefined, undefined, undefined, undefined);
|
| + call->AppendInput(zone(), start); // effect
|
| + call->AppendInput(zone(), start); // control
|
| +
|
| + m.Return(call);
|
| + Node* ret = *call->uses().begin();
|
| + ret->AppendInput(zone(), call); // effect
|
| + ret->AppendInput(zone(), start); // control
|
| +
|
| + Stream s = m.Build(kAllInstructions);
|
| + if (supports_tail_calls) {
|
| + ASSERT_EQ(3U, s.size());
|
| + EXPECT_EQ(kArchNop, s[0]->arch_opcode());
|
| + EXPECT_EQ(kArchTailCallCodeObject, s[1]->arch_opcode());
|
| + EXPECT_EQ(kArchNop, s[2]->arch_opcode());
|
| + } else {
|
| + ASSERT_EQ(4U, s.size());
|
| + EXPECT_EQ(kArchNop, s[0]->arch_opcode());
|
| + EXPECT_EQ(kArchCallCodeObject, s[1]->arch_opcode());
|
| + EXPECT_EQ(kArchRet, s[2]->arch_opcode());
|
| + EXPECT_EQ(kArchNop, s[3]->arch_opcode());
|
| + }
|
| + }
|
| +}
|
| +
|
| } // namespace compiler
|
| } // namespace internal
|
| } // namespace v8
|
|
|