diff options
Diffstat (limited to 'deps/v8/test/unittests/compiler')
21 files changed, 1790 insertions, 86 deletions
diff --git a/deps/v8/test/unittests/compiler/arm64/instruction-selector-arm64-unittest.cc b/deps/v8/test/unittests/compiler/arm64/instruction-selector-arm64-unittest.cc index 7e67b31616..71c2d44d2f 100644 --- a/deps/v8/test/unittests/compiler/arm64/instruction-selector-arm64-unittest.cc +++ b/deps/v8/test/unittests/compiler/arm64/instruction-selector-arm64-unittest.cc @@ -2421,6 +2421,40 @@ TEST_F(InstructionSelectorTest, Word32EqualWithSignedExtendHalfword) { } +TEST_F(InstructionSelectorTest, Word32EqualZeroWithWord32Equal) { + { + StreamBuilder m(this, kMachInt32, kMachInt32, kMachInt32); + Node* const p0 = m.Parameter(0); + Node* const p1 = m.Parameter(1); + m.Return(m.Word32Equal(m.Word32Equal(p0, p1), m.Int32Constant(0))); + Stream s = m.Build(); + ASSERT_EQ(1U, s.size()); + EXPECT_EQ(kArm64Cmp32, s[0]->arch_opcode()); + ASSERT_EQ(2U, s[0]->InputCount()); + EXPECT_EQ(s.ToVreg(p0), s.ToVreg(s[0]->InputAt(0))); + EXPECT_EQ(s.ToVreg(p1), s.ToVreg(s[0]->InputAt(1))); + EXPECT_EQ(1U, s[0]->OutputCount()); + EXPECT_EQ(kFlags_set, s[0]->flags_mode()); + EXPECT_EQ(kNotEqual, s[0]->flags_condition()); + } + { + StreamBuilder m(this, kMachInt32, kMachInt32, kMachInt32); + Node* const p0 = m.Parameter(0); + Node* const p1 = m.Parameter(1); + m.Return(m.Word32Equal(m.Int32Constant(0), m.Word32Equal(p0, p1))); + Stream s = m.Build(); + ASSERT_EQ(1U, s.size()); + EXPECT_EQ(kArm64Cmp32, s[0]->arch_opcode()); + ASSERT_EQ(2U, s[0]->InputCount()); + EXPECT_EQ(s.ToVreg(p0), s.ToVreg(s[0]->InputAt(0))); + EXPECT_EQ(s.ToVreg(p1), s.ToVreg(s[0]->InputAt(1))); + EXPECT_EQ(1U, s[0]->OutputCount()); + EXPECT_EQ(kFlags_set, s[0]->flags_mode()); + EXPECT_EQ(kNotEqual, s[0]->flags_condition()); + } +} + + // ----------------------------------------------------------------------------- // Miscellaneous diff --git a/deps/v8/test/unittests/compiler/coalesced-live-ranges-unittest.cc b/deps/v8/test/unittests/compiler/coalesced-live-ranges-unittest.cc new file mode 100644 index 0000000000..ea9ebdb20b --- /dev/null +++ b/deps/v8/test/unittests/compiler/coalesced-live-ranges-unittest.cc @@ -0,0 +1,309 @@ +// Copyright 2014 the V8 project authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "src/compiler/coalesced-live-ranges.h" +#include "test/unittests/test-utils.h" + +namespace v8 { +namespace internal { +namespace compiler { + + +// Utility offering shorthand syntax for building up a range by providing its ID +// and pairs (start, end) specifying intervals. Circumvents current incomplete +// support for C++ features such as instantiation lists, on OS X and Android. +class TestRangeBuilder { + public: + explicit TestRangeBuilder(Zone* zone) : id_(-1), pairs_(), zone_(zone) {} + + TestRangeBuilder& Id(int id) { + id_ = id; + return *this; + } + TestRangeBuilder& Add(int start, int end) { + pairs_.push_back({start, end}); + return *this; + } + + LiveRange* Build(int start, int end) { return Add(start, end).Build(); } + + LiveRange* Build() { + LiveRange* range = new (zone_) LiveRange(id_, MachineType::kRepTagged); + // Traverse the provided interval specifications backwards, because that is + // what LiveRange expects. + for (int i = static_cast<int>(pairs_.size()) - 1; i >= 0; --i) { + Interval pair = pairs_[i]; + LifetimePosition start = LifetimePosition::FromInt(pair.first); + LifetimePosition end = LifetimePosition::FromInt(pair.second); + CHECK(start < end); + range->AddUseInterval(start, end, zone_); + } + + pairs_.clear(); + return range; + } + + private: + typedef std::pair<int, int> Interval; + typedef std::vector<Interval> IntervalList; + int id_; + IntervalList pairs_; + Zone* zone_; +}; + + +class CoalescedLiveRangesTest : public TestWithZone { + public: + CoalescedLiveRangesTest() : TestWithZone(), ranges_(zone()) {} + bool HasNoConflicts(const LiveRange* range); + bool ConflictsPreciselyWith(const LiveRange* range, int id); + bool ConflictsPreciselyWith(const LiveRange* range, int id1, int id2); + + CoalescedLiveRanges& ranges() { return ranges_; } + const CoalescedLiveRanges& ranges() const { return ranges_; } + bool AllocationsAreValid() const; + void RemoveConflicts(LiveRange* range); + + private: + typedef ZoneSet<int> LiveRangeIDs; + bool IsRangeConflictingWith(const LiveRange* range, const LiveRangeIDs& ids); + CoalescedLiveRanges ranges_; +}; + + +bool CoalescedLiveRangesTest::ConflictsPreciselyWith(const LiveRange* range, + int id) { + LiveRangeIDs set(zone()); + set.insert(id); + return IsRangeConflictingWith(range, set); +} + + +bool CoalescedLiveRangesTest::ConflictsPreciselyWith(const LiveRange* range, + int id1, int id2) { + LiveRangeIDs set(zone()); + set.insert(id1); + set.insert(id2); + return IsRangeConflictingWith(range, set); +} + + +bool CoalescedLiveRangesTest::HasNoConflicts(const LiveRange* range) { + LiveRangeIDs set(zone()); + return IsRangeConflictingWith(range, set); +} + + +void CoalescedLiveRangesTest::RemoveConflicts(LiveRange* range) { + auto conflicts = ranges().GetConflicts(range); + LiveRangeIDs seen(zone()); + for (auto c = conflicts.Current(); c != nullptr; + c = conflicts.RemoveCurrentAndGetNext()) { + EXPECT_FALSE(seen.count(c->id()) > 0); + seen.insert(c->id()); + } +} + + +bool CoalescedLiveRangesTest::AllocationsAreValid() const { + return ranges().VerifyAllocationsAreValidForTesting(); +} + + +bool CoalescedLiveRangesTest::IsRangeConflictingWith(const LiveRange* range, + const LiveRangeIDs& ids) { + LiveRangeIDs found_ids(zone()); + + auto conflicts = ranges().GetConflicts(range); + for (auto conflict = conflicts.Current(); conflict != nullptr; + conflict = conflicts.GetNext()) { + found_ids.insert(conflict->id()); + } + return found_ids == ids; +} + + +TEST_F(CoalescedLiveRangesTest, VisitEmptyAllocations) { + LiveRange* range = TestRangeBuilder(zone()).Id(1).Build(1, 5); + ASSERT_TRUE(ranges().empty()); + ASSERT_TRUE(AllocationsAreValid()); + ASSERT_TRUE(HasNoConflicts(range)); +} + + +TEST_F(CoalescedLiveRangesTest, CandidateBeforeAfterAllocations) { + LiveRange* range = TestRangeBuilder(zone()).Id(1).Build(5, 6); + ranges().AllocateRange(range); + ASSERT_FALSE(ranges().empty()); + ASSERT_TRUE(AllocationsAreValid()); + LiveRange* query = TestRangeBuilder(zone()).Id(2).Build(1, 2); + ASSERT_TRUE(HasNoConflicts(query)); + query = TestRangeBuilder(zone()).Id(3).Build(1, 5); + ASSERT_TRUE(HasNoConflicts(query)); +} + + +TEST_F(CoalescedLiveRangesTest, CandidateBeforeAfterManyAllocations) { + LiveRange* range = + TestRangeBuilder(zone()).Id(1).Add(5, 7).Add(10, 12).Build(); + ranges().AllocateRange(range); + ASSERT_FALSE(ranges().empty()); + ASSERT_TRUE(AllocationsAreValid()); + LiveRange* query = + TestRangeBuilder(zone()).Id(2).Add(1, 2).Add(13, 15).Build(); + ASSERT_TRUE(HasNoConflicts(query)); + query = TestRangeBuilder(zone()).Id(3).Add(1, 5).Add(12, 15).Build(); + ASSERT_TRUE(HasNoConflicts(query)); +} + + +TEST_F(CoalescedLiveRangesTest, SelfConflictsPreciselyWithSelf) { + LiveRange* range = TestRangeBuilder(zone()).Id(1).Build(1, 5); + ranges().AllocateRange(range); + ASSERT_FALSE(ranges().empty()); + ASSERT_TRUE(AllocationsAreValid()); + ASSERT_TRUE(ConflictsPreciselyWith(range, 1)); + range = TestRangeBuilder(zone()).Id(2).Build(8, 10); + ranges().AllocateRange(range); + ASSERT_TRUE(ConflictsPreciselyWith(range, 2)); +} + + +TEST_F(CoalescedLiveRangesTest, QueryStartsBeforeConflict) { + LiveRange* range = TestRangeBuilder(zone()).Id(1).Build(2, 5); + ranges().AllocateRange(range); + LiveRange* query = TestRangeBuilder(zone()).Id(2).Build(1, 3); + ASSERT_TRUE(ConflictsPreciselyWith(query, 1)); + range = TestRangeBuilder(zone()).Id(3).Build(8, 10); + ranges().AllocateRange(range); + query = TestRangeBuilder(zone()).Id(4).Build(6, 9); + ASSERT_TRUE(ConflictsPreciselyWith(query, 3)); +} + + +TEST_F(CoalescedLiveRangesTest, QueryStartsInConflict) { + LiveRange* range = TestRangeBuilder(zone()).Id(1).Build(2, 5); + ranges().AllocateRange(range); + LiveRange* query = TestRangeBuilder(zone()).Id(2).Build(3, 6); + ASSERT_TRUE(ConflictsPreciselyWith(query, 1)); + range = TestRangeBuilder(zone()).Id(3).Build(8, 10); + ranges().AllocateRange(range); + query = TestRangeBuilder(zone()).Id(4).Build(9, 11); + ASSERT_TRUE(ConflictsPreciselyWith(query, 3)); +} + + +TEST_F(CoalescedLiveRangesTest, QueryContainedInConflict) { + LiveRange* range = TestRangeBuilder(zone()).Id(1).Build(1, 5); + ranges().AllocateRange(range); + LiveRange* query = TestRangeBuilder(zone()).Id(2).Build(2, 3); + ASSERT_TRUE(ConflictsPreciselyWith(query, 1)); +} + + +TEST_F(CoalescedLiveRangesTest, QueryContainsConflict) { + LiveRange* range = TestRangeBuilder(zone()).Id(1).Build(2, 3); + ranges().AllocateRange(range); + LiveRange* query = TestRangeBuilder(zone()).Id(2).Build(1, 5); + ASSERT_TRUE(ConflictsPreciselyWith(query, 1)); +} + + +TEST_F(CoalescedLiveRangesTest, QueryCoversManyIntervalsSameRange) { + LiveRange* range = + TestRangeBuilder(zone()).Id(1).Add(1, 5).Add(7, 9).Add(20, 25).Build(); + ranges().AllocateRange(range); + LiveRange* query = TestRangeBuilder(zone()).Id(2).Build(2, 8); + ASSERT_TRUE(ConflictsPreciselyWith(query, 1)); +} + + +TEST_F(CoalescedLiveRangesTest, QueryCoversManyIntervalsDifferentRanges) { + LiveRange* range = + TestRangeBuilder(zone()).Id(1).Add(1, 5).Add(20, 25).Build(); + ranges().AllocateRange(range); + range = TestRangeBuilder(zone()).Id(2).Build(7, 10); + ranges().AllocateRange(range); + LiveRange* query = TestRangeBuilder(zone()).Id(3).Build(2, 22); + ASSERT_TRUE(ConflictsPreciselyWith(query, 1, 2)); +} + + +TEST_F(CoalescedLiveRangesTest, QueryFitsInGaps) { + LiveRange* range = + TestRangeBuilder(zone()).Id(1).Add(1, 5).Add(10, 15).Add(20, 25).Build(); + ranges().AllocateRange(range); + LiveRange* query = + TestRangeBuilder(zone()).Id(3).Add(5, 10).Add(16, 19).Add(27, 30).Build(); + ASSERT_TRUE(HasNoConflicts(query)); +} + + +TEST_F(CoalescedLiveRangesTest, DeleteConflictBefore) { + LiveRange* range = TestRangeBuilder(zone()).Id(1).Add(1, 4).Add(5, 6).Build(); + ranges().AllocateRange(range); + range = TestRangeBuilder(zone()).Id(2).Build(40, 50); + ranges().AllocateRange(range); + LiveRange* query = TestRangeBuilder(zone()).Id(3).Build(3, 7); + RemoveConflicts(query); + query = TestRangeBuilder(zone()).Id(4).Build(0, 60); + ASSERT_TRUE(ConflictsPreciselyWith(query, 2)); +} + + +TEST_F(CoalescedLiveRangesTest, DeleteConflictAfter) { + LiveRange* range = TestRangeBuilder(zone()).Id(1).Build(1, 5); + ranges().AllocateRange(range); + range = TestRangeBuilder(zone()).Id(2).Add(40, 50).Add(60, 70).Build(); + ranges().AllocateRange(range); + LiveRange* query = TestRangeBuilder(zone()).Id(3).Build(45, 60); + RemoveConflicts(query); + query = TestRangeBuilder(zone()).Id(4).Build(0, 60); + ASSERT_TRUE(ConflictsPreciselyWith(query, 1)); +} + + +TEST_F(CoalescedLiveRangesTest, DeleteConflictStraddle) { + LiveRange* range = + TestRangeBuilder(zone()).Id(1).Add(1, 5).Add(10, 20).Build(); + ranges().AllocateRange(range); + range = TestRangeBuilder(zone()).Id(2).Build(40, 50); + ranges().AllocateRange(range); + LiveRange* query = TestRangeBuilder(zone()).Id(3).Build(4, 15); + RemoveConflicts(query); + query = TestRangeBuilder(zone()).Id(4).Build(0, 60); + ASSERT_TRUE(ConflictsPreciselyWith(query, 2)); +} + + +TEST_F(CoalescedLiveRangesTest, DeleteConflictManyOverlapsBefore) { + LiveRange* range = + TestRangeBuilder(zone()).Id(1).Add(1, 5).Add(6, 10).Add(10, 20).Build(); + ranges().AllocateRange(range); + range = TestRangeBuilder(zone()).Id(2).Build(40, 50); + ranges().AllocateRange(range); + LiveRange* query = TestRangeBuilder(zone()).Id(3).Build(4, 15); + RemoveConflicts(query); + query = TestRangeBuilder(zone()).Id(4).Build(0, 60); + ASSERT_TRUE(ConflictsPreciselyWith(query, 2)); +} + + +TEST_F(CoalescedLiveRangesTest, DeleteWhenConflictRepeatsAfterNonConflict) { + LiveRange* range = + TestRangeBuilder(zone()).Id(1).Add(1, 5).Add(6, 10).Add(20, 30).Build(); + ranges().AllocateRange(range); + range = TestRangeBuilder(zone()).Id(2).Build(12, 15); + ranges().AllocateRange(range); + LiveRange* query = + TestRangeBuilder(zone()).Id(3).Add(1, 8).Add(22, 25).Build(); + RemoveConflicts(query); + query = TestRangeBuilder(zone()).Id(4).Build(0, 60); + ASSERT_TRUE(ConflictsPreciselyWith(query, 2)); +} + + +} // namespace compiler +} // namespace internal +} // namespace v8 diff --git a/deps/v8/test/unittests/compiler/compiler-test-utils.h b/deps/v8/test/unittests/compiler/compiler-test-utils.h index 6ce28f9f94..7873c961b1 100644 --- a/deps/v8/test/unittests/compiler/compiler-test-utils.h +++ b/deps/v8/test/unittests/compiler/compiler-test-utils.h @@ -14,41 +14,25 @@ namespace compiler { // The TARGET_TEST(Case, Name) macro works just like // TEST(Case, Name), except that the test is disabled // if the platform is not a supported TurboFan target. -#if V8_TURBOFAN_TARGET #define TARGET_TEST(Case, Name) TEST(Case, Name) -#else -#define TARGET_TEST(Case, Name) TEST(Case, DISABLED_##Name) -#endif // The TARGET_TEST_F(Case, Name) macro works just like // TEST_F(Case, Name), except that the test is disabled // if the platform is not a supported TurboFan target. -#if V8_TURBOFAN_TARGET #define TARGET_TEST_F(Case, Name) TEST_F(Case, Name) -#else -#define TARGET_TEST_F(Case, Name) TEST_F(Case, DISABLED_##Name) -#endif // The TARGET_TEST_P(Case, Name) macro works just like // TEST_P(Case, Name), except that the test is disabled // if the platform is not a supported TurboFan target. -#if V8_TURBOFAN_TARGET #define TARGET_TEST_P(Case, Name) TEST_P(Case, Name) -#else -#define TARGET_TEST_P(Case, Name) TEST_P(Case, DISABLED_##Name) -#endif // The TARGET_TYPED_TEST(Case, Name) macro works just like // TYPED_TEST(Case, Name), except that the test is disabled // if the platform is not a supported TurboFan target. -#if V8_TURBOFAN_TARGET #define TARGET_TYPED_TEST(Case, Name) TYPED_TEST(Case, Name) -#else -#define TARGET_TYPED_TEST(Case, Name) TYPED_TEST(Case, DISABLED_##Name) -#endif } // namespace compiler } // namespace internal diff --git a/deps/v8/test/unittests/compiler/instruction-selector-unittest.cc b/deps/v8/test/unittests/compiler/instruction-selector-unittest.cc index acab91b009..1636b7ee5b 100644 --- a/deps/v8/test/unittests/compiler/instruction-selector-unittest.cc +++ b/deps/v8/test/unittests/compiler/instruction-selector-unittest.cc @@ -153,7 +153,7 @@ InstructionSelectorTest::StreamBuilder::GetFrameStateFunctionInfo( int parameter_count, int local_count) { return common()->CreateFrameStateFunctionInfo( FrameStateType::kJavaScriptFunction, parameter_count, local_count, - Handle<SharedFunctionInfo>()); + Handle<SharedFunctionInfo>(), CALL_MAINTAINS_NATIVE_CONTEXT); } diff --git a/deps/v8/test/unittests/compiler/instruction-selector-unittest.h b/deps/v8/test/unittests/compiler/instruction-selector-unittest.h index 15d3b2005f..574864edf5 100644 --- a/deps/v8/test/unittests/compiler/instruction-selector-unittest.h +++ b/deps/v8/test/unittests/compiler/instruction-selector-unittest.h @@ -39,22 +39,22 @@ class InstructionSelectorTest : public TestWithContext, StreamBuilder(InstructionSelectorTest* test, MachineType return_type) : RawMachineAssembler( test->isolate(), new (test->zone()) Graph(test->zone()), - MakeMachineSignature(test->zone(), return_type), kMachPtr, + MakeCallDescriptor(test->zone(), return_type), kMachPtr, MachineOperatorBuilder::kAllOptionalOps), test_(test) {} StreamBuilder(InstructionSelectorTest* test, MachineType return_type, MachineType parameter0_type) : RawMachineAssembler( test->isolate(), new (test->zone()) Graph(test->zone()), - MakeMachineSignature(test->zone(), return_type, parameter0_type), + MakeCallDescriptor(test->zone(), return_type, parameter0_type), kMachPtr, MachineOperatorBuilder::kAllOptionalOps), test_(test) {} StreamBuilder(InstructionSelectorTest* test, MachineType return_type, MachineType parameter0_type, MachineType parameter1_type) : RawMachineAssembler( test->isolate(), new (test->zone()) Graph(test->zone()), - MakeMachineSignature(test->zone(), return_type, parameter0_type, - parameter1_type), + MakeCallDescriptor(test->zone(), return_type, parameter0_type, + parameter1_type), kMachPtr, MachineOperatorBuilder::kAllOptionalOps), test_(test) {} StreamBuilder(InstructionSelectorTest* test, MachineType return_type, @@ -62,8 +62,8 @@ class InstructionSelectorTest : public TestWithContext, MachineType parameter2_type) : RawMachineAssembler( test->isolate(), new (test->zone()) Graph(test->zone()), - MakeMachineSignature(test->zone(), return_type, parameter0_type, - parameter1_type, parameter2_type), + MakeCallDescriptor(test->zone(), return_type, parameter0_type, + parameter1_type, parameter2_type), kMachPtr, MachineOperatorBuilder::kAllOptionalOps), test_(test) {} @@ -85,41 +85,40 @@ class InstructionSelectorTest : public TestWithContext, int local_count); private: - MachineSignature* MakeMachineSignature(Zone* zone, - MachineType return_type) { + CallDescriptor* MakeCallDescriptor(Zone* zone, MachineType return_type) { MachineSignature::Builder builder(zone, 1, 0); builder.AddReturn(return_type); - return builder.Build(); + return Linkage::GetSimplifiedCDescriptor(zone, builder.Build()); } - MachineSignature* MakeMachineSignature(Zone* zone, MachineType return_type, - MachineType parameter0_type) { + CallDescriptor* MakeCallDescriptor(Zone* zone, MachineType return_type, + MachineType parameter0_type) { MachineSignature::Builder builder(zone, 1, 1); builder.AddReturn(return_type); builder.AddParam(parameter0_type); - return builder.Build(); + return Linkage::GetSimplifiedCDescriptor(zone, builder.Build()); } - MachineSignature* MakeMachineSignature(Zone* zone, MachineType return_type, - MachineType parameter0_type, - MachineType parameter1_type) { + CallDescriptor* MakeCallDescriptor(Zone* zone, MachineType return_type, + MachineType parameter0_type, + MachineType parameter1_type) { MachineSignature::Builder builder(zone, 1, 2); builder.AddReturn(return_type); builder.AddParam(parameter0_type); builder.AddParam(parameter1_type); - return builder.Build(); + return Linkage::GetSimplifiedCDescriptor(zone, builder.Build()); } - MachineSignature* MakeMachineSignature(Zone* zone, MachineType return_type, - MachineType parameter0_type, - MachineType parameter1_type, - MachineType parameter2_type) { + CallDescriptor* MakeCallDescriptor(Zone* zone, MachineType return_type, + MachineType parameter0_type, + MachineType parameter1_type, + MachineType parameter2_type) { MachineSignature::Builder builder(zone, 1, 3); builder.AddReturn(return_type); builder.AddParam(parameter0_type); builder.AddParam(parameter1_type); builder.AddParam(parameter2_type); - return builder.Build(); + return Linkage::GetSimplifiedCDescriptor(zone, builder.Build()); } private: diff --git a/deps/v8/test/unittests/compiler/instruction-sequence-unittest.cc b/deps/v8/test/unittests/compiler/instruction-sequence-unittest.cc index 1ff441f746..65a7f299c5 100644 --- a/deps/v8/test/unittests/compiler/instruction-sequence-unittest.cc +++ b/deps/v8/test/unittests/compiler/instruction-sequence-unittest.cc @@ -93,9 +93,9 @@ void InstructionSequenceTest::EndLoop() { } -void InstructionSequenceTest::StartBlock() { +void InstructionSequenceTest::StartBlock(bool deferred) { block_returns_ = false; - NewBlock(); + NewBlock(deferred); } @@ -408,7 +408,7 @@ InstructionOperand InstructionSequenceTest::ConvertOutputOp(VReg vreg, } -InstructionBlock* InstructionSequenceTest::NewBlock() { +InstructionBlock* InstructionSequenceTest::NewBlock(bool deferred) { CHECK(current_block_ == nullptr); Rpo rpo = Rpo::FromInt(static_cast<int>(instruction_blocks_.size())); Rpo loop_header = Rpo::Invalid(); @@ -430,7 +430,7 @@ InstructionBlock* InstructionSequenceTest::NewBlock() { } // Construct instruction block. auto instruction_block = new (zone()) - InstructionBlock(zone(), rpo, loop_header, loop_end, false, false); + InstructionBlock(zone(), rpo, loop_header, loop_end, deferred, false); instruction_blocks_.push_back(instruction_block); current_block_ = instruction_block; sequence()->StartBlock(rpo); diff --git a/deps/v8/test/unittests/compiler/instruction-sequence-unittest.h b/deps/v8/test/unittests/compiler/instruction-sequence-unittest.h index 2d75da7e47..54317ede21 100644 --- a/deps/v8/test/unittests/compiler/instruction-sequence-unittest.h +++ b/deps/v8/test/unittests/compiler/instruction-sequence-unittest.h @@ -126,7 +126,7 @@ class InstructionSequenceTest : public TestWithIsolateAndZone { void StartLoop(int loop_blocks); void EndLoop(); - void StartBlock(); + void StartBlock(bool deferred = false); Instruction* EndBlock(BlockCompletion completion = FallThrough()); TestOperand Imm(int32_t imm = 0); @@ -203,7 +203,7 @@ class InstructionSequenceTest : public TestWithIsolateAndZone { InstructionOperand* ConvertInputs(size_t input_size, TestOperand* inputs); InstructionOperand ConvertInputOp(TestOperand op); InstructionOperand ConvertOutputOp(VReg vreg, TestOperand op); - InstructionBlock* NewBlock(); + InstructionBlock* NewBlock(bool deferred = false); void WireBlock(size_t block_offset, int jump_offset); Instruction* Emit(InstructionCode code, size_t outputs_size = 0, @@ -223,7 +223,7 @@ class InstructionSequenceTest : public TestWithIsolateAndZone { typedef std::map<int, const Instruction*> Instructions; typedef std::vector<BlockCompletion> Completions; - SmartPointer<RegisterConfiguration> config_; + base::SmartPointer<RegisterConfiguration> config_; InstructionSequence* sequence_; int num_general_registers_; int num_double_registers_; diff --git a/deps/v8/test/unittests/compiler/interpreter-assembler-unittest.cc b/deps/v8/test/unittests/compiler/interpreter-assembler-unittest.cc new file mode 100644 index 0000000000..a869f7ebb1 --- /dev/null +++ b/deps/v8/test/unittests/compiler/interpreter-assembler-unittest.cc @@ -0,0 +1,262 @@ +// Copyright 2015 the V8 project authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "test/unittests/compiler/interpreter-assembler-unittest.h" + +#include "src/compiler/graph.h" +#include "src/compiler/node.h" +#include "src/unique.h" +#include "test/unittests/compiler/compiler-test-utils.h" +#include "test/unittests/compiler/node-test-utils.h" + +using ::testing::_; + +namespace v8 { +namespace internal { +namespace compiler { + +const interpreter::Bytecode kBytecodes[] = { +#define DEFINE_BYTECODE(Name, ...) interpreter::Bytecode::k##Name, + BYTECODE_LIST(DEFINE_BYTECODE) +#undef DEFINE_BYTECODE +}; + + +Matcher<Node*> IsIntPtrAdd(const Matcher<Node*>& lhs_matcher, + const Matcher<Node*>& rhs_matcher) { + return kPointerSize == 8 ? IsInt64Add(lhs_matcher, rhs_matcher) + : IsInt32Add(lhs_matcher, rhs_matcher); +} + + +Matcher<Node*> IsIntPtrSub(const Matcher<Node*>& lhs_matcher, + const Matcher<Node*>& rhs_matcher) { + return kPointerSize == 8 ? IsInt64Sub(lhs_matcher, rhs_matcher) + : IsInt32Sub(lhs_matcher, rhs_matcher); +} + + +Matcher<Node*> IsWordShl(const Matcher<Node*>& lhs_matcher, + const Matcher<Node*>& rhs_matcher) { + return kPointerSize == 8 ? IsWord64Shl(lhs_matcher, rhs_matcher) + : IsWord32Shl(lhs_matcher, rhs_matcher); +} + + +Matcher<Node*> IsWordSar(const Matcher<Node*>& lhs_matcher, + const Matcher<Node*>& rhs_matcher) { + return kPointerSize == 8 ? IsWord64Sar(lhs_matcher, rhs_matcher) + : IsWord32Sar(lhs_matcher, rhs_matcher); +} + + +Matcher<Node*> InterpreterAssemblerTest::InterpreterAssemblerForTest::IsLoad( + const Matcher<LoadRepresentation>& rep_matcher, + const Matcher<Node*>& base_matcher, const Matcher<Node*>& index_matcher) { + return ::i::compiler::IsLoad(rep_matcher, base_matcher, index_matcher, + graph()->start(), graph()->start()); +} + + +Matcher<Node*> InterpreterAssemblerTest::InterpreterAssemblerForTest::IsStore( + const Matcher<StoreRepresentation>& rep_matcher, + const Matcher<Node*>& base_matcher, const Matcher<Node*>& index_matcher, + const Matcher<Node*>& value_matcher) { + return ::i::compiler::IsStore(rep_matcher, base_matcher, index_matcher, + value_matcher, graph()->start(), + graph()->start()); +} + + +Matcher<Node*> +InterpreterAssemblerTest::InterpreterAssemblerForTest::IsBytecodeOperand( + int operand) { + return IsLoad( + kMachUint8, IsParameter(Linkage::kInterpreterBytecodeArrayParameter), + IsIntPtrAdd(IsParameter(Linkage::kInterpreterBytecodeOffsetParameter), + IsInt32Constant(1 + operand))); +} + + +Matcher<Node*> InterpreterAssemblerTest::InterpreterAssemblerForTest:: + IsBytecodeOperandSignExtended(int operand) { + Matcher<Node*> load_matcher = IsLoad( + kMachInt8, IsParameter(Linkage::kInterpreterBytecodeArrayParameter), + IsIntPtrAdd(IsParameter(Linkage::kInterpreterBytecodeOffsetParameter), + IsInt32Constant(1 + operand))); + if (kPointerSize == 8) { + load_matcher = IsChangeInt32ToInt64(load_matcher); + } + return load_matcher; +} + + +Graph* +InterpreterAssemblerTest::InterpreterAssemblerForTest::GetCompletedGraph() { + End(); + return graph(); +} + + +TARGET_TEST_F(InterpreterAssemblerTest, Dispatch) { + TRACED_FOREACH(interpreter::Bytecode, bytecode, kBytecodes) { + InterpreterAssemblerForTest m(this, bytecode); + m.Dispatch(); + Graph* graph = m.GetCompletedGraph(); + + Node* end = graph->end(); + EXPECT_EQ(1, end->InputCount()); + Node* tail_call_node = end->InputAt(0); + + Matcher<Node*> next_bytecode_offset_matcher = + IsIntPtrAdd(IsParameter(Linkage::kInterpreterBytecodeOffsetParameter), + IsInt32Constant(interpreter::Bytecodes::Size(bytecode))); + Matcher<Node*> target_bytecode_matcher = m.IsLoad( + kMachUint8, IsParameter(Linkage::kInterpreterBytecodeArrayParameter), + next_bytecode_offset_matcher); + Matcher<Node*> code_target_matcher = m.IsLoad( + kMachPtr, IsParameter(Linkage::kInterpreterDispatchTableParameter), + IsWord32Shl(target_bytecode_matcher, + IsInt32Constant(kPointerSizeLog2))); + + EXPECT_EQ(CallDescriptor::kCallCodeObject, m.call_descriptor()->kind()); + EXPECT_TRUE(m.call_descriptor()->flags() & CallDescriptor::kCanUseRoots); + EXPECT_THAT( + tail_call_node, + IsTailCall(m.call_descriptor(), code_target_matcher, + IsParameter(Linkage::kInterpreterAccumulatorParameter), + IsParameter(Linkage::kInterpreterRegisterFileParameter), + next_bytecode_offset_matcher, + IsParameter(Linkage::kInterpreterBytecodeArrayParameter), + IsParameter(Linkage::kInterpreterDispatchTableParameter), + graph->start(), graph->start())); + } +} + + +TARGET_TEST_F(InterpreterAssemblerTest, Return) { + TRACED_FOREACH(interpreter::Bytecode, bytecode, kBytecodes) { + InterpreterAssemblerForTest m(this, bytecode); + m.Return(); + Graph* graph = m.GetCompletedGraph(); + + Node* end = graph->end(); + EXPECT_EQ(1, end->InputCount()); + Node* tail_call_node = end->InputAt(0); + + EXPECT_EQ(CallDescriptor::kCallCodeObject, m.call_descriptor()->kind()); + EXPECT_TRUE(m.call_descriptor()->flags() & CallDescriptor::kCanUseRoots); + Matcher<Unique<HeapObject>> exit_trampoline( + Unique<HeapObject>::CreateImmovable( + isolate()->builtins()->InterpreterExitTrampoline())); + EXPECT_THAT( + tail_call_node, + IsTailCall(m.call_descriptor(), IsHeapConstant(exit_trampoline), + IsParameter(Linkage::kInterpreterAccumulatorParameter), + IsParameter(Linkage::kInterpreterRegisterFileParameter), + IsParameter(Linkage::kInterpreterBytecodeOffsetParameter), + IsParameter(Linkage::kInterpreterBytecodeArrayParameter), + IsParameter(Linkage::kInterpreterDispatchTableParameter), + graph->start(), graph->start())); + } +} + + +TARGET_TEST_F(InterpreterAssemblerTest, BytecodeOperand) { + TRACED_FOREACH(interpreter::Bytecode, bytecode, kBytecodes) { + InterpreterAssemblerForTest m(this, bytecode); + int number_of_operands = interpreter::Bytecodes::NumberOfOperands(bytecode); + for (int i = 0; i < number_of_operands; i++) { + switch (interpreter::Bytecodes::GetOperandType(bytecode, i)) { + case interpreter::OperandType::kImm8: + EXPECT_THAT(m.BytecodeOperandImm8(i), + m.IsBytecodeOperandSignExtended(i)); + break; + case interpreter::OperandType::kReg: + EXPECT_THAT(m.BytecodeOperandReg(i), + m.IsBytecodeOperandSignExtended(i)); + break; + case interpreter::OperandType::kNone: + UNREACHABLE(); + break; + } + } + } +} + + +TARGET_TEST_F(InterpreterAssemblerTest, GetSetAccumulator) { + TRACED_FOREACH(interpreter::Bytecode, bytecode, kBytecodes) { + InterpreterAssemblerForTest m(this, bytecode); + // Should be incoming accumulator if not set. + EXPECT_THAT(m.GetAccumulator(), + IsParameter(Linkage::kInterpreterAccumulatorParameter)); + + // Should be set by SedtAccumulator. + Node* accumulator_value_1 = m.Int32Constant(0xdeadbeef); + m.SetAccumulator(accumulator_value_1); + EXPECT_THAT(m.GetAccumulator(), accumulator_value_1); + Node* accumulator_value_2 = m.Int32Constant(42); + m.SetAccumulator(accumulator_value_2); + EXPECT_THAT(m.GetAccumulator(), accumulator_value_2); + + // Should be passed to next bytecode handler on dispatch. + m.Dispatch(); + Graph* graph = m.GetCompletedGraph(); + + Node* end = graph->end(); + EXPECT_EQ(1, end->InputCount()); + Node* tail_call_node = end->InputAt(0); + + EXPECT_THAT(tail_call_node, + IsTailCall(m.call_descriptor(), _, accumulator_value_2, _, _, _, + _, graph->start(), graph->start())); + } +} + + +TARGET_TEST_F(InterpreterAssemblerTest, LoadRegister) { + TRACED_FOREACH(interpreter::Bytecode, bytecode, kBytecodes) { + InterpreterAssemblerForTest m(this, bytecode); + Node* reg_index_node = m.Int32Constant(44); + Node* load_reg_node = m.LoadRegister(reg_index_node); + EXPECT_THAT( + load_reg_node, + m.IsLoad(kMachPtr, + IsParameter(Linkage::kInterpreterRegisterFileParameter), + IsWordShl(reg_index_node, IsInt32Constant(kPointerSizeLog2)))); + } +} + + +TARGET_TEST_F(InterpreterAssemblerTest, StoreRegister) { + TRACED_FOREACH(interpreter::Bytecode, bytecode, kBytecodes) { + InterpreterAssemblerForTest m(this, bytecode); + Node* store_value = m.Int32Constant(0xdeadbeef); + Node* reg_index_node = m.Int32Constant(44); + Node* store_reg_node = m.StoreRegister(store_value, reg_index_node); + EXPECT_THAT( + store_reg_node, + m.IsStore(StoreRepresentation(kMachPtr, kNoWriteBarrier), + IsParameter(Linkage::kInterpreterRegisterFileParameter), + IsWordShl(reg_index_node, IsInt32Constant(kPointerSizeLog2)), + store_value)); + } +} + + +TARGET_TEST_F(InterpreterAssemblerTest, SmiTag) { + TRACED_FOREACH(interpreter::Bytecode, bytecode, kBytecodes) { + InterpreterAssemblerForTest m(this, bytecode); + Node* value = m.Int32Constant(44); + EXPECT_THAT(m.SmiTag(value), + IsWordShl(value, IsInt32Constant(kSmiShiftSize + kSmiTagSize))); + EXPECT_THAT(m.SmiUntag(value), + IsWordSar(value, IsInt32Constant(kSmiShiftSize + kSmiTagSize))); + } +} + +} // namespace compiler +} // namespace internal +} // namespace v8 diff --git a/deps/v8/test/unittests/compiler/interpreter-assembler-unittest.h b/deps/v8/test/unittests/compiler/interpreter-assembler-unittest.h new file mode 100644 index 0000000000..64353ae128 --- /dev/null +++ b/deps/v8/test/unittests/compiler/interpreter-assembler-unittest.h @@ -0,0 +1,56 @@ +// Copyright 2015 the V8 project authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef V8_UNITTESTS_COMPILER_INTERPRETER_ASSEMBLER_UNITTEST_H_ +#define V8_UNITTESTS_COMPILER_INTERPRETER_ASSEMBLER_UNITTEST_H_ + +#include "src/compiler/interpreter-assembler.h" +#include "src/compiler/linkage.h" +#include "src/compiler/machine-operator.h" +#include "test/unittests/test-utils.h" +#include "testing/gmock-support.h" + +namespace v8 { +namespace internal { +namespace compiler { + +using ::testing::Matcher; + +class InterpreterAssemblerTest : public TestWithIsolateAndZone { + public: + InterpreterAssemblerTest() {} + ~InterpreterAssemblerTest() override {} + + class InterpreterAssemblerForTest final : public InterpreterAssembler { + public: + InterpreterAssemblerForTest(InterpreterAssemblerTest* test, + interpreter::Bytecode bytecode) + : InterpreterAssembler(test->isolate(), test->zone(), bytecode) {} + ~InterpreterAssemblerForTest() override {} + + Graph* GetCompletedGraph(); + + Matcher<Node*> IsLoad(const Matcher<LoadRepresentation>& rep_matcher, + const Matcher<Node*>& base_matcher, + const Matcher<Node*>& index_matcher); + Matcher<Node*> IsStore(const Matcher<StoreRepresentation>& rep_matcher, + const Matcher<Node*>& base_matcher, + const Matcher<Node*>& index_matcher, + const Matcher<Node*>& value_matcher); + Matcher<Node*> IsBytecodeOperand(int operand); + Matcher<Node*> IsBytecodeOperandSignExtended(int operand); + + using InterpreterAssembler::call_descriptor; + using InterpreterAssembler::graph; + + private: + DISALLOW_COPY_AND_ASSIGN(InterpreterAssemblerForTest); + }; +}; + +} // namespace compiler +} // namespace internal +} // namespace v8 + +#endif // V8_UNITTESTS_COMPILER_INTERPRETER_ASSEMBLER_UNITTEST_H_ diff --git a/deps/v8/test/unittests/compiler/js-context-relaxation-unittest.cc b/deps/v8/test/unittests/compiler/js-context-relaxation-unittest.cc new file mode 100644 index 0000000000..b52417de2f --- /dev/null +++ b/deps/v8/test/unittests/compiler/js-context-relaxation-unittest.cc @@ -0,0 +1,306 @@ +// Copyright 2015 the V8 project authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "src/compiler/js-context-relaxation.h" +#include "src/compiler/js-graph.h" +#include "test/unittests/compiler/graph-unittest.h" +#include "test/unittests/compiler/node-test-utils.h" + +namespace v8 { +namespace internal { +namespace compiler { + +class JSContextRelaxationTest : public GraphTest { + public: + JSContextRelaxationTest() : GraphTest(3), javascript_(zone()) {} + ~JSContextRelaxationTest() override {} + + protected: + Reduction Reduce(Node* node, MachineOperatorBuilder::Flags flags = + MachineOperatorBuilder::kNoFlags) { + MachineOperatorBuilder machine(zone(), kMachPtr, flags); + JSGraph jsgraph(isolate(), graph(), common(), javascript(), &machine); + // TODO(titzer): mock the GraphReducer here for better unit testing. + GraphReducer graph_reducer(zone(), graph()); + JSContextRelaxation reducer; + return reducer.Reduce(node); + } + + Node* EmptyFrameState() { + MachineOperatorBuilder machine(zone()); + JSGraph jsgraph(isolate(), graph(), common(), javascript(), &machine); + return jsgraph.EmptyFrameState(); + } + + Node* ShallowFrameStateChain(Node* outer_context, + ContextCallingMode context_calling_mode) { + const FrameStateFunctionInfo* const frame_state_function_info = + common()->CreateFrameStateFunctionInfo( + FrameStateType::kJavaScriptFunction, 3, 0, + Handle<SharedFunctionInfo>(), context_calling_mode); + const Operator* op = common()->FrameState(BailoutId::None(), + OutputFrameStateCombine::Ignore(), + frame_state_function_info); + return graph()->NewNode(op, graph()->start(), graph()->start(), + graph()->start(), outer_context, graph()->start(), + graph()->start()); + } + + Node* DeepFrameStateChain(Node* outer_context, + ContextCallingMode context_calling_mode) { + const FrameStateFunctionInfo* const frame_state_function_info = + common()->CreateFrameStateFunctionInfo( + FrameStateType::kJavaScriptFunction, 3, 0, + Handle<SharedFunctionInfo>(), context_calling_mode); + const Operator* op = common()->FrameState(BailoutId::None(), + OutputFrameStateCombine::Ignore(), + frame_state_function_info); + Node* shallow_frame_state = + ShallowFrameStateChain(outer_context, CALL_MAINTAINS_NATIVE_CONTEXT); + return graph()->NewNode(op, graph()->start(), graph()->start(), + graph()->start(), graph()->start(), + graph()->start(), shallow_frame_state); + } + + JSOperatorBuilder* javascript() { return &javascript_; } + + private: + JSOperatorBuilder javascript_; +}; + + +TEST_F(JSContextRelaxationTest, + RelaxJSCallFunctionShallowFrameStateChainNoCrossCtx) { + Node* const input0 = Parameter(0); + Node* const input1 = Parameter(1); + Node* const context = Parameter(2); + Node* const outer_context = Parameter(3); + Node* const frame_state = + ShallowFrameStateChain(outer_context, CALL_MAINTAINS_NATIVE_CONTEXT); + Node* const effect = graph()->start(); + Node* const control = graph()->start(); + Node* node = + graph()->NewNode(javascript()->CallFunction(2, NO_CALL_FUNCTION_FLAGS, + STRICT, VectorSlotPair()), + input0, input1, context, frame_state, effect, control); + Reduction const r = Reduce(node); + EXPECT_TRUE(r.Changed()); + EXPECT_EQ(outer_context, NodeProperties::GetContextInput(node)); +} + +TEST_F(JSContextRelaxationTest, + RelaxJSCallFunctionShallowFrameStateChainCrossCtx) { + Node* const input0 = Parameter(0); + Node* const input1 = Parameter(1); + Node* const context = Parameter(2); + Node* const outer_context = Parameter(3); + Node* const frame_state = + ShallowFrameStateChain(outer_context, CALL_CHANGES_NATIVE_CONTEXT); + Node* const effect = graph()->start(); + Node* const control = graph()->start(); + Node* node = + graph()->NewNode(javascript()->CallFunction(2, NO_CALL_FUNCTION_FLAGS, + STRICT, VectorSlotPair()), + input0, input1, context, frame_state, effect, control); + Reduction const r = Reduce(node); + EXPECT_FALSE(r.Changed()); + EXPECT_EQ(context, NodeProperties::GetContextInput(node)); +} + +TEST_F(JSContextRelaxationTest, + RelaxJSCallFunctionDeepFrameStateChainNoCrossCtx) { + Node* const input0 = Parameter(0); + Node* const input1 = Parameter(1); + Node* const context = Parameter(2); + Node* const outer_context = Parameter(3); + Node* const frame_state = + DeepFrameStateChain(outer_context, CALL_MAINTAINS_NATIVE_CONTEXT); + Node* const effect = graph()->start(); + Node* const control = graph()->start(); + Node* node = + graph()->NewNode(javascript()->CallFunction(2, NO_CALL_FUNCTION_FLAGS, + STRICT, VectorSlotPair()), + input0, input1, context, frame_state, effect, control); + Reduction const r = Reduce(node); + EXPECT_TRUE(r.Changed()); + EXPECT_EQ(outer_context, NodeProperties::GetContextInput(node)); +} + +TEST_F(JSContextRelaxationTest, + RelaxJSCallFunctionDeepFrameStateChainCrossCtx) { + Node* const input0 = Parameter(0); + Node* const input1 = Parameter(1); + Node* const context = Parameter(2); + Node* const outer_context = Parameter(3); + Node* const frame_state = + DeepFrameStateChain(outer_context, CALL_CHANGES_NATIVE_CONTEXT); + Node* const effect = graph()->start(); + Node* const control = graph()->start(); + Node* node = + graph()->NewNode(javascript()->CallFunction(2, NO_CALL_FUNCTION_FLAGS, + STRICT, VectorSlotPair()), + input0, input1, context, frame_state, effect, control); + Reduction const r = Reduce(node); + EXPECT_FALSE(r.Changed()); + EXPECT_EQ(context, NodeProperties::GetContextInput(node)); +} + +TEST_F(JSContextRelaxationTest, + RelaxJSCallFunctionDeepContextChainFullRelaxForCatch) { + Node* const input0 = Parameter(0); + Node* const input1 = Parameter(1); + Node* const context = Parameter(2); + Node* const outer_context = Parameter(3); + const Operator* op = javascript()->CreateCatchContext(Unique<String>()); + Node* const frame_state_1 = + ShallowFrameStateChain(outer_context, CALL_MAINTAINS_NATIVE_CONTEXT); + Node* const effect = graph()->start(); + Node* const control = graph()->start(); + Node* nested_context = + graph()->NewNode(op, graph()->start(), graph()->start(), outer_context, + frame_state_1, effect, control); + Node* const frame_state_2 = + ShallowFrameStateChain(nested_context, CALL_MAINTAINS_NATIVE_CONTEXT); + Node* node = + graph()->NewNode(javascript()->CallFunction(2, NO_CALL_FUNCTION_FLAGS, + STRICT, VectorSlotPair()), + input0, input1, context, frame_state_2, effect, control); + Reduction const r = Reduce(node); + EXPECT_TRUE(r.Changed()); + EXPECT_EQ(outer_context, NodeProperties::GetContextInput(node)); +} + + +TEST_F(JSContextRelaxationTest, + RelaxJSCallFunctionDeepContextChainFullRelaxForWith) { + Node* const input0 = Parameter(0); + Node* const input1 = Parameter(1); + Node* const context = Parameter(2); + Node* const outer_context = Parameter(3); + const Operator* op = javascript()->CreateWithContext(); + Node* const frame_state_1 = + ShallowFrameStateChain(outer_context, CALL_MAINTAINS_NATIVE_CONTEXT); + Node* const effect = graph()->start(); + Node* const control = graph()->start(); + Node* nested_context = + graph()->NewNode(op, graph()->start(), graph()->start(), outer_context, + frame_state_1, effect, control); + Node* const frame_state_2 = + ShallowFrameStateChain(nested_context, CALL_MAINTAINS_NATIVE_CONTEXT); + Node* node = + graph()->NewNode(javascript()->CallFunction(2, NO_CALL_FUNCTION_FLAGS, + STRICT, VectorSlotPair()), + input0, input1, context, frame_state_2, effect, control); + Reduction const r = Reduce(node); + EXPECT_TRUE(r.Changed()); + EXPECT_EQ(outer_context, NodeProperties::GetContextInput(node)); +} + + +TEST_F(JSContextRelaxationTest, + RelaxJSCallFunctionDeepContextChainFullRelaxForBlock) { + Node* const input0 = Parameter(0); + Node* const input1 = Parameter(1); + Node* const context = Parameter(2); + Node* const outer_context = Parameter(3); + const Operator* op = javascript()->CreateBlockContext(); + Node* const frame_state_1 = + ShallowFrameStateChain(outer_context, CALL_MAINTAINS_NATIVE_CONTEXT); + Node* const effect = graph()->start(); + Node* const control = graph()->start(); + Node* nested_context = + graph()->NewNode(op, graph()->start(), graph()->start(), outer_context, + frame_state_1, effect, control); + Node* const frame_state_2 = + ShallowFrameStateChain(nested_context, CALL_MAINTAINS_NATIVE_CONTEXT); + Node* node = + graph()->NewNode(javascript()->CallFunction(2, NO_CALL_FUNCTION_FLAGS, + STRICT, VectorSlotPair()), + input0, input1, context, frame_state_2, effect, control); + Reduction const r = Reduce(node); + EXPECT_TRUE(r.Changed()); + EXPECT_EQ(outer_context, NodeProperties::GetContextInput(node)); +} + + +TEST_F(JSContextRelaxationTest, + RelaxJSCallFunctionDeepContextChainPartialRelaxForScript) { + Node* const input0 = Parameter(0); + Node* const input1 = Parameter(1); + Node* const context = Parameter(2); + Node* const outer_context = Parameter(3); + const Operator* op = javascript()->CreateScriptContext(); + Node* const frame_state_1 = + ShallowFrameStateChain(outer_context, CALL_MAINTAINS_NATIVE_CONTEXT); + Node* const effect = graph()->start(); + Node* const control = graph()->start(); + Node* nested_context = + graph()->NewNode(op, graph()->start(), graph()->start(), outer_context, + frame_state_1, effect, control); + Node* const frame_state_2 = + ShallowFrameStateChain(nested_context, CALL_MAINTAINS_NATIVE_CONTEXT); + Node* node = + graph()->NewNode(javascript()->CallFunction(2, NO_CALL_FUNCTION_FLAGS, + STRICT, VectorSlotPair()), + input0, input1, context, frame_state_2, effect, control); + Reduction const r = Reduce(node); + EXPECT_TRUE(r.Changed()); + EXPECT_EQ(nested_context, NodeProperties::GetContextInput(node)); +} + + +TEST_F(JSContextRelaxationTest, + RelaxJSCallFunctionDeepContextChainPartialRelaxForModule) { + Node* const input0 = Parameter(0); + Node* const input1 = Parameter(1); + Node* const context = Parameter(2); + Node* const outer_context = Parameter(3); + const Operator* op = javascript()->CreateModuleContext(); + Node* const frame_state_1 = + ShallowFrameStateChain(outer_context, CALL_MAINTAINS_NATIVE_CONTEXT); + Node* const effect = graph()->start(); + Node* const control = graph()->start(); + Node* nested_context = + graph()->NewNode(op, graph()->start(), graph()->start(), outer_context, + frame_state_1, effect, control); + Node* const frame_state_2 = + ShallowFrameStateChain(nested_context, CALL_MAINTAINS_NATIVE_CONTEXT); + Node* node = + graph()->NewNode(javascript()->CallFunction(2, NO_CALL_FUNCTION_FLAGS, + STRICT, VectorSlotPair()), + input0, input1, context, frame_state_2, effect, control); + Reduction const r = Reduce(node); + EXPECT_TRUE(r.Changed()); + EXPECT_EQ(nested_context, NodeProperties::GetContextInput(node)); +} + + +TEST_F(JSContextRelaxationTest, + RelaxJSCallFunctionDeepContextChainPartialNoRelax) { + Node* const input0 = Parameter(0); + Node* const input1 = Parameter(1); + Node* const context = Parameter(2); + Node* const outer_context = Parameter(3); + const Operator* op = javascript()->CreateFunctionContext(); + Node* const frame_state_1 = + ShallowFrameStateChain(outer_context, CALL_MAINTAINS_NATIVE_CONTEXT); + Node* const effect = graph()->start(); + Node* const control = graph()->start(); + Node* nested_context = + graph()->NewNode(op, graph()->start(), graph()->start(), outer_context, + frame_state_1, effect, control); + Node* const frame_state_2 = + ShallowFrameStateChain(nested_context, CALL_MAINTAINS_NATIVE_CONTEXT); + Node* node = + graph()->NewNode(javascript()->CallFunction(2, NO_CALL_FUNCTION_FLAGS, + STRICT, VectorSlotPair()), + input0, input1, context, frame_state_2, effect, control); + Reduction const r = Reduce(node); + EXPECT_FALSE(r.Changed()); + EXPECT_EQ(context, NodeProperties::GetContextInput(node)); +} + +} // namespace compiler +} // namespace internal +} // namespace v8 diff --git a/deps/v8/test/unittests/compiler/js-type-feedback-unittest.cc b/deps/v8/test/unittests/compiler/js-type-feedback-unittest.cc index d52242ec7d..251293ddcf 100644 --- a/deps/v8/test/unittests/compiler/js-type-feedback-unittest.cc +++ b/deps/v8/test/unittests/compiler/js-type-feedback-unittest.cc @@ -85,7 +85,7 @@ class JSTypeFeedbackTest : public TypedGraphTest { Unique<Name> name = Unique<Name>::CreateUninitialized( isolate()->factory()->InternalizeUtf8String(string)); const Operator* op = javascript()->LoadGlobal(name, feedback); - Node* load = graph()->NewNode(op, global, vector, context); + Node* load = graph()->NewNode(op, context, global, vector, context); if (mode == JSTypeFeedbackSpecializer::kDeoptimizationEnabled) { for (int i = 0; i < OperatorProperties::GetFrameStateInputCount(op); i++) { diff --git a/deps/v8/test/unittests/compiler/js-typed-lowering-unittest.cc b/deps/v8/test/unittests/compiler/js-typed-lowering-unittest.cc index a12d79f02b..9d6cca3dbc 100644 --- a/deps/v8/test/unittests/compiler/js-typed-lowering-unittest.cc +++ b/deps/v8/test/unittests/compiler/js-typed-lowering-unittest.cc @@ -874,7 +874,11 @@ TEST_F(JSTypedLoweringTest, JSStorePropertyToExternalTypedArrayWithSafeKey) { } -TEST_F(JSTypedLoweringTest, JSLoadNamedGlobalConstants) { +// ----------------------------------------------------------------------------- +// JSLoadGlobal + + +TEST_F(JSTypedLoweringTest, JSLoadGlobalConstants) { Handle<String> names[] = { Handle<String>(isolate()->heap()->undefined_string(), isolate()), Handle<String>(isolate()->heap()->infinity_string(), isolate()), @@ -897,8 +901,8 @@ TEST_F(JSTypedLoweringTest, JSLoadNamedGlobalConstants) { for (size_t i = 0; i < arraysize(names); i++) { Unique<Name> name = Unique<Name>::CreateImmovable(names[i]); Reduction r = Reduce(graph()->NewNode( - javascript()->LoadGlobal(name, feedback), global, vector, context, - EmptyFrameState(), EmptyFrameState(), effect, control)); + javascript()->LoadGlobal(name, feedback), context, global, vector, + context, EmptyFrameState(), EmptyFrameState(), effect, control)); ASSERT_TRUE(r.Changed()); EXPECT_THAT(r.replacement(), matches[i]); @@ -907,6 +911,31 @@ TEST_F(JSTypedLoweringTest, JSLoadNamedGlobalConstants) { // ----------------------------------------------------------------------------- +// JSLoadNamed + + +TEST_F(JSTypedLoweringTest, JSLoadNamedStringLength) { + VectorSlotPair feedback; + Unique<Name> name = Unique<Name>::CreateImmovable(factory()->length_string()); + Node* const receiver = Parameter(Type::String(), 0); + Node* const vector = Parameter(Type::Internal(), 1); + Node* const context = UndefinedConstant(); + Node* const effect = graph()->start(); + Node* const control = graph()->start(); + TRACED_FOREACH(LanguageMode, language_mode, kLanguageModes) { + Reduction const r = Reduce( + graph()->NewNode(javascript()->LoadNamed(name, feedback, language_mode), + receiver, vector, context, EmptyFrameState(), + EmptyFrameState(), effect, control)); + ASSERT_TRUE(r.Changed()); + EXPECT_THAT(r.replacement(), + IsLoadField(AccessBuilder::ForStringLength(zone()), receiver, + effect, control)); + } +} + + +// ----------------------------------------------------------------------------- // JSLoadDynamicGlobal @@ -921,7 +950,8 @@ TEST_F(JSTypedLoweringTest, JSLoadDynamicGlobal) { for (int i = 0; i < DynamicGlobalAccess::kMaxCheckDepth; ++i) { uint32_t bitset = 1 << i; // Only single check. Reduction r = Reduce(graph()->NewNode( - javascript()->LoadDynamicGlobal(name, bitset, feedback, NOT_CONTEXTUAL), + javascript()->LoadDynamicGlobal(name, bitset, feedback, + NOT_INSIDE_TYPEOF), vector, context, context, frame_state, frame_state, effect, control)); ASSERT_TRUE(r.Changed()); EXPECT_THAT( @@ -974,7 +1004,6 @@ TEST_F(JSTypedLoweringTest, JSLoadDynamicContext) { } } -#if V8_TURBOFAN_TARGET // ----------------------------------------------------------------------------- // JSAdd @@ -1074,8 +1103,6 @@ TEST_F(JSTypedLoweringTest, JSCreateLiteralObject) { input0, input1, input2, _, context, frame_state, effect, control)); } -#endif // V8_TURBOFAN_TARGET - // ----------------------------------------------------------------------------- // JSCreateWithContext diff --git a/deps/v8/test/unittests/compiler/linkage-tail-call-unittest.cc b/deps/v8/test/unittests/compiler/linkage-tail-call-unittest.cc new file mode 100644 index 0000000000..5d24a3bd1d --- /dev/null +++ b/deps/v8/test/unittests/compiler/linkage-tail-call-unittest.cc @@ -0,0 +1,324 @@ +// Copyright 2014 the V8 project authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "src/compiler/common-operator.h" +#include "src/compiler/graph.h" +#include "src/compiler/linkage.h" +#include "src/compiler/node.h" +#include "test/unittests/test-utils.h" + +namespace v8 { +namespace internal { +namespace compiler { + +namespace { + +MachineType kMachineTypes[] = {kMachAnyTagged, kMachAnyTagged, kMachAnyTagged, + kMachAnyTagged, kMachAnyTagged, kMachAnyTagged, + kMachAnyTagged, kMachAnyTagged}; +} + +class LinkageTailCall : public TestWithZone { + protected: + CallDescriptor* NewStandardCallDescriptor(LocationSignature* locations) { + DCHECK(arraysize(kMachineTypes) >= + locations->return_count() + locations->parameter_count()); + MachineSignature* types = new (zone()) MachineSignature( + locations->return_count(), locations->parameter_count(), kMachineTypes); + return new (zone()) + CallDescriptor(CallDescriptor::kCallCodeObject, kMachAnyTagged, + LinkageLocation::ForAnyRegister(), + types, // machine_sig + locations, // location_sig + 0, // js_parameter_count + Operator::kNoProperties, // properties + 0, // callee-saved + 0, // callee-saved fp + CallDescriptor::kNoFlags, // flags, + ""); + } + + LinkageLocation StackLocation(int loc) { + return LinkageLocation::ForCallerFrameSlot(-loc); + } + + LinkageLocation RegisterLocation(int loc) { + return LinkageLocation::ForRegister(loc); + } +}; + + +TEST_F(LinkageTailCall, EmptyToEmpty) { + LocationSignature locations(0, 0, nullptr); + CallDescriptor* desc = NewStandardCallDescriptor(&locations); + CommonOperatorBuilder common(zone()); + const Operator* op = common.Call(desc); + Node* const node = Node::New(zone(), 1, op, 0, nullptr, false); + EXPECT_TRUE(desc->CanTailCall(node)); +} + + +TEST_F(LinkageTailCall, SameReturn) { + // Caller + LinkageLocation location_array[] = {RegisterLocation(0)}; + LocationSignature locations1(1, 0, location_array); + CallDescriptor* desc1 = NewStandardCallDescriptor(&locations1); + + // Callee + CallDescriptor* desc2 = NewStandardCallDescriptor(&locations1); + + CommonOperatorBuilder common(zone()); + const Operator* op = common.Call(desc2); + Node* const node = Node::New(zone(), 1, op, 0, nullptr, false); + EXPECT_TRUE(desc1->CanTailCall(node)); +} + + +TEST_F(LinkageTailCall, DifferingReturn) { + // Caller + LinkageLocation location_array1[] = {RegisterLocation(0)}; + LocationSignature locations1(1, 0, location_array1); + CallDescriptor* desc1 = NewStandardCallDescriptor(&locations1); + + // Callee + LinkageLocation location_array2[] = {RegisterLocation(1)}; + LocationSignature locations2(1, 0, location_array2); + CallDescriptor* desc2 = NewStandardCallDescriptor(&locations2); + + CommonOperatorBuilder common(zone()); + const Operator* op = common.Call(desc2); + Node* const node = Node::New(zone(), 1, op, 0, nullptr, false); + EXPECT_FALSE(desc1->CanTailCall(node)); +} + + +TEST_F(LinkageTailCall, MoreRegisterParametersCallee) { + // Caller + LinkageLocation location_array1[] = {RegisterLocation(0)}; + LocationSignature locations1(1, 0, location_array1); + CallDescriptor* desc1 = NewStandardCallDescriptor(&locations1); + + // Callee + LinkageLocation location_array2[] = {RegisterLocation(0), + RegisterLocation(0)}; + LocationSignature locations2(1, 1, location_array2); + CallDescriptor* desc2 = NewStandardCallDescriptor(&locations2); + + CommonOperatorBuilder common(zone()); + const Operator* op = common.Call(desc2); + Node* const node = Node::New(zone(), 1, op, 0, nullptr, false); + EXPECT_TRUE(desc1->CanTailCall(node)); +} + + +TEST_F(LinkageTailCall, MoreRegisterParametersCaller) { + // Caller + LinkageLocation location_array1[] = {RegisterLocation(0), + RegisterLocation(0)}; + LocationSignature locations1(1, 1, location_array1); + CallDescriptor* desc1 = NewStandardCallDescriptor(&locations1); + + // Callee + LinkageLocation location_array2[] = {RegisterLocation(0)}; + LocationSignature locations2(1, 0, location_array2); + CallDescriptor* desc2 = NewStandardCallDescriptor(&locations2); + + CommonOperatorBuilder common(zone()); + const Operator* op = common.Call(desc2); + Node* const node = Node::New(zone(), 1, op, 0, nullptr, false); + EXPECT_TRUE(desc1->CanTailCall(node)); +} + + +TEST_F(LinkageTailCall, MoreRegisterAndStackParametersCallee) { + // Caller + LinkageLocation location_array1[] = {RegisterLocation(0)}; + LocationSignature locations1(1, 0, location_array1); + CallDescriptor* desc1 = NewStandardCallDescriptor(&locations1); + + // Callee + LinkageLocation location_array2[] = {RegisterLocation(0), RegisterLocation(0), + RegisterLocation(1), StackLocation(1)}; + LocationSignature locations2(1, 3, location_array2); + CallDescriptor* desc2 = NewStandardCallDescriptor(&locations2); + + CommonOperatorBuilder common(zone()); + const Operator* op = common.Call(desc2); + Node* const node = Node::New(zone(), 1, op, 0, nullptr, false); + EXPECT_FALSE(desc1->CanTailCall(node)); +} + + +TEST_F(LinkageTailCall, MoreRegisterAndStackParametersCaller) { + // Caller + LinkageLocation location_array[] = {RegisterLocation(0), RegisterLocation(0), + RegisterLocation(1), StackLocation(1)}; + LocationSignature locations1(1, 3, location_array); + CallDescriptor* desc1 = NewStandardCallDescriptor(&locations1); + + // Callee + LinkageLocation location_array2[] = {RegisterLocation(0)}; + LocationSignature locations2(1, 0, location_array2); + CallDescriptor* desc2 = NewStandardCallDescriptor(&locations2); + + CommonOperatorBuilder common(zone()); + const Operator* op = common.Call(desc2); + Node* const node = Node::New(zone(), 1, op, 0, nullptr, false); + EXPECT_FALSE(desc1->CanTailCall(node)); +} + + +TEST_F(LinkageTailCall, MatchingStackParameters) { + // Caller + LinkageLocation location_array[] = {RegisterLocation(0), StackLocation(3), + StackLocation(2), StackLocation(1)}; + LocationSignature locations1(1, 3, location_array); + CallDescriptor* desc1 = NewStandardCallDescriptor(&locations1); + + // Caller + LocationSignature locations2(1, 3, location_array); + CallDescriptor* desc2 = NewStandardCallDescriptor(&locations1); + + CommonOperatorBuilder common(zone()); + Node* p0 = Node::New(zone(), 0, nullptr, 0, nullptr, false); + Node* p1 = Node::New(zone(), 0, common.Parameter(0), 0, nullptr, false); + Node* p2 = Node::New(zone(), 0, common.Parameter(1), 0, nullptr, false); + Node* p3 = Node::New(zone(), 0, common.Parameter(2), 0, nullptr, false); + Node* parameters[] = {p0, p1, p2, p3}; + const Operator* op = common.Call(desc2); + Node* const node = + Node::New(zone(), 1, op, arraysize(parameters), parameters, false); + EXPECT_TRUE(desc1->CanTailCall(node)); +} + + +TEST_F(LinkageTailCall, NonMatchingStackParameters) { + // Caller + LinkageLocation location_array[] = {RegisterLocation(0), StackLocation(3), + StackLocation(2), StackLocation(1)}; + LocationSignature locations1(1, 3, location_array); + CallDescriptor* desc1 = NewStandardCallDescriptor(&locations1); + + // Caller + LocationSignature locations2(1, 3, location_array); + CallDescriptor* desc2 = NewStandardCallDescriptor(&locations1); + + CommonOperatorBuilder common(zone()); + Node* p0 = Node::New(zone(), 0, nullptr, 0, nullptr, false); + Node* p1 = Node::New(zone(), 0, common.Parameter(0), 0, nullptr, false); + Node* p2 = Node::New(zone(), 0, common.Parameter(2), 0, nullptr, false); + Node* p3 = Node::New(zone(), 0, common.Parameter(1), 0, nullptr, false); + Node* parameters[] = {p0, p1, p2, p3}; + const Operator* op = common.Call(desc2); + Node* const node = + Node::New(zone(), 1, op, arraysize(parameters), parameters, false); + EXPECT_FALSE(desc1->CanTailCall(node)); +} + + +TEST_F(LinkageTailCall, MatchingStackParametersExtraCallerRegisters) { + // Caller + LinkageLocation location_array[] = {RegisterLocation(0), StackLocation(3), + StackLocation(2), StackLocation(1), + RegisterLocation(0), RegisterLocation(1)}; + LocationSignature locations1(1, 5, location_array); + CallDescriptor* desc1 = NewStandardCallDescriptor(&locations1); + + // Caller + LocationSignature locations2(1, 3, location_array); + CallDescriptor* desc2 = NewStandardCallDescriptor(&locations1); + + CommonOperatorBuilder common(zone()); + Node* p0 = Node::New(zone(), 0, nullptr, 0, nullptr, false); + Node* p1 = Node::New(zone(), 0, common.Parameter(0), 0, nullptr, false); + Node* p2 = Node::New(zone(), 0, common.Parameter(1), 0, nullptr, false); + Node* p3 = Node::New(zone(), 0, common.Parameter(2), 0, nullptr, false); + Node* parameters[] = {p0, p1, p2, p3}; + const Operator* op = common.Call(desc2); + Node* const node = + Node::New(zone(), 1, op, arraysize(parameters), parameters, false); + EXPECT_TRUE(desc1->CanTailCall(node)); +} + + +TEST_F(LinkageTailCall, MatchingStackParametersExtraCalleeRegisters) { + // Caller + LinkageLocation location_array[] = {RegisterLocation(0), StackLocation(3), + StackLocation(2), StackLocation(1), + RegisterLocation(0), RegisterLocation(1)}; + LocationSignature locations1(1, 3, location_array); + CallDescriptor* desc1 = NewStandardCallDescriptor(&locations1); + + // Caller + LocationSignature locations2(1, 5, location_array); + CallDescriptor* desc2 = NewStandardCallDescriptor(&locations1); + + CommonOperatorBuilder common(zone()); + Node* p0 = Node::New(zone(), 0, nullptr, 0, nullptr, false); + Node* p1 = Node::New(zone(), 0, common.Parameter(0), 0, nullptr, false); + Node* p2 = Node::New(zone(), 0, common.Parameter(1), 0, nullptr, false); + Node* p3 = Node::New(zone(), 0, common.Parameter(2), 0, nullptr, false); + Node* p4 = Node::New(zone(), 0, common.Parameter(3), 0, nullptr, false); + Node* parameters[] = {p0, p1, p2, p3, p4}; + const Operator* op = common.Call(desc2); + Node* const node = + Node::New(zone(), 1, op, arraysize(parameters), parameters, false); + EXPECT_TRUE(desc1->CanTailCall(node)); +} + + +TEST_F(LinkageTailCall, MatchingStackParametersExtraCallerRegistersAndStack) { + // Caller + LinkageLocation location_array[] = {RegisterLocation(0), StackLocation(3), + StackLocation(2), StackLocation(1), + RegisterLocation(0), StackLocation(4)}; + LocationSignature locations1(1, 5, location_array); + CallDescriptor* desc1 = NewStandardCallDescriptor(&locations1); + + // Caller + LocationSignature locations2(1, 3, location_array); + CallDescriptor* desc2 = NewStandardCallDescriptor(&locations2); + + CommonOperatorBuilder common(zone()); + Node* p0 = Node::New(zone(), 0, nullptr, 0, nullptr, false); + Node* p1 = Node::New(zone(), 0, common.Parameter(0), 0, nullptr, false); + Node* p2 = Node::New(zone(), 0, common.Parameter(1), 0, nullptr, false); + Node* p3 = Node::New(zone(), 0, common.Parameter(2), 0, nullptr, false); + Node* p4 = Node::New(zone(), 0, common.Parameter(3), 0, nullptr, false); + Node* parameters[] = {p0, p1, p2, p3, p4}; + const Operator* op = common.Call(desc2); + Node* const node = + Node::New(zone(), 1, op, arraysize(parameters), parameters, false); + EXPECT_FALSE(desc1->CanTailCall(node)); +} + + +TEST_F(LinkageTailCall, MatchingStackParametersExtraCalleeRegistersAndStack) { + // Caller + LinkageLocation location_array[] = {RegisterLocation(0), StackLocation(3), + StackLocation(2), RegisterLocation(0), + RegisterLocation(1), StackLocation(4)}; + LocationSignature locations1(1, 3, location_array); + CallDescriptor* desc1 = NewStandardCallDescriptor(&locations1); + + // Caller + LocationSignature locations2(1, 5, location_array); + CallDescriptor* desc2 = NewStandardCallDescriptor(&locations2); + + CommonOperatorBuilder common(zone()); + Node* p0 = Node::New(zone(), 0, nullptr, 0, nullptr, false); + Node* p1 = Node::New(zone(), 0, common.Parameter(0), 0, nullptr, false); + Node* p2 = Node::New(zone(), 0, common.Parameter(1), 0, nullptr, false); + Node* p3 = Node::New(zone(), 0, common.Parameter(2), 0, nullptr, false); + Node* p4 = Node::New(zone(), 0, common.Parameter(3), 0, nullptr, false); + Node* parameters[] = {p0, p1, p2, p3, p4}; + const Operator* op = common.Call(desc2); + Node* const node = + Node::New(zone(), 1, op, arraysize(parameters), parameters, false); + EXPECT_FALSE(desc1->CanTailCall(node)); +} + +} // namespace compiler +} // namespace internal +} // namespace v8 diff --git a/deps/v8/test/unittests/compiler/liveness-analyzer-unittest.cc b/deps/v8/test/unittests/compiler/liveness-analyzer-unittest.cc index 1e142550d5..3c94c25887 100644 --- a/deps/v8/test/unittests/compiler/liveness-analyzer-unittest.cc +++ b/deps/v8/test/unittests/compiler/liveness-analyzer-unittest.cc @@ -60,7 +60,7 @@ class LivenessAnalysisTest : public GraphTest { const FrameStateFunctionInfo* state_info = common()->CreateFrameStateFunctionInfo( FrameStateType::kJavaScriptFunction, 0, locals_count_, - Handle<SharedFunctionInfo>()); + Handle<SharedFunctionInfo>(), CALL_MAINTAINS_NATIVE_CONTEXT); const Operator* op = common()->FrameState( BailoutId(ast_num), OutputFrameStateCombine::Ignore(), state_info); diff --git a/deps/v8/test/unittests/compiler/machine-operator-reducer-unittest.cc b/deps/v8/test/unittests/compiler/machine-operator-reducer-unittest.cc index ce11fdef81..b14e9d392d 100644 --- a/deps/v8/test/unittests/compiler/machine-operator-reducer-unittest.cc +++ b/deps/v8/test/unittests/compiler/machine-operator-reducer-unittest.cc @@ -1438,6 +1438,55 @@ TEST_F(MachineOperatorReducerTest, Float64InsertHighWord32WithConstant) { // ----------------------------------------------------------------------------- +// Float64Equal + + +TEST_F(MachineOperatorReducerTest, Float64EqualWithFloat32Conversions) { + Node* const p0 = Parameter(0); + Node* const p1 = Parameter(1); + Reduction const r = Reduce(graph()->NewNode( + machine()->Float64Equal(), + graph()->NewNode(machine()->ChangeFloat32ToFloat64(), p0), + graph()->NewNode(machine()->ChangeFloat32ToFloat64(), p1))); + ASSERT_TRUE(r.Changed()); + EXPECT_THAT(r.replacement(), IsFloat32Equal(p0, p1)); +} + + +// ----------------------------------------------------------------------------- +// Float64LessThan + + +TEST_F(MachineOperatorReducerTest, Float64LessThanWithFloat32Conversions) { + Node* const p0 = Parameter(0); + Node* const p1 = Parameter(1); + Reduction const r = Reduce(graph()->NewNode( + machine()->Float64LessThan(), + graph()->NewNode(machine()->ChangeFloat32ToFloat64(), p0), + graph()->NewNode(machine()->ChangeFloat32ToFloat64(), p1))); + ASSERT_TRUE(r.Changed()); + EXPECT_THAT(r.replacement(), IsFloat32LessThan(p0, p1)); +} + + +// ----------------------------------------------------------------------------- +// Float64LessThanOrEqual + + +TEST_F(MachineOperatorReducerTest, + Float64LessThanOrEqualWithFloat32Conversions) { + Node* const p0 = Parameter(0); + Node* const p1 = Parameter(1); + Reduction const r = Reduce(graph()->NewNode( + machine()->Float64LessThanOrEqual(), + graph()->NewNode(machine()->ChangeFloat32ToFloat64(), p0), + graph()->NewNode(machine()->ChangeFloat32ToFloat64(), p1))); + ASSERT_TRUE(r.Changed()); + EXPECT_THAT(r.replacement(), IsFloat32LessThanOrEqual(p0, p1)); +} + + +// ----------------------------------------------------------------------------- // Store diff --git a/deps/v8/test/unittests/compiler/node-test-utils.cc b/deps/v8/test/unittests/compiler/node-test-utils.cc index 520ce0159e..d097ee4b66 100644 --- a/deps/v8/test/unittests/compiler/node-test-utils.cc +++ b/deps/v8/test/unittests/compiler/node-test-utils.cc @@ -7,6 +7,7 @@ #include <vector> #include "src/assembler.h" +#include "src/compiler/common-operator.h" #include "src/compiler/js-operator.h" #include "src/compiler/node-properties.h" #include "src/compiler/simplified-operator.h" @@ -1375,6 +1376,27 @@ class IsUnopMatcher final : public NodeMatcher { const Matcher<Node*> input_matcher_; }; +class IsParameterMatcher final : public NodeMatcher { + public: + explicit IsParameterMatcher(const Matcher<int>& index_matcher) + : NodeMatcher(IrOpcode::kParameter), index_matcher_(index_matcher) {} + + void DescribeTo(std::ostream* os) const override { + *os << "is a Parameter node with index("; + index_matcher_.DescribeTo(os); + *os << ")"; + } + + bool MatchAndExplain(Node* node, MatchResultListener* listener) const final { + return (NodeMatcher::MatchAndExplain(node, listener) && + PrintMatchAndExplain(ParameterIndexOf(node->op()), "index", + index_matcher_, listener)); + } + + private: + const Matcher<int> index_matcher_; +}; + } // namespace @@ -1678,6 +1700,72 @@ Matcher<Node*> IsTailCall( } +Matcher<Node*> IsTailCall( + const Matcher<CallDescriptor const*>& descriptor_matcher, + const Matcher<Node*>& value0_matcher, const Matcher<Node*>& value1_matcher, + const Matcher<Node*>& value2_matcher, const Matcher<Node*>& effect_matcher, + const Matcher<Node*>& control_matcher) { + std::vector<Matcher<Node*>> value_matchers; + value_matchers.push_back(value0_matcher); + value_matchers.push_back(value1_matcher); + value_matchers.push_back(value2_matcher); + return MakeMatcher(new IsTailCallMatcher(descriptor_matcher, value_matchers, + effect_matcher, control_matcher)); +} + + +Matcher<Node*> IsTailCall( + const Matcher<CallDescriptor const*>& descriptor_matcher, + const Matcher<Node*>& value0_matcher, const Matcher<Node*>& value1_matcher, + const Matcher<Node*>& value2_matcher, const Matcher<Node*>& value3_matcher, + const Matcher<Node*>& effect_matcher, + const Matcher<Node*>& control_matcher) { + std::vector<Matcher<Node*>> value_matchers; + value_matchers.push_back(value0_matcher); + value_matchers.push_back(value1_matcher); + value_matchers.push_back(value2_matcher); + value_matchers.push_back(value3_matcher); + return MakeMatcher(new IsTailCallMatcher(descriptor_matcher, value_matchers, + effect_matcher, control_matcher)); +} + + +Matcher<Node*> IsTailCall( + const Matcher<CallDescriptor const*>& descriptor_matcher, + const Matcher<Node*>& value0_matcher, const Matcher<Node*>& value1_matcher, + const Matcher<Node*>& value2_matcher, const Matcher<Node*>& value3_matcher, + const Matcher<Node*>& value4_matcher, const Matcher<Node*>& effect_matcher, + const Matcher<Node*>& control_matcher) { + std::vector<Matcher<Node*>> value_matchers; + value_matchers.push_back(value0_matcher); + value_matchers.push_back(value1_matcher); + value_matchers.push_back(value2_matcher); + value_matchers.push_back(value3_matcher); + value_matchers.push_back(value4_matcher); + return MakeMatcher(new IsTailCallMatcher(descriptor_matcher, value_matchers, + effect_matcher, control_matcher)); +} + + +Matcher<Node*> IsTailCall( + const Matcher<CallDescriptor const*>& descriptor_matcher, + const Matcher<Node*>& value0_matcher, const Matcher<Node*>& value1_matcher, + const Matcher<Node*>& value2_matcher, const Matcher<Node*>& value3_matcher, + const Matcher<Node*>& value4_matcher, const Matcher<Node*>& value5_matcher, + const Matcher<Node*>& effect_matcher, + const Matcher<Node*>& control_matcher) { + std::vector<Matcher<Node*>> value_matchers; + value_matchers.push_back(value0_matcher); + value_matchers.push_back(value1_matcher); + value_matchers.push_back(value2_matcher); + value_matchers.push_back(value3_matcher); + value_matchers.push_back(value4_matcher); + value_matchers.push_back(value5_matcher); + return MakeMatcher(new IsTailCallMatcher(descriptor_matcher, value_matchers, + effect_matcher, control_matcher)); +} + + Matcher<Node*> IsReferenceEqual(const Matcher<Type*>& type_matcher, const Matcher<Node*>& lhs_matcher, const Matcher<Node*>& rhs_matcher) { @@ -1799,6 +1887,16 @@ Matcher<Node*> IsLoadContext(const Matcher<ContextAccess>& access_matcher, } +Matcher<Node*> IsParameter(const Matcher<int> index_matcher) { + return MakeMatcher(new IsParameterMatcher(index_matcher)); +} + + +Matcher<Node*> IsLoadFramePointer() { + return MakeMatcher(new NodeMatcher(IrOpcode::kLoadFramePointer)); +} + + #define IS_BINOP_MATCHER(Name) \ Matcher<Node*> Is##Name(const Matcher<Node*>& lhs_matcher, \ const Matcher<Node*>& rhs_matcher) { \ @@ -1830,8 +1928,13 @@ IS_BINOP_MATCHER(Int32MulHigh) IS_BINOP_MATCHER(Int32LessThan) IS_BINOP_MATCHER(Uint32LessThan) IS_BINOP_MATCHER(Uint32LessThanOrEqual) +IS_BINOP_MATCHER(Int64Add) +IS_BINOP_MATCHER(Int64Sub) IS_BINOP_MATCHER(Float32Max) IS_BINOP_MATCHER(Float32Min) +IS_BINOP_MATCHER(Float32Equal) +IS_BINOP_MATCHER(Float32LessThan) +IS_BINOP_MATCHER(Float32LessThanOrEqual) IS_BINOP_MATCHER(Float64Max) IS_BINOP_MATCHER(Float64Min) IS_BINOP_MATCHER(Float64Sub) diff --git a/deps/v8/test/unittests/compiler/node-test-utils.h b/deps/v8/test/unittests/compiler/node-test-utils.h index a64d9f009a..149dcfc439 100644 --- a/deps/v8/test/unittests/compiler/node-test-utils.h +++ b/deps/v8/test/unittests/compiler/node-test-utils.h @@ -134,6 +134,31 @@ Matcher<Node*> IsTailCall( const Matcher<Node*>& value0_matcher, const Matcher<Node*>& value1_matcher, const Matcher<Node*>& effect_matcher, const Matcher<Node*>& control_matcher); +Matcher<Node*> IsTailCall( + const Matcher<CallDescriptor const*>& descriptor_matcher, + const Matcher<Node*>& value0_matcher, const Matcher<Node*>& value1_matcher, + const Matcher<Node*>& value2_matcher, const Matcher<Node*>& effect_matcher, + const Matcher<Node*>& control_matcher); +Matcher<Node*> IsTailCall( + const Matcher<CallDescriptor const*>& descriptor_matcher, + const Matcher<Node*>& value0_matcher, const Matcher<Node*>& value1_matcher, + const Matcher<Node*>& value2_matcher, const Matcher<Node*>& value3_matcher, + const Matcher<Node*>& effect_matcher, + const Matcher<Node*>& control_matcher); +Matcher<Node*> IsTailCall( + const Matcher<CallDescriptor const*>& descriptor_matcher, + const Matcher<Node*>& value0_matcher, const Matcher<Node*>& value1_matcher, + const Matcher<Node*>& value2_matcher, const Matcher<Node*>& value3_matcher, + const Matcher<Node*>& value4_matcher, const Matcher<Node*>& effect_matcher, + const Matcher<Node*>& control_matcher); +Matcher<Node*> IsTailCall( + const Matcher<CallDescriptor const*>& descriptor_matcher, + const Matcher<Node*>& value0_matcher, const Matcher<Node*>& value1_matcher, + const Matcher<Node*>& value2_matcher, const Matcher<Node*>& value3_matcher, + const Matcher<Node*>& value4_matcher, const Matcher<Node*>& value5_matcher, + const Matcher<Node*>& effect_matcher, + const Matcher<Node*>& control_matcher); + Matcher<Node*> IsBooleanNot(const Matcher<Node*>& value_matcher); Matcher<Node*> IsReferenceEqual(const Matcher<Type*>& type_matcher, @@ -240,6 +265,10 @@ Matcher<Node*> IsUint32LessThan(const Matcher<Node*>& lhs_matcher, const Matcher<Node*>& rhs_matcher); Matcher<Node*> IsUint32LessThanOrEqual(const Matcher<Node*>& lhs_matcher, const Matcher<Node*>& rhs_matcher); +Matcher<Node*> IsInt64Add(const Matcher<Node*>& lhs_matcher, + const Matcher<Node*>& rhs_matcher); +Matcher<Node*> IsInt64Sub(const Matcher<Node*>& lhs_matcher, + const Matcher<Node*>& rhs_matcher); Matcher<Node*> IsChangeFloat64ToInt32(const Matcher<Node*>& input_matcher); Matcher<Node*> IsChangeFloat64ToUint32(const Matcher<Node*>& input_matcher); Matcher<Node*> IsChangeInt32ToFloat64(const Matcher<Node*>& input_matcher); @@ -254,6 +283,12 @@ Matcher<Node*> IsFloat32Max(const Matcher<Node*>& lhs_matcher, Matcher<Node*> IsFloat32Min(const Matcher<Node*>& lhs_matcher, const Matcher<Node*>& rhs_matcher); Matcher<Node*> IsFloat32Abs(const Matcher<Node*>& input_matcher); +Matcher<Node*> IsFloat32Equal(const Matcher<Node*>& lhs_matcher, + const Matcher<Node*>& rhs_matcher); +Matcher<Node*> IsFloat32LessThan(const Matcher<Node*>& lhs_matcher, + const Matcher<Node*>& rhs_matcher); +Matcher<Node*> IsFloat32LessThanOrEqual(const Matcher<Node*>& lhs_matcher, + const Matcher<Node*>& rhs_matcher); Matcher<Node*> IsFloat64Max(const Matcher<Node*>& lhs_matcher, const Matcher<Node*>& rhs_matcher); Matcher<Node*> IsFloat64Min(const Matcher<Node*>& lhs_matcher, @@ -279,6 +314,8 @@ Matcher<Node*> IsLoadContext(const Matcher<ContextAccess>& access_matcher, const Matcher<Node*>& context_matcher); Matcher<Node*> IsNumberToInt32(const Matcher<Node*>& input_matcher); Matcher<Node*> IsNumberToUint32(const Matcher<Node*>& input_matcher); +Matcher<Node*> IsParameter(const Matcher<int> index_matcher); +Matcher<Node*> IsLoadFramePointer(); } // namespace compiler } // namespace internal diff --git a/deps/v8/test/unittests/compiler/ppc/OWNERS b/deps/v8/test/unittests/compiler/ppc/OWNERS index a04d29a94f..eb007cb908 100644 --- a/deps/v8/test/unittests/compiler/ppc/OWNERS +++ b/deps/v8/test/unittests/compiler/ppc/OWNERS @@ -1,3 +1,4 @@ +jyan@ca.ibm.com dstence@us.ibm.com joransiu@ca.ibm.com mbrandy@us.ibm.com diff --git a/deps/v8/test/unittests/compiler/register-allocator-unittest.cc b/deps/v8/test/unittests/compiler/register-allocator-unittest.cc index 873b4ecd2a..23a118b6ad 100644 --- a/deps/v8/test/unittests/compiler/register-allocator-unittest.cc +++ b/deps/v8/test/unittests/compiler/register-allocator-unittest.cc @@ -9,6 +9,75 @@ namespace v8 { namespace internal { namespace compiler { + +namespace { + +// We can't just use the size of the moves collection, because of +// redundant moves which need to be discounted. +int GetMoveCount(const ParallelMove& moves) { + int move_count = 0; + for (auto move : moves) { + if (move->IsEliminated() || move->IsRedundant()) continue; + ++move_count; + } + return move_count; +} + + +bool AreOperandsOfSameType( + const AllocatedOperand& op, + const InstructionSequenceTest::TestOperand& test_op) { + bool test_op_is_reg = + (test_op.type_ == + InstructionSequenceTest::TestOperandType::kFixedRegister || + test_op.type_ == InstructionSequenceTest::TestOperandType::kRegister); + + return (op.IsRegister() && test_op_is_reg) || + (op.IsStackSlot() && !test_op_is_reg); +} + + +bool AllocatedOperandMatches( + const AllocatedOperand& op, + const InstructionSequenceTest::TestOperand& test_op) { + return AreOperandsOfSameType(op, test_op) && + (op.index() == test_op.value_ || + test_op.value_ == InstructionSequenceTest::kNoValue); +} + + +int GetParallelMoveCount(int instr_index, Instruction::GapPosition gap_pos, + const InstructionSequence* sequence) { + const ParallelMove* moves = + sequence->InstructionAt(instr_index)->GetParallelMove(gap_pos); + if (moves == nullptr) return 0; + return GetMoveCount(*moves); +} + + +bool IsParallelMovePresent(int instr_index, Instruction::GapPosition gap_pos, + const InstructionSequence* sequence, + const InstructionSequenceTest::TestOperand& src, + const InstructionSequenceTest::TestOperand& dest) { + const ParallelMove* moves = + sequence->InstructionAt(instr_index)->GetParallelMove(gap_pos); + EXPECT_NE(nullptr, moves); + + bool found_match = false; + for (auto move : *moves) { + if (move->IsEliminated() || move->IsRedundant()) continue; + if (AllocatedOperandMatches(AllocatedOperand::cast(move->source()), src) && + AllocatedOperandMatches(AllocatedOperand::cast(move->destination()), + dest)) { + found_match = true; + break; + } + } + return found_match; +} +} + + class RegisterAllocatorTest : public InstructionSequenceTest { public: void Allocate() { @@ -492,6 +561,144 @@ TEST_F(RegisterAllocatorTest, RegressionLoadConstantBeforeSpill) { } +TEST_F(RegisterAllocatorTest, DiamondWithCallFirstBlock) { + StartBlock(); + auto x = EmitOI(Reg(0)); + EndBlock(Branch(Reg(x), 1, 2)); + + StartBlock(); + EmitCall(Slot(-1)); + auto occupy = EmitOI(Reg(0)); + EndBlock(Jump(2)); + + StartBlock(); + EndBlock(FallThrough()); + + StartBlock(); + Use(occupy); + Return(Reg(x)); + EndBlock(); + Allocate(); +} + + +TEST_F(RegisterAllocatorTest, DiamondWithCallSecondBlock) { + StartBlock(); + auto x = EmitOI(Reg(0)); + EndBlock(Branch(Reg(x), 1, 2)); + + StartBlock(); + EndBlock(Jump(2)); + + StartBlock(); + EmitCall(Slot(-1)); + auto occupy = EmitOI(Reg(0)); + EndBlock(FallThrough()); + + StartBlock(); + Use(occupy); + Return(Reg(x)); + EndBlock(); + Allocate(); +} + + +TEST_F(RegisterAllocatorTest, SingleDeferredBlockSpill) { + StartBlock(); // B0 + auto var = EmitOI(Reg(0)); + EndBlock(Branch(Reg(var), 1, 2)); + + StartBlock(); // B1 + EndBlock(Jump(2)); + + StartBlock(true); // B2 + EmitCall(Slot(-1), Slot(var)); + EndBlock(); + + StartBlock(); // B3 + EmitNop(); + EndBlock(); + + StartBlock(); // B4 + Return(Reg(var, 0)); + EndBlock(); + + Allocate(); + + const int var_def_index = 1; + const int call_index = 3; + int expect_no_moves = + FLAG_turbo_preprocess_ranges ? var_def_index : call_index; + int expect_spill_move = + FLAG_turbo_preprocess_ranges ? call_index : var_def_index; + + // We should have no parallel moves at the "expect_no_moves" position. + EXPECT_EQ( + 0, GetParallelMoveCount(expect_no_moves, Instruction::START, sequence())); + + // The spill should be performed at the position expect_spill_move. + EXPECT_TRUE(IsParallelMovePresent(expect_spill_move, Instruction::START, + sequence(), Reg(0), Slot(0))); +} + + +TEST_F(RegisterAllocatorTest, MultipleDeferredBlockSpills) { + if (!FLAG_turbo_preprocess_ranges) return; + + StartBlock(); // B0 + auto var1 = EmitOI(Reg(0)); + auto var2 = EmitOI(Reg(1)); + auto var3 = EmitOI(Reg(2)); + EndBlock(Branch(Reg(var1, 0), 1, 2)); + + StartBlock(true); // B1 + EmitCall(Slot(-2), Slot(var1)); + EndBlock(Jump(2)); + + StartBlock(true); // B2 + EmitCall(Slot(-1), Slot(var2)); + EndBlock(); + + StartBlock(); // B3 + EmitNop(); + EndBlock(); + + StartBlock(); // B4 + Return(Reg(var3, 2)); + EndBlock(); + + const int def_of_v2 = 3; + const int call_in_b1 = 4; + const int call_in_b2 = 6; + const int end_of_b1 = 5; + const int end_of_b2 = 7; + const int start_of_b3 = 8; + + Allocate(); + // TODO(mtrofin): at the moment, the linear allocator spills var1 and var2, + // so only var3 is spilled in deferred blocks. Greedy avoids spilling 1&2. + // Expand the test once greedy is back online with this facility. + const int var3_reg = 2; + const int var3_slot = 2; + + EXPECT_FALSE(IsParallelMovePresent(def_of_v2, Instruction::START, sequence(), + Reg(var3_reg), Slot())); + EXPECT_TRUE(IsParallelMovePresent(call_in_b1, Instruction::START, sequence(), + Reg(var3_reg), Slot(var3_slot))); + EXPECT_TRUE(IsParallelMovePresent(end_of_b1, Instruction::START, sequence(), + Slot(var3_slot), Reg())); + + EXPECT_TRUE(IsParallelMovePresent(call_in_b2, Instruction::START, sequence(), + Reg(var3_reg), Slot(var3_slot))); + EXPECT_TRUE(IsParallelMovePresent(end_of_b2, Instruction::START, sequence(), + Slot(var3_slot), Reg())); + + + EXPECT_EQ(0, + GetParallelMoveCount(start_of_b3, Instruction::START, sequence())); +} + + namespace { enum class ParameterType { kFixedSlot, kSlot, kRegister, kFixedRegister }; diff --git a/deps/v8/test/unittests/compiler/scheduler-unittest.cc b/deps/v8/test/unittests/compiler/scheduler-unittest.cc index 45c636b27a..954541b721 100644 --- a/deps/v8/test/unittests/compiler/scheduler-unittest.cc +++ b/deps/v8/test/unittests/compiler/scheduler-unittest.cc @@ -215,7 +215,7 @@ TEST_F(SchedulerRPOTest, EntryLoop) { TEST_F(SchedulerRPOTest, EndLoop) { Schedule schedule(zone()); - SmartPointer<TestLoop> loop1(CreateLoop(&schedule, 2)); + base::SmartPointer<TestLoop> loop1(CreateLoop(&schedule, 2)); schedule.AddSuccessorForTesting(schedule.start(), loop1->header()); BasicBlockVector* order = Scheduler::ComputeSpecialRPO(zone(), &schedule); CheckRPONumbers(order, 3, true); @@ -225,7 +225,7 @@ TEST_F(SchedulerRPOTest, EndLoop) { TEST_F(SchedulerRPOTest, EndLoopNested) { Schedule schedule(zone()); - SmartPointer<TestLoop> loop1(CreateLoop(&schedule, 2)); + base::SmartPointer<TestLoop> loop1(CreateLoop(&schedule, 2)); schedule.AddSuccessorForTesting(schedule.start(), loop1->header()); schedule.AddSuccessorForTesting(loop1->last(), schedule.start()); BasicBlockVector* order = Scheduler::ComputeSpecialRPO(zone(), &schedule); @@ -406,8 +406,8 @@ TEST_F(SchedulerRPOTest, LoopNest2) { TEST_F(SchedulerRPOTest, LoopFollow1) { Schedule schedule(zone()); - SmartPointer<TestLoop> loop1(CreateLoop(&schedule, 1)); - SmartPointer<TestLoop> loop2(CreateLoop(&schedule, 1)); + base::SmartPointer<TestLoop> loop1(CreateLoop(&schedule, 1)); + base::SmartPointer<TestLoop> loop2(CreateLoop(&schedule, 1)); BasicBlock* A = schedule.start(); BasicBlock* E = schedule.end(); @@ -427,8 +427,8 @@ TEST_F(SchedulerRPOTest, LoopFollow1) { TEST_F(SchedulerRPOTest, LoopFollow2) { Schedule schedule(zone()); - SmartPointer<TestLoop> loop1(CreateLoop(&schedule, 1)); - SmartPointer<TestLoop> loop2(CreateLoop(&schedule, 1)); + base::SmartPointer<TestLoop> loop1(CreateLoop(&schedule, 1)); + base::SmartPointer<TestLoop> loop2(CreateLoop(&schedule, 1)); BasicBlock* A = schedule.start(); BasicBlock* S = schedule.NewBasicBlock(); @@ -451,8 +451,8 @@ TEST_F(SchedulerRPOTest, LoopFollowN) { for (int size = 1; size < 5; size++) { for (int exit = 0; exit < size; exit++) { Schedule schedule(zone()); - SmartPointer<TestLoop> loop1(CreateLoop(&schedule, size)); - SmartPointer<TestLoop> loop2(CreateLoop(&schedule, size)); + base::SmartPointer<TestLoop> loop1(CreateLoop(&schedule, size)); + base::SmartPointer<TestLoop> loop2(CreateLoop(&schedule, size)); BasicBlock* A = schedule.start(); BasicBlock* E = schedule.end(); @@ -472,8 +472,8 @@ TEST_F(SchedulerRPOTest, LoopFollowN) { TEST_F(SchedulerRPOTest, NestedLoopFollow1) { Schedule schedule(zone()); - SmartPointer<TestLoop> loop1(CreateLoop(&schedule, 1)); - SmartPointer<TestLoop> loop2(CreateLoop(&schedule, 1)); + base::SmartPointer<TestLoop> loop1(CreateLoop(&schedule, 1)); + base::SmartPointer<TestLoop> loop2(CreateLoop(&schedule, 1)); BasicBlock* A = schedule.start(); BasicBlock* B = schedule.NewBasicBlock(); @@ -506,7 +506,7 @@ TEST_F(SchedulerRPOTest, LoopBackedges1) { BasicBlock* A = schedule.start(); BasicBlock* E = schedule.end(); - SmartPointer<TestLoop> loop1(CreateLoop(&schedule, size)); + base::SmartPointer<TestLoop> loop1(CreateLoop(&schedule, size)); schedule.AddSuccessorForTesting(A, loop1->header()); schedule.AddSuccessorForTesting(loop1->last(), E); @@ -530,7 +530,7 @@ TEST_F(SchedulerRPOTest, LoopOutedges1) { BasicBlock* D = schedule.NewBasicBlock(); BasicBlock* E = schedule.end(); - SmartPointer<TestLoop> loop1(CreateLoop(&schedule, size)); + base::SmartPointer<TestLoop> loop1(CreateLoop(&schedule, size)); schedule.AddSuccessorForTesting(A, loop1->header()); schedule.AddSuccessorForTesting(loop1->last(), E); @@ -553,7 +553,7 @@ TEST_F(SchedulerRPOTest, LoopOutedges2) { BasicBlock* A = schedule.start(); BasicBlock* E = schedule.end(); - SmartPointer<TestLoop> loop1(CreateLoop(&schedule, size)); + base::SmartPointer<TestLoop> loop1(CreateLoop(&schedule, size)); schedule.AddSuccessorForTesting(A, loop1->header()); schedule.AddSuccessorForTesting(loop1->last(), E); @@ -576,7 +576,7 @@ TEST_F(SchedulerRPOTest, LoopOutloops1) { Schedule schedule(zone()); BasicBlock* A = schedule.start(); BasicBlock* E = schedule.end(); - SmartPointer<TestLoop> loop1(CreateLoop(&schedule, size)); + base::SmartPointer<TestLoop> loop1(CreateLoop(&schedule, size)); schedule.AddSuccessorForTesting(A, loop1->header()); schedule.AddSuccessorForTesting(loop1->last(), E); diff --git a/deps/v8/test/unittests/compiler/tail-call-optimization-unittest.cc b/deps/v8/test/unittests/compiler/tail-call-optimization-unittest.cc index 449299bb1d..7257cc9802 100644 --- a/deps/v8/test/unittests/compiler/tail-call-optimization-unittest.cc +++ b/deps/v8/test/unittests/compiler/tail-call-optimization-unittest.cc @@ -27,10 +27,11 @@ class TailCallOptimizationTest : public GraphTest { TEST_F(TailCallOptimizationTest, CallCodeObject0) { MachineType kMachineSignature[] = {kMachAnyTagged, kMachAnyTagged}; - LinkageLocation kLocationSignature[] = {LinkageLocation(0), - LinkageLocation(1)}; + LinkageLocation kLocationSignature[] = {LinkageLocation::ForRegister(0), + LinkageLocation::ForRegister(1)}; const CallDescriptor* kCallDescriptor = new (zone()) CallDescriptor( - CallDescriptor::kCallCodeObject, kMachAnyTagged, LinkageLocation(0), + CallDescriptor::kCallCodeObject, kMachAnyTagged, + LinkageLocation::ForRegister(0), new (zone()) MachineSignature(1, 1, kMachineSignature), new (zone()) LocationSignature(1, 1, kLocationSignature), 0, Operator::kNoProperties, 0, 0, CallDescriptor::kNoFlags); @@ -47,10 +48,11 @@ TEST_F(TailCallOptimizationTest, CallCodeObject0) { TEST_F(TailCallOptimizationTest, CallCodeObject1) { MachineType kMachineSignature[] = {kMachAnyTagged, kMachAnyTagged}; - LinkageLocation kLocationSignature[] = {LinkageLocation(0), - LinkageLocation(1)}; + LinkageLocation kLocationSignature[] = {LinkageLocation::ForRegister(0), + LinkageLocation::ForRegister(1)}; const CallDescriptor* kCallDescriptor = new (zone()) CallDescriptor( - CallDescriptor::kCallCodeObject, kMachAnyTagged, LinkageLocation(0), + CallDescriptor::kCallCodeObject, kMachAnyTagged, + LinkageLocation::ForRegister(0), new (zone()) MachineSignature(1, 1, kMachineSignature), new (zone()) LocationSignature(1, 1, kLocationSignature), 0, Operator::kNoProperties, 0, 0, CallDescriptor::kSupportsTailCalls); @@ -71,10 +73,11 @@ TEST_F(TailCallOptimizationTest, CallCodeObject1) { TEST_F(TailCallOptimizationTest, CallCodeObject2) { MachineType kMachineSignature[] = {kMachAnyTagged, kMachAnyTagged}; - LinkageLocation kLocationSignature[] = {LinkageLocation(0), - LinkageLocation(1)}; + LinkageLocation kLocationSignature[] = {LinkageLocation::ForRegister(0), + LinkageLocation::ForRegister(1)}; const CallDescriptor* kCallDescriptor = new (zone()) CallDescriptor( - CallDescriptor::kCallCodeObject, kMachAnyTagged, LinkageLocation(0), + CallDescriptor::kCallCodeObject, kMachAnyTagged, + LinkageLocation::ForRegister(0), new (zone()) MachineSignature(1, 1, kMachineSignature), new (zone()) LocationSignature(1, 1, kLocationSignature), 0, Operator::kNoProperties, 0, 0, CallDescriptor::kSupportsTailCalls); @@ -93,10 +96,11 @@ TEST_F(TailCallOptimizationTest, CallCodeObject2) { TEST_F(TailCallOptimizationTest, CallJSFunction0) { MachineType kMachineSignature[] = {kMachAnyTagged, kMachAnyTagged}; - LinkageLocation kLocationSignature[] = {LinkageLocation(0), - LinkageLocation(1)}; + LinkageLocation kLocationSignature[] = {LinkageLocation::ForRegister(0), + LinkageLocation::ForRegister(1)}; const CallDescriptor* kCallDescriptor = new (zone()) CallDescriptor( - CallDescriptor::kCallJSFunction, kMachAnyTagged, LinkageLocation(0), + CallDescriptor::kCallJSFunction, kMachAnyTagged, + LinkageLocation::ForRegister(0), new (zone()) MachineSignature(1, 1, kMachineSignature), new (zone()) LocationSignature(1, 1, kLocationSignature), 0, Operator::kNoProperties, 0, 0, CallDescriptor::kNoFlags); @@ -113,10 +117,11 @@ TEST_F(TailCallOptimizationTest, CallJSFunction0) { TEST_F(TailCallOptimizationTest, CallJSFunction1) { MachineType kMachineSignature[] = {kMachAnyTagged, kMachAnyTagged}; - LinkageLocation kLocationSignature[] = {LinkageLocation(0), - LinkageLocation(1)}; + LinkageLocation kLocationSignature[] = {LinkageLocation::ForRegister(0), + LinkageLocation::ForRegister(1)}; const CallDescriptor* kCallDescriptor = new (zone()) CallDescriptor( - CallDescriptor::kCallJSFunction, kMachAnyTagged, LinkageLocation(0), + CallDescriptor::kCallJSFunction, kMachAnyTagged, + LinkageLocation::ForRegister(0), new (zone()) MachineSignature(1, 1, kMachineSignature), new (zone()) LocationSignature(1, 1, kLocationSignature), 0, Operator::kNoProperties, 0, 0, CallDescriptor::kSupportsTailCalls); @@ -137,10 +142,11 @@ TEST_F(TailCallOptimizationTest, CallJSFunction1) { TEST_F(TailCallOptimizationTest, CallJSFunction2) { MachineType kMachineSignature[] = {kMachAnyTagged, kMachAnyTagged}; - LinkageLocation kLocationSignature[] = {LinkageLocation(0), - LinkageLocation(1)}; + LinkageLocation kLocationSignature[] = {LinkageLocation::ForRegister(0), + LinkageLocation::ForRegister(1)}; const CallDescriptor* kCallDescriptor = new (zone()) CallDescriptor( - CallDescriptor::kCallJSFunction, kMachAnyTagged, LinkageLocation(0), + CallDescriptor::kCallJSFunction, kMachAnyTagged, + LinkageLocation::ForRegister(0), new (zone()) MachineSignature(1, 1, kMachineSignature), new (zone()) LocationSignature(1, 1, kLocationSignature), 0, Operator::kNoProperties, 0, 0, CallDescriptor::kSupportsTailCalls); |