diff options
Diffstat (limited to 'deps/v8/test/unittests/compiler')
35 files changed, 1456 insertions, 437 deletions
diff --git a/deps/v8/test/unittests/compiler/arm/instruction-selector-arm-unittest.cc b/deps/v8/test/unittests/compiler/arm/instruction-selector-arm-unittest.cc index 941fa26e00..bfae2ba4d0 100644 --- a/deps/v8/test/unittests/compiler/arm/instruction-selector-arm-unittest.cc +++ b/deps/v8/test/unittests/compiler/arm/instruction-selector-arm-unittest.cc @@ -1320,7 +1320,8 @@ TEST_P(InstructionSelectorMemoryAccessTest, LoadWithImmediateIndex) { TEST_P(InstructionSelectorMemoryAccessTest, StoreWithParameters) { const MemoryAccess memacc = GetParam(); StreamBuilder m(this, kMachInt32, kMachPtr, kMachInt32, memacc.type); - m.Store(memacc.type, m.Parameter(0), m.Parameter(1), m.Parameter(2)); + m.Store(memacc.type, m.Parameter(0), m.Parameter(1), m.Parameter(2), + kNoWriteBarrier); m.Return(m.Int32Constant(0)); Stream s = m.Build(); ASSERT_EQ(1U, s.size()); @@ -1335,8 +1336,8 @@ TEST_P(InstructionSelectorMemoryAccessTest, StoreWithImmediateIndex) { const MemoryAccess memacc = GetParam(); TRACED_FOREACH(int32_t, index, memacc.immediates) { StreamBuilder m(this, kMachInt32, kMachPtr, memacc.type); - m.Store(memacc.type, m.Parameter(0), m.Int32Constant(index), - m.Parameter(1)); + m.Store(memacc.type, m.Parameter(0), m.Int32Constant(index), m.Parameter(1), + kNoWriteBarrier); m.Return(m.Int32Constant(0)); Stream s = m.Build(); ASSERT_EQ(1U, s.size()); 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 154645c1fb..3af1232cff 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 @@ -583,7 +583,6 @@ TEST_F(InstructionSelectorTest, AddImmediateOnLeft) { TEST_F(InstructionSelectorTest, SubZeroOnLeft) { - // Subtraction with zero on the left maps to Neg. { // 32-bit subtract. StreamBuilder m(this, kMachInt32, kMachInt32, kMachInt32); @@ -591,8 +590,10 @@ TEST_F(InstructionSelectorTest, SubZeroOnLeft) { Stream s = m.Build(); ASSERT_EQ(1U, s.size()); - EXPECT_EQ(kArm64Neg32, s[0]->arch_opcode()); - EXPECT_EQ(1U, s[0]->InputCount()); + EXPECT_EQ(kArm64Sub32, s[0]->arch_opcode()); + ASSERT_EQ(2U, s[0]->InputCount()); + EXPECT_TRUE(s[0]->InputAt(0)->IsImmediate()); + EXPECT_EQ(0, s.ToInt32(s[0]->InputAt(0))); EXPECT_EQ(1U, s[0]->OutputCount()); } { @@ -602,13 +603,71 @@ TEST_F(InstructionSelectorTest, SubZeroOnLeft) { Stream s = m.Build(); ASSERT_EQ(1U, s.size()); - EXPECT_EQ(kArm64Neg, s[0]->arch_opcode()); - EXPECT_EQ(1U, s[0]->InputCount()); + EXPECT_EQ(kArm64Sub, s[0]->arch_opcode()); + ASSERT_EQ(2U, s[0]->InputCount()); + EXPECT_TRUE(s[0]->InputAt(0)->IsImmediate()); + EXPECT_EQ(0, s.ToInt64(s[0]->InputAt(0))); EXPECT_EQ(1U, s[0]->OutputCount()); } } +TEST_F(InstructionSelectorTest, SubZeroOnLeftWithShift) { + TRACED_FOREACH(Shift, shift, kShiftInstructions) { + { + // Test 32-bit operations. Ignore ROR shifts, as subtract does not + // support them. + if ((shift.mi.machine_type != kMachInt32) || + (shift.mi.arch_opcode == kArm64Ror32) || + (shift.mi.arch_opcode == kArm64Ror)) + continue; + + TRACED_FORRANGE(int, imm, -32, 63) { + StreamBuilder m(this, kMachInt32, kMachInt32, kMachInt32); + m.Return(m.Int32Sub( + m.Int32Constant(0), + (m.*shift.mi.constructor)(m.Parameter(1), m.Int32Constant(imm)))); + Stream s = m.Build(); + + ASSERT_EQ(1U, s.size()); + EXPECT_EQ(kArm64Sub32, s[0]->arch_opcode()); + ASSERT_EQ(3U, s[0]->InputCount()); + EXPECT_TRUE(s[0]->InputAt(0)->IsImmediate()); + EXPECT_EQ(0, s.ToInt32(s[0]->InputAt(0))); + EXPECT_EQ(shift.mode, s[0]->addressing_mode()); + EXPECT_EQ(imm, s.ToInt32(s[0]->InputAt(2))); + EXPECT_EQ(1U, s[0]->OutputCount()); + } + } + { + // Test 64-bit operations. Ignore ROR shifts, as subtract does not + // support them. + if ((shift.mi.machine_type != kMachInt64) || + (shift.mi.arch_opcode == kArm64Ror32) || + (shift.mi.arch_opcode == kArm64Ror)) + continue; + + TRACED_FORRANGE(int, imm, -32, 127) { + StreamBuilder m(this, kMachInt64, kMachInt64, kMachInt64); + m.Return(m.Int64Sub( + m.Int64Constant(0), + (m.*shift.mi.constructor)(m.Parameter(1), m.Int64Constant(imm)))); + Stream s = m.Build(); + + ASSERT_EQ(1U, s.size()); + EXPECT_EQ(kArm64Sub, s[0]->arch_opcode()); + ASSERT_EQ(3U, s[0]->InputCount()); + EXPECT_TRUE(s[0]->InputAt(0)->IsImmediate()); + EXPECT_EQ(0, s.ToInt32(s[0]->InputAt(0))); + EXPECT_EQ(shift.mode, s[0]->addressing_mode()); + EXPECT_EQ(imm, s.ToInt32(s[0]->InputAt(2))); + EXPECT_EQ(1U, s[0]->OutputCount()); + } + } + } +} + + TEST_F(InstructionSelectorTest, AddNegImmediateOnLeft) { { // 32-bit add. @@ -2097,7 +2156,8 @@ TEST_P(InstructionSelectorMemoryAccessTest, LoadWithImmediateIndex) { TEST_P(InstructionSelectorMemoryAccessTest, StoreWithParameters) { const MemoryAccess memacc = GetParam(); StreamBuilder m(this, kMachInt32, kMachPtr, kMachInt32, memacc.type); - m.Store(memacc.type, m.Parameter(0), m.Parameter(1), m.Parameter(2)); + m.Store(memacc.type, m.Parameter(0), m.Parameter(1), m.Parameter(2), + kNoWriteBarrier); m.Return(m.Int32Constant(0)); Stream s = m.Build(); ASSERT_EQ(1U, s.size()); @@ -2112,8 +2172,8 @@ TEST_P(InstructionSelectorMemoryAccessTest, StoreWithImmediateIndex) { const MemoryAccess memacc = GetParam(); TRACED_FOREACH(int32_t, index, memacc.immediates) { StreamBuilder m(this, kMachInt32, kMachPtr, memacc.type); - m.Store(memacc.type, m.Parameter(0), m.Int32Constant(index), - m.Parameter(1)); + m.Store(memacc.type, m.Parameter(0), m.Int32Constant(index), m.Parameter(1), + kNoWriteBarrier); m.Return(m.Int32Constant(0)); Stream s = m.Build(); ASSERT_EQ(1U, s.size()); @@ -2473,6 +2533,71 @@ TEST_F(InstructionSelectorTest, Word32EqualZeroWithWord32Equal) { } } +namespace { + +struct IntegerCmp { + MachInst2 mi; + FlagsCondition cond; +}; + + +std::ostream& operator<<(std::ostream& os, const IntegerCmp& cmp) { + return os << cmp.mi; +} + + +// ARM64 32-bit integer comparison instructions. +const IntegerCmp kIntegerCmpInstructions[] = { + {{&RawMachineAssembler::Word32Equal, "Word32Equal", kArm64Cmp32, + kMachInt32}, + kEqual}, + {{&RawMachineAssembler::Int32LessThan, "Int32LessThan", kArm64Cmp32, + kMachInt32}, + kSignedLessThan}, + {{&RawMachineAssembler::Int32LessThanOrEqual, "Int32LessThanOrEqual", + kArm64Cmp32, kMachInt32}, + kSignedLessThanOrEqual}, + {{&RawMachineAssembler::Uint32LessThan, "Uint32LessThan", kArm64Cmp32, + kMachUint32}, + kUnsignedLessThan}, + {{&RawMachineAssembler::Uint32LessThanOrEqual, "Uint32LessThanOrEqual", + kArm64Cmp32, kMachUint32}, + kUnsignedLessThanOrEqual}}; + +} // namespace + + +TEST_F(InstructionSelectorTest, Word32CompareNegateWithWord32Shift) { + TRACED_FOREACH(IntegerCmp, cmp, kIntegerCmpInstructions) { + TRACED_FOREACH(Shift, shift, kShiftInstructions) { + // Test 32-bit operations. Ignore ROR shifts, as compare-negate does not + // support them. + if (shift.mi.machine_type != kMachInt32 || + shift.mi.arch_opcode == kArm64Ror32) { + continue; + } + + TRACED_FORRANGE(int32_t, imm, -32, 63) { + StreamBuilder m(this, kMachInt32, kMachInt32, kMachInt32); + Node* const p0 = m.Parameter(0); + Node* const p1 = m.Parameter(1); + Node* r = (m.*shift.mi.constructor)(p1, m.Int32Constant(imm)); + m.Return( + (m.*cmp.mi.constructor)(p0, m.Int32Sub(m.Int32Constant(0), r))); + Stream s = m.Build(); + ASSERT_EQ(1U, s.size()); + EXPECT_EQ(kArm64Cmn32, s[0]->arch_opcode()); + EXPECT_EQ(3U, s[0]->InputCount()); + EXPECT_EQ(shift.mode, s[0]->addressing_mode()); + EXPECT_EQ(imm, s.ToInt32(s[0]->InputAt(2))); + EXPECT_EQ(1U, s[0]->OutputCount()); + EXPECT_EQ(kFlags_set, s[0]->flags_mode()); + EXPECT_EQ(cmp.cond, s[0]->flags_condition()); + } + } + } +} + // ----------------------------------------------------------------------------- // Miscellaneous @@ -3054,6 +3179,78 @@ TEST_F(InstructionSelectorTest, Float64SubWithMinusZero) { EXPECT_EQ(s.ToVreg(n), s.ToVreg(s[0]->Output())); } + +TEST_F(InstructionSelectorTest, Float32Max) { + StreamBuilder m(this, kMachFloat32, kMachFloat32, kMachFloat32); + Node* const p0 = m.Parameter(0); + Node* const p1 = m.Parameter(1); + Node* const n = m.Float32Max(p0, p1); + m.Return(n); + Stream s = m.Build(); + // Float32Max is `(b < a) ? a : b`. + ASSERT_EQ(1U, s.size()); + EXPECT_EQ(kArm64Float32Max, 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))); + ASSERT_EQ(1U, s[0]->OutputCount()); + EXPECT_EQ(s.ToVreg(n), s.ToVreg(s[0]->Output())); +} + + +TEST_F(InstructionSelectorTest, Float32Min) { + StreamBuilder m(this, kMachFloat32, kMachFloat32, kMachFloat32); + Node* const p0 = m.Parameter(0); + Node* const p1 = m.Parameter(1); + Node* const n = m.Float32Min(p0, p1); + m.Return(n); + Stream s = m.Build(); + // Float32Min is `(a < b) ? a : b`. + ASSERT_EQ(1U, s.size()); + EXPECT_EQ(kArm64Float32Min, 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))); + ASSERT_EQ(1U, s[0]->OutputCount()); + EXPECT_EQ(s.ToVreg(n), s.ToVreg(s[0]->Output())); +} + + +TEST_F(InstructionSelectorTest, Float64Max) { + StreamBuilder m(this, kMachFloat64, kMachFloat64, kMachFloat64); + Node* const p0 = m.Parameter(0); + Node* const p1 = m.Parameter(1); + Node* const n = m.Float64Max(p0, p1); + m.Return(n); + Stream s = m.Build(); + // Float64Max is `(b < a) ? a : b`. + ASSERT_EQ(1U, s.size()); + EXPECT_EQ(kArm64Float64Max, 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))); + ASSERT_EQ(1U, s[0]->OutputCount()); + EXPECT_EQ(s.ToVreg(n), s.ToVreg(s[0]->Output())); +} + + +TEST_F(InstructionSelectorTest, Float64Min) { + StreamBuilder m(this, kMachFloat64, kMachFloat64, kMachFloat64); + Node* const p0 = m.Parameter(0); + Node* const p1 = m.Parameter(1); + Node* const n = m.Float64Min(p0, p1); + m.Return(n); + Stream s = m.Build(); + // Float64Min is `(a < b) ? a : b`. + ASSERT_EQ(1U, s.size()); + EXPECT_EQ(kArm64Float64Min, 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))); + ASSERT_EQ(1U, s[0]->OutputCount()); + EXPECT_EQ(s.ToVreg(n), s.ToVreg(s[0]->Output())); +} + } // namespace compiler } // namespace internal } // namespace v8 diff --git a/deps/v8/test/unittests/compiler/binary-operator-reducer-unittest.cc b/deps/v8/test/unittests/compiler/binary-operator-reducer-unittest.cc new file mode 100644 index 0000000000..5d223446e2 --- /dev/null +++ b/deps/v8/test/unittests/compiler/binary-operator-reducer-unittest.cc @@ -0,0 +1,94 @@ +// 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/binary-operator-reducer.h" +#include "src/compiler/common-operator.h" +#include "src/compiler/machine-operator.h" +#include "src/compiler/machine-type.h" +#include "src/compiler/node-properties.h" +#include "src/compiler/operator.h" +#include "src/compiler/simplified-operator.h" +#include "src/types-inl.h" +#include "test/unittests/compiler/graph-reducer-unittest.h" +#include "test/unittests/compiler/graph-unittest.h" +#include "test/unittests/compiler/node-test-utils.h" + +using testing::StrictMock; + +namespace v8 { +namespace internal { +namespace compiler { + +class BinaryOperatorReducerTest : public TypedGraphTest { + public: + explicit BinaryOperatorReducerTest(int num_parameters = 1) + : TypedGraphTest(num_parameters), machine_(zone()), simplified_(zone()) {} + ~BinaryOperatorReducerTest() override {} + + protected: + Reduction Reduce(AdvancedReducer::Editor* editor, Node* node) { + BinaryOperatorReducer reducer(editor, graph(), common(), machine()); + return reducer.Reduce(node); + } + + Reduction Reduce(Node* node) { + StrictMock<MockAdvancedReducerEditor> editor; + return Reduce(&editor, node); + } + + MachineOperatorBuilder* machine() { return &machine_; } + SimplifiedOperatorBuilder* simplified() { return &simplified_; } + + private: + MachineOperatorBuilder machine_; + SimplifiedOperatorBuilder simplified_; +}; + + +TEST_F(BinaryOperatorReducerTest, Div52OfMul52) { + // This reduction applies only to 64bit arch + if (!machine()->Is64()) return; + + Node* p0 = Parameter(0); + Node* p1 = Parameter(1); + Node* t0 = graph()->NewNode(machine()->ChangeInt32ToFloat64(), p0); + Node* t1 = graph()->NewNode(machine()->ChangeInt32ToFloat64(), p1); + + Type* mul_range = Type::Range(0x0, 0xFFFFFFFFFFFFFULL, graph()->zone()); + Node* mul = graph()->NewNode(machine()->Float64Mul(), t0, t1); + NodeProperties::SetType( + mul, Type::Intersect(mul_range, Type::Number(), graph()->zone())); + + Node* mul_replacement; + auto mul_matcher = IsInt64Mul(p0, p1); + { + StrictMock<MockAdvancedReducerEditor> editor; + + EXPECT_CALL(editor, Revisit(mul_matcher)); + + Reduction r = Reduce(&editor, mul); + ASSERT_TRUE(r.Changed()); + mul_replacement = r.replacement(); + EXPECT_THAT(mul_replacement, IsRoundInt64ToFloat64(mul_matcher)); + } + + { + StrictMock<MockAdvancedReducerEditor> editor; + + Node* power = Float64Constant(0x4000000); + Node* div = + graph()->NewNode(machine()->Float64Div(), mul_replacement, power); + + auto shr_matcher = IsWord64Shr(mul_matcher, IsInt64Constant(26)); + EXPECT_CALL(editor, Revisit(shr_matcher)); + + Reduction r = Reduce(&editor, div); + ASSERT_TRUE(r.Changed()); + EXPECT_THAT(r.replacement(), IsRoundInt64ToFloat64(shr_matcher)); + } +} + +} // namespace compiler +} // namespace internal +} // namespace v8 diff --git a/deps/v8/test/unittests/compiler/branch-elimination-unittest.cc b/deps/v8/test/unittests/compiler/branch-elimination-unittest.cc new file mode 100644 index 0000000000..efa490d7ec --- /dev/null +++ b/deps/v8/test/unittests/compiler/branch-elimination-unittest.cc @@ -0,0 +1,204 @@ +// 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/branch-elimination.h" +#include "src/compiler/js-graph.h" +#include "src/compiler/linkage.h" +#include "src/compiler/node-properties.h" +#include "test/unittests/compiler/compiler-test-utils.h" +#include "test/unittests/compiler/graph-unittest.h" +#include "test/unittests/compiler/node-test-utils.h" +#include "testing/gmock-support.h" + +namespace v8 { +namespace internal { +namespace compiler { + +class BranchEliminationTest : public TypedGraphTest { + public: + BranchEliminationTest() + : machine_(zone(), kMachPtr, MachineOperatorBuilder::kNoFlags) {} + + MachineOperatorBuilder* machine() { return &machine_; } + + void Reduce() { + JSOperatorBuilder javascript(zone()); + JSGraph jsgraph(isolate(), graph(), common(), &javascript, nullptr, + machine()); + GraphReducer graph_reducer(zone(), graph(), jsgraph.Dead()); + BranchElimination branch_condition_elimination(&graph_reducer, &jsgraph, + zone()); + graph_reducer.AddReducer(&branch_condition_elimination); + graph_reducer.ReduceGraph(); + } + + private: + MachineOperatorBuilder machine_; +}; + + +TEST_F(BranchEliminationTest, NestedBranchSameTrue) { + // { return (x ? (x ? 1 : 2) : 3; } + // should be reduced to + // { return (x ? 1 : 3; } + Node* condition = Parameter(0); + Node* outer_branch = + graph()->NewNode(common()->Branch(), condition, graph()->start()); + + Node* outer_if_true = graph()->NewNode(common()->IfTrue(), outer_branch); + Node* inner_branch = + graph()->NewNode(common()->Branch(), condition, outer_if_true); + Node* inner_if_true = graph()->NewNode(common()->IfTrue(), inner_branch); + Node* inner_if_false = graph()->NewNode(common()->IfFalse(), inner_branch); + Node* inner_merge = + graph()->NewNode(common()->Merge(2), inner_if_true, inner_if_false); + Node* inner_phi = + graph()->NewNode(common()->Phi(kMachInt32, 2), Int32Constant(1), + Int32Constant(2), inner_merge); + + Node* outer_if_false = graph()->NewNode(common()->IfFalse(), outer_branch); + Node* outer_merge = + graph()->NewNode(common()->Merge(2), inner_merge, outer_if_false); + Node* outer_phi = graph()->NewNode(common()->Phi(kMachInt32, 2), inner_phi, + Int32Constant(3), outer_merge); + + Node* ret = graph()->NewNode(common()->Return(), outer_phi, graph()->start(), + outer_merge); + graph()->SetEnd(graph()->NewNode(common()->End(1), ret)); + + Reduce(); + + // Outer branch should not be rewritten, the inner branch should be discarded. + EXPECT_THAT(outer_branch, IsBranch(condition, graph()->start())); + EXPECT_THAT(inner_phi, + IsPhi(kMachInt32, IsInt32Constant(1), IsInt32Constant(2), + IsMerge(outer_if_true, IsDead()))); +} + + +TEST_F(BranchEliminationTest, NestedBranchSameFalse) { + // { return (x ? 1 : (x ? 2 : 3); } + // should be reduced to + // { return (x ? 1 : 3; } + Node* condition = Parameter(0); + Node* outer_branch = + graph()->NewNode(common()->Branch(), condition, graph()->start()); + + Node* outer_if_true = graph()->NewNode(common()->IfTrue(), outer_branch); + + Node* outer_if_false = graph()->NewNode(common()->IfFalse(), outer_branch); + Node* inner_branch = + graph()->NewNode(common()->Branch(), condition, outer_if_false); + Node* inner_if_true = graph()->NewNode(common()->IfTrue(), inner_branch); + Node* inner_if_false = graph()->NewNode(common()->IfFalse(), inner_branch); + Node* inner_merge = + graph()->NewNode(common()->Merge(2), inner_if_true, inner_if_false); + Node* inner_phi = + graph()->NewNode(common()->Phi(kMachInt32, 2), Int32Constant(2), + Int32Constant(3), inner_merge); + + Node* outer_merge = + graph()->NewNode(common()->Merge(2), outer_if_true, inner_merge); + Node* outer_phi = graph()->NewNode(common()->Phi(kMachInt32, 2), + Int32Constant(1), inner_phi, outer_merge); + + Node* ret = graph()->NewNode(common()->Return(), outer_phi, graph()->start(), + outer_merge); + graph()->SetEnd(graph()->NewNode(common()->End(1), ret)); + + Reduce(); + + // Outer branch should not be rewritten, the inner branch should be discarded. + EXPECT_THAT(outer_branch, IsBranch(condition, graph()->start())); + EXPECT_THAT(inner_phi, + IsPhi(kMachInt32, IsInt32Constant(2), IsInt32Constant(3), + IsMerge(IsDead(), outer_if_false))); +} + + +TEST_F(BranchEliminationTest, BranchAfterDiamond) { + // { var y = x ? 1 : 2; return y + x ? 3 : 4; } + // should not be reduced. + Node* condition = Parameter(0); + + Node* branch1 = + graph()->NewNode(common()->Branch(), condition, graph()->start()); + Node* if_true1 = graph()->NewNode(common()->IfTrue(), branch1); + Node* if_false1 = graph()->NewNode(common()->IfFalse(), branch1); + Node* merge1 = graph()->NewNode(common()->Merge(2), if_true1, if_false1); + Node* phi1 = graph()->NewNode(common()->Phi(kMachInt32, 2), Int32Constant(1), + Int32Constant(2), merge1); + + Node* branch2 = graph()->NewNode(common()->Branch(), condition, merge1); + Node* if_true2 = graph()->NewNode(common()->IfTrue(), branch2); + Node* if_false2 = graph()->NewNode(common()->IfFalse(), branch2); + Node* merge2 = graph()->NewNode(common()->Merge(2), if_true2, if_false2); + Node* phi2 = graph()->NewNode(common()->Phi(kMachInt32, 2), Int32Constant(3), + Int32Constant(4), merge1); + + + Node* add = graph()->NewNode(machine()->Int32Add(), phi1, phi2); + Node* ret = + graph()->NewNode(common()->Return(), add, graph()->start(), merge2); + graph()->SetEnd(graph()->NewNode(common()->End(1), ret)); + + Reduce(); + + // Outer branch should not be rewritten, the inner branch condition should + // be true. + EXPECT_THAT(branch1, IsBranch(condition, graph()->start())); + EXPECT_THAT(branch2, IsBranch(condition, merge1)); +} + + +TEST_F(BranchEliminationTest, BranchInsideLoopSame) { + // if (x) while (x) { return 2; } else { return 1; } + // should be rewritten to + // if (x) while (true) { return 2; } else { return 1; } + + Node* condition = Parameter(0); + + Node* outer_branch = + graph()->NewNode(common()->Branch(), condition, graph()->start()); + Node* outer_if_true = graph()->NewNode(common()->IfTrue(), outer_branch); + + + Node* loop = graph()->NewNode(common()->Loop(1), outer_if_true); + Node* effect = + graph()->NewNode(common()->EffectPhi(1), graph()->start(), loop); + + Node* inner_branch = graph()->NewNode(common()->Branch(), condition, loop); + + Node* inner_if_true = graph()->NewNode(common()->IfTrue(), inner_branch); + Node* ret1 = graph()->NewNode(common()->Return(), Int32Constant(2), effect, + inner_if_true); + + Node* inner_if_false = graph()->NewNode(common()->IfFalse(), inner_branch); + loop->AppendInput(zone(), inner_if_false); + NodeProperties::ChangeOp(loop, common()->Loop(2)); + effect->InsertInput(zone(), 1, effect); + NodeProperties::ChangeOp(effect, common()->EffectPhi(2)); + + Node* outer_if_false = graph()->NewNode(common()->IfFalse(), outer_branch); + Node* outer_merge = + graph()->NewNode(common()->Merge(2), loop, outer_if_false); + Node* outer_ephi = graph()->NewNode(common()->EffectPhi(2), effect, + graph()->start(), outer_merge); + + Node* ret2 = graph()->NewNode(common()->Return(), Int32Constant(1), + outer_ephi, outer_merge); + + Node* terminate = graph()->NewNode(common()->Terminate(), effect, loop); + graph()->SetEnd(graph()->NewNode(common()->End(3), ret1, ret2, terminate)); + + Reduce(); + + // Outer branch should not be rewritten, the inner branch should be discarded. + EXPECT_THAT(outer_branch, IsBranch(condition, graph()->start())); + EXPECT_THAT(ret1, IsReturn(IsInt32Constant(2), effect, loop)); +} + +} // namespace compiler +} // namespace internal +} // namespace v8 diff --git a/deps/v8/test/unittests/compiler/bytecode-graph-builder-unittest.cc b/deps/v8/test/unittests/compiler/bytecode-graph-builder-unittest.cc index 22b9b893e8..27ff4ca359 100644 --- a/deps/v8/test/unittests/compiler/bytecode-graph-builder-unittest.cc +++ b/deps/v8/test/unittests/compiler/bytecode-graph-builder-unittest.cc @@ -51,8 +51,8 @@ Graph* BytecodeGraphBuilderTest::GetCompletedGraph() { CommonOperatorBuilder* common = new (zone()) CommonOperatorBuilder(zone()); JSOperatorBuilder* javascript = new (zone()) JSOperatorBuilder(zone()); Graph* graph = new (zone()) Graph(zone()); - JSGraph* jsgraph = - new (zone()) JSGraph(isolate(), graph, common, javascript, machine); + JSGraph* jsgraph = new (zone()) + JSGraph(isolate(), graph, common, javascript, nullptr, machine); Handle<String> name = factory()->NewStringFromStaticChars("test"); Handle<String> script = factory()->NewStringFromStaticChars("test() {}"); @@ -98,6 +98,7 @@ Matcher<Node*> BytecodeGraphBuilderTest::IsTrueConstant() { TEST_F(BytecodeGraphBuilderTest, ReturnUndefined) { array_builder()->set_locals_count(0); + array_builder()->set_context_count(0); array_builder()->set_parameter_count(1); array_builder()->LoadUndefined().Return(); @@ -113,6 +114,7 @@ TEST_F(BytecodeGraphBuilderTest, ReturnUndefined) { TEST_F(BytecodeGraphBuilderTest, ReturnNull) { array_builder()->set_locals_count(0); + array_builder()->set_context_count(0); array_builder()->set_parameter_count(1); array_builder()->LoadNull().Return(); @@ -126,6 +128,7 @@ TEST_F(BytecodeGraphBuilderTest, ReturnNull) { TEST_F(BytecodeGraphBuilderTest, ReturnTheHole) { array_builder()->set_locals_count(0); + array_builder()->set_context_count(0); array_builder()->set_parameter_count(1); array_builder()->LoadTheHole().Return(); @@ -141,6 +144,7 @@ TEST_F(BytecodeGraphBuilderTest, ReturnTheHole) { TEST_F(BytecodeGraphBuilderTest, ReturnTrue) { array_builder()->set_locals_count(0); + array_builder()->set_context_count(0); array_builder()->set_parameter_count(1); array_builder()->LoadTrue().Return(); @@ -156,6 +160,7 @@ TEST_F(BytecodeGraphBuilderTest, ReturnTrue) { TEST_F(BytecodeGraphBuilderTest, ReturnFalse) { array_builder()->set_locals_count(0); + array_builder()->set_context_count(0); array_builder()->set_parameter_count(1); array_builder()->LoadFalse().Return(); @@ -172,6 +177,7 @@ TEST_F(BytecodeGraphBuilderTest, ReturnFalse) { TEST_F(BytecodeGraphBuilderTest, ReturnInt8) { static const int kValue = 3; array_builder()->set_locals_count(0); + array_builder()->set_context_count(0); array_builder()->set_parameter_count(1); array_builder()->LoadLiteral(Smi::FromInt(kValue)).Return(); @@ -188,6 +194,7 @@ TEST_F(BytecodeGraphBuilderTest, ReturnInt8) { TEST_F(BytecodeGraphBuilderTest, ReturnDouble) { const double kValue = 0.123456789; array_builder()->set_locals_count(0); + array_builder()->set_context_count(0); array_builder()->set_parameter_count(1); array_builder()->LoadLiteral(factory()->NewHeapNumber(kValue)); array_builder()->Return(); @@ -204,10 +211,12 @@ TEST_F(BytecodeGraphBuilderTest, ReturnDouble) { TEST_F(BytecodeGraphBuilderTest, SimpleExpressionWithParameters) { array_builder()->set_locals_count(1); + array_builder()->set_context_count(0); array_builder()->set_parameter_count(3); array_builder() ->LoadAccumulatorWithRegister(array_builder()->Parameter(1)) - .BinaryOperation(Token::Value::ADD, array_builder()->Parameter(2)) + .BinaryOperation(Token::Value::ADD, array_builder()->Parameter(2), + Strength::WEAK) .StoreAccumulatorInRegister(interpreter::Register(0)) .Return(); @@ -226,12 +235,14 @@ TEST_F(BytecodeGraphBuilderTest, SimpleExpressionWithRegister) { static const int kLeft = -655371; static const int kRight = +2000000; array_builder()->set_locals_count(1); + array_builder()->set_context_count(0); array_builder()->set_parameter_count(1); array_builder() ->LoadLiteral(Smi::FromInt(kLeft)) .StoreAccumulatorInRegister(interpreter::Register(0)) .LoadLiteral(Smi::FromInt(kRight)) - .BinaryOperation(Token::Value::ADD, interpreter::Register(0)) + .BinaryOperation(Token::Value::ADD, interpreter::Register(0), + Strength::WEAK) .Return(); Graph* graph = GetCompletedGraph(); diff --git a/deps/v8/test/unittests/compiler/change-lowering-unittest.cc b/deps/v8/test/unittests/compiler/change-lowering-unittest.cc index fd2d7c4dae..aec568c9db 100644 --- a/deps/v8/test/unittests/compiler/change-lowering-unittest.cc +++ b/deps/v8/test/unittests/compiler/change-lowering-unittest.cc @@ -36,7 +36,8 @@ class ChangeLoweringTest : public TypedGraphTest { Reduction Reduce(Node* node) { MachineOperatorBuilder machine(zone(), WordRepresentation()); JSOperatorBuilder javascript(zone()); - JSGraph jsgraph(isolate(), graph(), common(), &javascript, &machine); + JSGraph jsgraph(isolate(), graph(), common(), &javascript, nullptr, + &machine); ChangeLowering reducer(&jsgraph); return reducer.Reduce(node); } @@ -120,24 +121,6 @@ TARGET_TEST_P(ChangeLoweringCommonTest, ChangeBoolToBit) { } -TARGET_TEST_P(ChangeLoweringCommonTest, ChangeFloat64ToTagged) { - Node* value = Parameter(Type::Number()); - Reduction r = - Reduce(graph()->NewNode(simplified()->ChangeFloat64ToTagged(), value)); - ASSERT_TRUE(r.Changed()); - Capture<Node*> heap_number; - EXPECT_THAT( - r.replacement(), - IsFinish( - AllOf(CaptureEq(&heap_number), - IsAllocateHeapNumber(IsValueEffect(value), graph()->start())), - IsStore(StoreRepresentation(kMachFloat64, kNoWriteBarrier), - CaptureEq(&heap_number), - IsIntPtrConstant(HeapNumber::kValueOffset - kHeapObjectTag), - value, CaptureEq(&heap_number), graph()->start()))); -} - - TARGET_TEST_P(ChangeLoweringCommonTest, ChangeInt32ToTaggedWithSignedSmall) { Node* value = Parameter(Type::SignedSmall()); Reduction r = @@ -218,14 +201,15 @@ TARGET_TEST_F(ChangeLowering32Test, ChangeInt32ToTagged) { EXPECT_THAT( r.replacement(), IsPhi(kMachAnyTagged, - IsFinish(AllOf(CaptureEq(&heap_number), - IsAllocateHeapNumber(_, CaptureEq(&if_true))), - IsStore(StoreRepresentation(kMachFloat64, kNoWriteBarrier), - CaptureEq(&heap_number), - IsIntPtrConstant(HeapNumber::kValueOffset - - kHeapObjectTag), - IsChangeInt32ToFloat64(value), - CaptureEq(&heap_number), CaptureEq(&if_true))), + IsFinishRegion( + AllOf(CaptureEq(&heap_number), + IsAllocateHeapNumber(_, CaptureEq(&if_true))), + IsStore( + StoreRepresentation(kMachFloat64, kNoWriteBarrier), + CaptureEq(&heap_number), + IsIntPtrConstant(HeapNumber::kValueOffset - kHeapObjectTag), + IsChangeInt32ToFloat64(value), CaptureEq(&heap_number), + CaptureEq(&if_true))), IsProjection(0, AllOf(CaptureEq(&add), IsInt32AddWithOverflow(value, value))), IsMerge(AllOf(CaptureEq(&if_true), IsIfTrue(CaptureEq(&branch))), @@ -319,14 +303,15 @@ TARGET_TEST_F(ChangeLowering32Test, ChangeUint32ToTagged) { IsPhi( kMachAnyTagged, IsWord32Shl(value, IsInt32Constant(kSmiTagSize + kSmiShiftSize)), - IsFinish(AllOf(CaptureEq(&heap_number), - IsAllocateHeapNumber(_, CaptureEq(&if_false))), - IsStore(StoreRepresentation(kMachFloat64, kNoWriteBarrier), - CaptureEq(&heap_number), - IsInt32Constant(HeapNumber::kValueOffset - - kHeapObjectTag), - IsChangeUint32ToFloat64(value), - CaptureEq(&heap_number), CaptureEq(&if_false))), + IsFinishRegion( + AllOf(CaptureEq(&heap_number), + IsAllocateHeapNumber(_, CaptureEq(&if_false))), + IsStore( + StoreRepresentation(kMachFloat64, kNoWriteBarrier), + CaptureEq(&heap_number), + IsInt32Constant(HeapNumber::kValueOffset - kHeapObjectTag), + IsChangeUint32ToFloat64(value), CaptureEq(&heap_number), + CaptureEq(&if_false))), IsMerge(IsIfTrue(AllOf( CaptureEq(&branch), IsBranch(IsUint32LessThanOrEqual( @@ -443,14 +428,15 @@ TARGET_TEST_F(ChangeLowering64Test, ChangeUint32ToTagged) { kMachAnyTagged, IsWord64Shl(IsChangeUint32ToUint64(value), IsInt64Constant(kSmiTagSize + kSmiShiftSize)), - IsFinish(AllOf(CaptureEq(&heap_number), - IsAllocateHeapNumber(_, CaptureEq(&if_false))), - IsStore(StoreRepresentation(kMachFloat64, kNoWriteBarrier), - CaptureEq(&heap_number), - IsInt64Constant(HeapNumber::kValueOffset - - kHeapObjectTag), - IsChangeUint32ToFloat64(value), - CaptureEq(&heap_number), CaptureEq(&if_false))), + IsFinishRegion( + AllOf(CaptureEq(&heap_number), + IsAllocateHeapNumber(_, CaptureEq(&if_false))), + IsStore( + StoreRepresentation(kMachFloat64, kNoWriteBarrier), + CaptureEq(&heap_number), + IsInt64Constant(HeapNumber::kValueOffset - kHeapObjectTag), + IsChangeUint32ToFloat64(value), CaptureEq(&heap_number), + CaptureEq(&if_false))), IsMerge(IsIfTrue(AllOf( CaptureEq(&branch), IsBranch(IsUint32LessThanOrEqual( diff --git a/deps/v8/test/unittests/compiler/common-operator-unittest.cc b/deps/v8/test/unittests/compiler/common-operator-unittest.cc index 66eb140d27..64c5f73d27 100644 --- a/deps/v8/test/unittests/compiler/common-operator-unittest.cc +++ b/deps/v8/test/unittests/compiler/common-operator-unittest.cc @@ -53,7 +53,6 @@ const SharedOperator kSharedOperators[] = { SHARED(IfFalse, Operator::kKontrol, 0, 0, 1, 0, 0, 1), SHARED(IfSuccess, Operator::kKontrol, 0, 0, 1, 0, 0, 1), SHARED(Throw, Operator::kKontrol, 1, 1, 1, 0, 0, 1), - SHARED(Return, Operator::kNoThrow, 1, 1, 1, 0, 0, 1), SHARED(Terminate, Operator::kKontrol, 0, 1, 1, 0, 0, 1) #undef SHARED }; @@ -188,6 +187,22 @@ TEST_F(CommonOperatorTest, End) { } +TEST_F(CommonOperatorTest, Return) { + TRACED_FOREACH(int, input_count, kArguments) { + const Operator* const op = common()->Return(input_count); + EXPECT_EQ(IrOpcode::kReturn, op->opcode()); + EXPECT_EQ(Operator::kNoThrow, op->properties()); + EXPECT_EQ(input_count, op->ValueInputCount()); + EXPECT_EQ(1, op->EffectInputCount()); + EXPECT_EQ(1, op->ControlInputCount()); + EXPECT_EQ(2 + input_count, OperatorProperties::GetTotalInputCount(op)); + EXPECT_EQ(0, op->ValueOutputCount()); + EXPECT_EQ(0, op->EffectOutputCount()); + EXPECT_EQ(1, op->ControlOutputCount()); + } +} + + TEST_F(CommonOperatorTest, Branch) { TRACED_FOREACH(BranchHint, hint, kBranchHints) { const Operator* const op = common()->Branch(hint); @@ -343,28 +358,24 @@ TEST_F(CommonOperatorTest, NumberConstant) { } -TEST_F(CommonOperatorTest, ValueEffect) { - TRACED_FOREACH(int, arguments, kArguments) { - const Operator* op = common()->ValueEffect(arguments); - EXPECT_EQ(arguments, op->ValueInputCount()); - EXPECT_EQ(arguments, OperatorProperties::GetTotalInputCount(op)); - EXPECT_EQ(0, op->ControlOutputCount()); - EXPECT_EQ(1, op->EffectOutputCount()); - EXPECT_EQ(0, op->ValueOutputCount()); - } +TEST_F(CommonOperatorTest, BeginRegion) { + const Operator* op = common()->BeginRegion(); + EXPECT_EQ(1, op->EffectInputCount()); + EXPECT_EQ(1, OperatorProperties::GetTotalInputCount(op)); + EXPECT_EQ(0, op->ControlOutputCount()); + EXPECT_EQ(1, op->EffectOutputCount()); + EXPECT_EQ(0, op->ValueOutputCount()); } -TEST_F(CommonOperatorTest, Finish) { - TRACED_FOREACH(int, arguments, kArguments) { - const Operator* op = common()->Finish(arguments); - EXPECT_EQ(1, op->ValueInputCount()); - EXPECT_EQ(arguments, op->EffectInputCount()); - EXPECT_EQ(arguments + 1, OperatorProperties::GetTotalInputCount(op)); - EXPECT_EQ(0, op->ControlOutputCount()); - EXPECT_EQ(0, op->EffectOutputCount()); - EXPECT_EQ(1, op->ValueOutputCount()); - } +TEST_F(CommonOperatorTest, FinishRegion) { + const Operator* op = common()->FinishRegion(); + EXPECT_EQ(1, op->ValueInputCount()); + EXPECT_EQ(1, op->EffectInputCount()); + EXPECT_EQ(2, OperatorProperties::GetTotalInputCount(op)); + EXPECT_EQ(0, op->ControlOutputCount()); + EXPECT_EQ(1, op->EffectOutputCount()); + EXPECT_EQ(1, op->ValueOutputCount()); } } // namespace compiler diff --git a/deps/v8/test/unittests/compiler/ia32/instruction-selector-ia32-unittest.cc b/deps/v8/test/unittests/compiler/ia32/instruction-selector-ia32-unittest.cc index 4c8e0c0431..1e07d7a41b 100644 --- a/deps/v8/test/unittests/compiler/ia32/instruction-selector-ia32-unittest.cc +++ b/deps/v8/test/unittests/compiler/ia32/instruction-selector-ia32-unittest.cc @@ -249,7 +249,8 @@ TEST_P(InstructionSelectorMemoryAccessTest, LoadWithImmediateIndex) { TEST_P(InstructionSelectorMemoryAccessTest, StoreWithParameters) { const MemoryAccess memacc = GetParam(); StreamBuilder m(this, kMachInt32, kMachPtr, kMachInt32, memacc.type); - m.Store(memacc.type, m.Parameter(0), m.Parameter(1), m.Parameter(2)); + m.Store(memacc.type, m.Parameter(0), m.Parameter(1), m.Parameter(2), + kNoWriteBarrier); m.Return(m.Int32Constant(0)); Stream s = m.Build(); ASSERT_EQ(1U, s.size()); @@ -263,7 +264,8 @@ TEST_P(InstructionSelectorMemoryAccessTest, StoreWithImmediateBase) { const MemoryAccess memacc = GetParam(); TRACED_FOREACH(int32_t, base, kImmediates) { StreamBuilder m(this, kMachInt32, kMachInt32, memacc.type); - m.Store(memacc.type, m.Int32Constant(base), m.Parameter(0), m.Parameter(1)); + m.Store(memacc.type, m.Int32Constant(base), m.Parameter(0), m.Parameter(1), + kNoWriteBarrier); m.Return(m.Int32Constant(0)); Stream s = m.Build(); ASSERT_EQ(1U, s.size()); @@ -284,8 +286,8 @@ TEST_P(InstructionSelectorMemoryAccessTest, StoreWithImmediateIndex) { const MemoryAccess memacc = GetParam(); TRACED_FOREACH(int32_t, index, kImmediates) { StreamBuilder m(this, kMachInt32, kMachPtr, memacc.type); - m.Store(memacc.type, m.Parameter(0), m.Int32Constant(index), - m.Parameter(1)); + m.Store(memacc.type, m.Parameter(0), m.Int32Constant(index), m.Parameter(1), + kNoWriteBarrier); m.Return(m.Int32Constant(0)); Stream s = m.Build(); ASSERT_EQ(1U, s.size()); @@ -319,7 +321,7 @@ class AddressingModeUnitTest : public InstructionSelectorTest { void Run(Node* base, Node* load_index, Node* store_index, AddressingMode mode) { Node* load = m->Load(kMachInt32, base, load_index); - m->Store(kMachInt32, base, store_index, load); + m->Store(kMachInt32, base, store_index, load, kNoWriteBarrier); m->Return(m->Int32Constant(0)); Stream s = m->Build(); ASSERT_EQ(2U, s.size()); diff --git a/deps/v8/test/unittests/compiler/instruction-selector-unittest.cc b/deps/v8/test/unittests/compiler/instruction-selector-unittest.cc index e14382e914..8b182a76ba 100644 --- a/deps/v8/test/unittests/compiler/instruction-selector-unittest.cc +++ b/deps/v8/test/unittests/compiler/instruction-selector-unittest.cc @@ -4,6 +4,7 @@ #include "test/unittests/compiler/instruction-selector-unittest.h" +#include "src/code-factory.h" #include "src/compiler/graph.h" #include "src/compiler/schedule.h" #include "src/flags.h" @@ -51,7 +52,8 @@ InstructionSelectorTest::Stream InstructionSelectorTest::StreamBuilder::Build( if (FLAG_trace_turbo) { OFStream out(stdout); PrintableInstructionSequence printable = { - RegisterConfiguration::ArchDefault(), &sequence}; + RegisterConfiguration::ArchDefault(RegisterConfiguration::TURBOFAN), + &sequence}; out << "=== Code sequence after instruction selection ===" << std::endl << printable; } @@ -127,8 +129,7 @@ bool InstructionSelectorTest::Stream::IsFixed(const InstructionOperand* operand, if (!operand->IsUnallocated()) return false; const UnallocatedOperand* unallocated = UnallocatedOperand::cast(operand); if (!unallocated->HasFixedRegisterPolicy()) return false; - const int index = Register::ToAllocationIndex(reg); - return unallocated->fixed_register_index() == index; + return unallocated->fixed_register_index() == reg.code(); } @@ -242,13 +243,14 @@ TARGET_TEST_F(InstructionSelectorTest, ReferenceParameter) { // ----------------------------------------------------------------------------- -// Finish. +// FinishRegion. -TARGET_TEST_F(InstructionSelectorTest, Finish) { +TARGET_TEST_F(InstructionSelectorTest, FinishRegion) { StreamBuilder m(this, kMachAnyTagged, kMachAnyTagged); Node* param = m.Parameter(0); - Node* finish = m.AddNode(m.common()->Finish(1), param, m.graph()->start()); + Node* finish = + m.AddNode(m.common()->FinishRegion(), param, m.graph()->start()); m.Return(finish); Stream s = m.Build(kAllInstructions); ASSERT_EQ(4U, s.size()); @@ -334,8 +336,9 @@ TARGET_TEST_F(InstructionSelectorTest, ValueEffect) { Stream s1 = m1.Build(kAllInstructions); StreamBuilder m2(this, kMachInt32, kMachPtr); Node* p2 = m2.Parameter(0); - m2.Return(m2.AddNode(m2.machine()->Load(kMachInt32), p2, m2.Int32Constant(0), - m2.AddNode(m2.common()->ValueEffect(1), p2))); + m2.Return( + m2.AddNode(m2.machine()->Load(kMachInt32), p2, m2.Int32Constant(0), + m2.AddNode(m2.common()->BeginRegion(), m2.graph()->start()))); Stream s2 = m2.Build(kAllInstructions); EXPECT_LE(3U, s1.size()); ASSERT_EQ(s1.size(), s2.size()); @@ -369,18 +372,20 @@ TARGET_TEST_F(InstructionSelectorTest, CallJSFunctionWithDeopt) { CallDescriptor* descriptor = Linkage::GetJSCallDescriptor( zone(), false, 1, CallDescriptor::kNeedsFrameState); + // Build frame state for the state before the call. Node* parameters = m.AddNode(m.common()->TypedStateValues(&int32_type), m.Int32Constant(1)); Node* locals = m.AddNode(m.common()->TypedStateValues(&empty_types)); Node* stack = m.AddNode(m.common()->TypedStateValues(&empty_types)); - Node* context_dummy = m.Int32Constant(0); - + Node* context_sentinel = m.Int32Constant(0); Node* state_node = m.AddNode( m.common()->FrameState(bailout_id, OutputFrameStateCombine::Push(), m.GetFrameStateFunctionInfo(1, 0)), - parameters, locals, stack, context_dummy, function_node, + parameters, locals, stack, context_sentinel, function_node, m.UndefinedConstant()); - Node* args[] = {receiver, context}; + + // Build the call. + Node* args[] = {receiver, m.Int32Constant(1), context}; Node* call = m.CallNWithFrameState(descriptor, function_node, args, state_node); m.Return(call); @@ -402,7 +407,7 @@ TARGET_TEST_F(InstructionSelectorTest, CallJSFunctionWithDeopt) { } -TARGET_TEST_F(InstructionSelectorTest, CallFunctionStubWithDeopt) { +TARGET_TEST_F(InstructionSelectorTest, CallStubWithDeopt) { StreamBuilder m(this, kMachAnyTagged, kMachAnyTagged, kMachAnyTagged, kMachAnyTagged); @@ -417,6 +422,11 @@ TARGET_TEST_F(InstructionSelectorTest, CallFunctionStubWithDeopt) { ZoneVector<MachineType> float64_type(1, kMachFloat64, zone()); ZoneVector<MachineType> tagged_type(1, kMachAnyTagged, zone()); + Callable callable = CodeFactory::ToObject(isolate()); + CallDescriptor* descriptor = Linkage::GetStubCallDescriptor( + isolate(), zone(), callable.descriptor(), 1, + CallDescriptor::kNeedsFrameState, Operator::kNoProperties); + // Build frame state for the state before the call. Node* parameters = m.AddNode(m.common()->TypedStateValues(&int32_type), m.Int32Constant(43)); @@ -424,18 +434,17 @@ TARGET_TEST_F(InstructionSelectorTest, CallFunctionStubWithDeopt) { m.Float64Constant(0.5)); Node* stack = m.AddNode(m.common()->TypedStateValues(&tagged_type), m.UndefinedConstant()); - Node* context_sentinel = m.Int32Constant(0); - Node* frame_state_before = m.AddNode( + Node* state_node = m.AddNode( m.common()->FrameState(bailout_id_before, OutputFrameStateCombine::Push(), m.GetFrameStateFunctionInfo(1, 1)), parameters, locals, stack, context_sentinel, function_node, m.UndefinedConstant()); // Build the call. - Node* call = m.CallFunctionStub0(function_node, receiver, context, - frame_state_before, CALL_AS_METHOD); - + Node* args[] = {function_node, receiver, context}; + Node* stub_code = m.HeapConstant(callable.code()); + Node* call = m.CallNWithFrameState(descriptor, stub_code, args, state_node); m.Return(call); Stream s = m.Build(kAllExceptNopInstructions); @@ -496,8 +505,7 @@ TARGET_TEST_F(InstructionSelectorTest, CallFunctionStubWithDeopt) { } -TARGET_TEST_F(InstructionSelectorTest, - CallFunctionStubDeoptRecursiveFrameState) { +TARGET_TEST_F(InstructionSelectorTest, CallStubWithDeoptRecursiveFrameState) { StreamBuilder m(this, kMachAnyTagged, kMachAnyTagged, kMachAnyTagged, kMachAnyTagged); @@ -508,11 +516,17 @@ TARGET_TEST_F(InstructionSelectorTest, Node* function_node = m.Parameter(0); Node* receiver = m.Parameter(1); Node* context = m.Int32Constant(66); + Node* context2 = m.Int32Constant(46); ZoneVector<MachineType> int32_type(1, kMachInt32, zone()); ZoneVector<MachineType> int32x2_type(2, kMachInt32, zone()); ZoneVector<MachineType> float64_type(1, kMachFloat64, zone()); + Callable callable = CodeFactory::ToObject(isolate()); + CallDescriptor* descriptor = Linkage::GetStubCallDescriptor( + isolate(), zone(), callable.descriptor(), 1, + CallDescriptor::kNeedsFrameState, Operator::kNoProperties); + // Build frame state for the state before the call. Node* parameters = m.AddNode(m.common()->TypedStateValues(&int32_type), m.Int32Constant(63)); @@ -526,23 +540,22 @@ TARGET_TEST_F(InstructionSelectorTest, m.GetFrameStateFunctionInfo(1, 1)), parameters, locals, stack, context, function_node, m.UndefinedConstant()); - Node* context2 = m.Int32Constant(46); Node* parameters2 = m.AddNode(m.common()->TypedStateValues(&int32_type), m.Int32Constant(43)); Node* locals2 = m.AddNode(m.common()->TypedStateValues(&float64_type), m.Float64Constant(0.25)); Node* stack2 = m.AddNode(m.common()->TypedStateValues(&int32x2_type), m.Int32Constant(44), m.Int32Constant(45)); - Node* frame_state_before = m.AddNode( + Node* state_node = m.AddNode( m.common()->FrameState(bailout_id_before, OutputFrameStateCombine::Push(), m.GetFrameStateFunctionInfo(1, 1)), parameters2, locals2, stack2, context2, function_node, frame_state_parent); // Build the call. - Node* call = m.CallFunctionStub0(function_node, receiver, context2, - frame_state_before, CALL_AS_METHOD); - + Node* args[] = {function_node, receiver, context2}; + Node* stub_code = m.HeapConstant(callable.code()); + Node* call = m.CallNWithFrameState(descriptor, stub_code, args, state_node); m.Return(call); Stream s = m.Build(kAllExceptNopInstructions); diff --git a/deps/v8/test/unittests/compiler/instruction-sequence-unittest.cc b/deps/v8/test/unittests/compiler/instruction-sequence-unittest.cc index 65a7f299c5..51112a6470 100644 --- a/deps/v8/test/unittests/compiler/instruction-sequence-unittest.cc +++ b/deps/v8/test/unittests/compiler/instruction-sequence-unittest.cc @@ -20,6 +20,14 @@ static char register_names_[10 * (RegisterConfiguration::kMaxGeneralRegisters + RegisterConfiguration::kMaxDoubleRegisters)]; +namespace { +static int allocatable_codes[InstructionSequenceTest::kDefaultNRegs] = { + 0, 1, 2, 3, 4, 5, 6, 7}; +static int allocatable_double_codes[InstructionSequenceTest::kDefaultNRegs] = { + 0, 1, 2, 3, 4, 5, 6, 7}; +} + + static void InitializeRegisterNames() { char* loc = register_names_; for (int i = 0; i < RegisterConfiguration::kMaxGeneralRegisters; ++i) { @@ -59,8 +67,10 @@ void InstructionSequenceTest::SetNumRegs(int num_general_registers, RegisterConfiguration* InstructionSequenceTest::config() { if (config_.is_empty()) { config_.Reset(new RegisterConfiguration( - num_general_registers_, num_double_registers_, num_double_registers_, - general_register_names_, double_register_names_)); + num_general_registers_, num_double_registers_, num_general_registers_, + num_double_registers_, num_double_registers_, allocatable_codes, + allocatable_double_codes, general_register_names_, + double_register_names_)); } return config_.get(); } diff --git a/deps/v8/test/unittests/compiler/instruction-sequence-unittest.h b/deps/v8/test/unittests/compiler/instruction-sequence-unittest.h index 54317ede21..eb86bd9174 100644 --- a/deps/v8/test/unittests/compiler/instruction-sequence-unittest.h +++ b/deps/v8/test/unittests/compiler/instruction-sequence-unittest.h @@ -15,7 +15,7 @@ namespace compiler { class InstructionSequenceTest : public TestWithIsolateAndZone { public: - static const int kDefaultNRegs = 4; + static const int kDefaultNRegs = 8; static const int kNoValue = kMinInt; typedef RpoNumber Rpo; @@ -36,6 +36,7 @@ class InstructionSequenceTest : public TestWithIsolateAndZone { kFixedRegister, kSlot, kFixedSlot, + kExplicit, kImmediate, kNone, kConstant, @@ -57,6 +58,11 @@ class InstructionSequenceTest : public TestWithIsolateAndZone { static TestOperand Same() { return TestOperand(kSameAsFirst, VReg()); } + static TestOperand ExplicitReg(int index) { + TestOperandType type = kExplicit; + return TestOperand(type, VReg(), index); + } + static TestOperand Reg(VReg vreg, int index = kNoValue) { TestOperandType type = kRegister; if (index != kNoValue) type = kFixedRegister; diff --git a/deps/v8/test/unittests/compiler/interpreter-assembler-unittest.cc b/deps/v8/test/unittests/compiler/interpreter-assembler-unittest.cc index 48aa8f1ec4..a7712880f7 100644 --- a/deps/v8/test/unittests/compiler/interpreter-assembler-unittest.cc +++ b/deps/v8/test/unittests/compiler/interpreter-assembler-unittest.cc @@ -59,6 +59,13 @@ Matcher<Node*> IsWordSar(const Matcher<Node*>& lhs_matcher, } +Matcher<Node*> IsWordOr(const Matcher<Node*>& lhs_matcher, + const Matcher<Node*>& rhs_matcher) { + return kPointerSize == 8 ? IsWord64Or(lhs_matcher, rhs_matcher) + : IsWord32Or(lhs_matcher, rhs_matcher); +} + + Matcher<Node*> InterpreterAssemblerTest::InterpreterAssemblerForTest::IsLoad( const Matcher<LoadRepresentation>& rep_matcher, const Matcher<Node*>& base_matcher, const Matcher<Node*>& index_matcher) { @@ -87,20 +94,20 @@ Matcher<Node*> InterpreterAssemblerTest::InterpreterAssemblerForTest::IsCall( Matcher<Node*> InterpreterAssemblerTest::InterpreterAssemblerForTest::IsBytecodeOperand( - int operand) { + int offset) { return IsLoad( kMachUint8, IsParameter(Linkage::kInterpreterBytecodeArrayParameter), IsIntPtrAdd(IsParameter(Linkage::kInterpreterBytecodeOffsetParameter), - IsInt32Constant(1 + operand))); + IsInt32Constant(offset))); } Matcher<Node*> InterpreterAssemblerTest::InterpreterAssemblerForTest:: - IsBytecodeOperandSignExtended(int operand) { + IsBytecodeOperandSignExtended(int offset) { Matcher<Node*> load_matcher = IsLoad( kMachInt8, IsParameter(Linkage::kInterpreterBytecodeArrayParameter), IsIntPtrAdd(IsParameter(Linkage::kInterpreterBytecodeOffsetParameter), - IsInt32Constant(1 + operand))); + IsInt32Constant(offset))); if (kPointerSize == 8) { load_matcher = IsChangeInt32ToInt64(load_matcher); } @@ -108,6 +115,36 @@ Matcher<Node*> InterpreterAssemblerTest::InterpreterAssemblerForTest:: } +Matcher<Node*> +InterpreterAssemblerTest::InterpreterAssemblerForTest::IsBytecodeOperandShort( + int offset) { + if (TargetSupportsUnalignedAccess()) { + return IsLoad( + kMachUint16, IsParameter(Linkage::kInterpreterBytecodeArrayParameter), + IsIntPtrAdd(IsParameter(Linkage::kInterpreterBytecodeOffsetParameter), + IsInt32Constant(offset))); + } else { + Matcher<Node*> first_byte = IsLoad( + kMachUint8, IsParameter(Linkage::kInterpreterBytecodeArrayParameter), + IsIntPtrAdd(IsParameter(Linkage::kInterpreterBytecodeOffsetParameter), + IsInt32Constant(offset))); + Matcher<Node*> second_byte = IsLoad( + kMachUint8, IsParameter(Linkage::kInterpreterBytecodeArrayParameter), + IsIntPtrAdd(IsParameter(Linkage::kInterpreterBytecodeOffsetParameter), + IsInt32Constant(offset + 1))); +#if V8_TARGET_LITTLE_ENDIAN + return IsWordOr(IsWordShl(second_byte, IsInt32Constant(kBitsPerByte)), + first_byte); +#elif V8_TARGET_BIG_ENDIAN + return IsWordOr(IsWordShl(first_byte, IsInt32Constant(kBitsPerByte)), + second_byte); +#else +#error "Unknown Architecture" +#endif + } +} + + Graph* InterpreterAssemblerTest::InterpreterAssemblerForTest::GetCompletedGraph() { End(); @@ -268,20 +305,26 @@ TARGET_TEST_F(InterpreterAssemblerTest, BytecodeOperand) { InterpreterAssemblerForTest m(this, bytecode); int number_of_operands = interpreter::Bytecodes::NumberOfOperands(bytecode); for (int i = 0; i < number_of_operands; i++) { + int offset = interpreter::Bytecodes::GetOperandOffset(bytecode, i); switch (interpreter::Bytecodes::GetOperandType(bytecode, i)) { - case interpreter::OperandType::kCount: - EXPECT_THAT(m.BytecodeOperandCount(i), m.IsBytecodeOperand(i)); + case interpreter::OperandType::kCount8: + EXPECT_THAT(m.BytecodeOperandCount(i), m.IsBytecodeOperand(offset)); break; - case interpreter::OperandType::kIdx: - EXPECT_THAT(m.BytecodeOperandIdx(i), m.IsBytecodeOperand(i)); + case interpreter::OperandType::kIdx8: + EXPECT_THAT(m.BytecodeOperandIdx(i), m.IsBytecodeOperand(offset)); break; case interpreter::OperandType::kImm8: - EXPECT_THAT(m.BytecodeOperandImm8(i), - m.IsBytecodeOperandSignExtended(i)); + EXPECT_THAT(m.BytecodeOperandImm(i), + m.IsBytecodeOperandSignExtended(offset)); break; - case interpreter::OperandType::kReg: + case interpreter::OperandType::kMaybeReg8: + case interpreter::OperandType::kReg8: EXPECT_THAT(m.BytecodeOperandReg(i), - m.IsBytecodeOperandSignExtended(i)); + m.IsBytecodeOperandSignExtended(offset)); + break; + case interpreter::OperandType::kIdx16: + EXPECT_THAT(m.BytecodeOperandIdx(i), + m.IsBytecodeOperandShort(offset)); break; case interpreter::OperandType::kNone: UNREACHABLE(); @@ -429,21 +472,19 @@ TARGET_TEST_F(InterpreterAssemblerTest, LoadConstantPoolEntry) { } -TARGET_TEST_F(InterpreterAssemblerTest, LoadContextSlot) { +TARGET_TEST_F(InterpreterAssemblerTest, LoadFixedArrayElement) { TRACED_FOREACH(interpreter::Bytecode, bytecode, kBytecodes) { InterpreterAssemblerForTest m(this, bytecode); - Node* load_from_current_context = m.LoadContextSlot(22); - Matcher<Node*> load_from_current_context_matcher = m.IsLoad( - kMachAnyTagged, IsParameter(Linkage::kInterpreterContextParameter), - IsIntPtrConstant(Context::SlotOffset(22))); - EXPECT_THAT(load_from_current_context, load_from_current_context_matcher); - - // Let's imagine that the loaded context slot is another context. - Node* load_from_any_context = - m.LoadContextSlot(load_from_current_context, 23); - EXPECT_THAT(load_from_any_context, - m.IsLoad(kMachAnyTagged, load_from_current_context_matcher, - IsIntPtrConstant(Context::SlotOffset(23)))); + int index = 3; + Node* fixed_array = m.IntPtrConstant(0xdeadbeef); + Node* load_element = m.LoadFixedArrayElement(fixed_array, index); + EXPECT_THAT( + load_element, + m.IsLoad(kMachAnyTagged, fixed_array, + IsIntPtrAdd( + IsIntPtrConstant(FixedArray::kHeaderSize - kHeapObjectTag), + IsWordShl(IsInt32Constant(index), + IsInt32Constant(kPointerSizeLog2))))); } } @@ -461,7 +502,41 @@ TARGET_TEST_F(InterpreterAssemblerTest, LoadObjectField) { } -TARGET_TEST_F(InterpreterAssemblerTest, CallRuntime) { +TARGET_TEST_F(InterpreterAssemblerTest, LoadContextSlot) { + TRACED_FOREACH(interpreter::Bytecode, bytecode, kBytecodes) { + InterpreterAssemblerForTest m(this, bytecode); + Node* context = m.Int32Constant(1); + Node* slot_index = m.Int32Constant(22); + Node* load_context_slot = m.LoadContextSlot(context, slot_index); + + Matcher<Node*> offset = + IsIntPtrAdd(IsWordShl(slot_index, IsInt32Constant(kPointerSizeLog2)), + IsInt32Constant(Context::kHeaderSize - kHeapObjectTag)); + EXPECT_THAT(load_context_slot, m.IsLoad(kMachAnyTagged, context, offset)); + } +} + + +TARGET_TEST_F(InterpreterAssemblerTest, StoreContextSlot) { + TRACED_FOREACH(interpreter::Bytecode, bytecode, kBytecodes) { + InterpreterAssemblerForTest m(this, bytecode); + Node* context = m.Int32Constant(1); + Node* slot_index = m.Int32Constant(22); + Node* value = m.Int32Constant(100); + Node* store_context_slot = m.StoreContextSlot(context, slot_index, value); + + Matcher<Node*> offset = + IsIntPtrAdd(IsWordShl(slot_index, IsInt32Constant(kPointerSizeLog2)), + IsInt32Constant(Context::kHeaderSize - kHeapObjectTag)); + EXPECT_THAT( + store_context_slot, + m.IsStore(StoreRepresentation(kMachAnyTagged, kFullWriteBarrier), + context, offset, value)); + } +} + + +TARGET_TEST_F(InterpreterAssemblerTest, CallRuntime2) { TRACED_FOREACH(interpreter::Bytecode, bytecode, kBytecodes) { InterpreterAssemblerForTest m(this, bytecode); Node* arg1 = m.Int32Constant(2); @@ -474,6 +549,33 @@ TARGET_TEST_F(InterpreterAssemblerTest, CallRuntime) { } +TARGET_TEST_F(InterpreterAssemblerTest, CallRuntime) { + TRACED_FOREACH(interpreter::Bytecode, bytecode, kBytecodes) { + InterpreterAssemblerForTest m(this, bytecode); + Callable builtin = CodeFactory::InterpreterCEntry(isolate()); + + Node* function_id = m.Int32Constant(0); + Node* first_arg = m.Int32Constant(1); + Node* arg_count = m.Int32Constant(2); + + Matcher<Node*> function_table = IsExternalConstant( + ExternalReference::runtime_function_table_address(isolate())); + Matcher<Node*> function = IsIntPtrAdd( + function_table, + IsInt32Mul(function_id, IsInt32Constant(sizeof(Runtime::Function)))); + Matcher<Node*> function_entry = + m.IsLoad(kMachPtr, function, + IsInt32Constant(offsetof(Runtime::Function, entry))); + + Node* call_runtime = m.CallRuntime(function_id, first_arg, arg_count); + EXPECT_THAT(call_runtime, + m.IsCall(_, IsHeapConstant(builtin.code()), arg_count, + first_arg, function_entry, + IsParameter(Linkage::kInterpreterContextParameter))); + } +} + + TARGET_TEST_F(InterpreterAssemblerTest, CallIC) { TRACED_FOREACH(interpreter::Bytecode, bytecode, kBytecodes) { InterpreterAssemblerForTest m(this, bytecode); @@ -494,7 +596,7 @@ TARGET_TEST_F(InterpreterAssemblerTest, CallIC) { TARGET_TEST_F(InterpreterAssemblerTest, CallJS) { TRACED_FOREACH(interpreter::Bytecode, bytecode, kBytecodes) { InterpreterAssemblerForTest m(this, bytecode); - Callable builtin = CodeFactory::PushArgsAndCall(isolate()); + Callable builtin = CodeFactory::InterpreterPushArgsAndCall(isolate()); Node* function = m.Int32Constant(0); Node* first_arg = m.Int32Constant(1); Node* arg_count = m.Int32Constant(2); diff --git a/deps/v8/test/unittests/compiler/interpreter-assembler-unittest.h b/deps/v8/test/unittests/compiler/interpreter-assembler-unittest.h index 0ed91eb401..49c1c2ad29 100644 --- a/deps/v8/test/unittests/compiler/interpreter-assembler-unittest.h +++ b/deps/v8/test/unittests/compiler/interpreter-assembler-unittest.h @@ -43,8 +43,9 @@ class InterpreterAssemblerTest : public TestWithIsolateAndZone { const Matcher<const CallDescriptor*>& descriptor_matcher, A... args); - Matcher<Node*> IsBytecodeOperand(int operand); - Matcher<Node*> IsBytecodeOperandSignExtended(int operand); + Matcher<Node*> IsBytecodeOperand(int offset); + Matcher<Node*> IsBytecodeOperandSignExtended(int offset); + Matcher<Node*> IsBytecodeOperandShort(int offset); using InterpreterAssembler::call_descriptor; using InterpreterAssembler::graph; diff --git a/deps/v8/test/unittests/compiler/js-builtin-reducer-unittest.cc b/deps/v8/test/unittests/compiler/js-builtin-reducer-unittest.cc index 9e0cee0d3d..ae367aa395 100644 --- a/deps/v8/test/unittests/compiler/js-builtin-reducer-unittest.cc +++ b/deps/v8/test/unittests/compiler/js-builtin-reducer-unittest.cc @@ -5,6 +5,7 @@ #include "src/compiler/js-builtin-reducer.h" #include "src/compiler/js-graph.h" #include "src/compiler/node-properties.h" +#include "src/compiler/simplified-operator.h" #include "src/compiler/typer.h" #include "src/isolate-inl.h" #include "test/unittests/compiler/graph-unittest.h" @@ -26,7 +27,9 @@ class JSBuiltinReducerTest : public TypedGraphTest { Reduction Reduce(Node* node, MachineOperatorBuilder::Flags flags = MachineOperatorBuilder::Flag::kNoFlags) { MachineOperatorBuilder machine(zone(), kMachPtr, flags); - JSGraph jsgraph(isolate(), graph(), common(), javascript(), &machine); + SimplifiedOperatorBuilder simplified(zone()); + JSGraph jsgraph(isolate(), graph(), common(), javascript(), &simplified, + &machine); // TODO(titzer): mock the GraphReducer here for better unit testing. GraphReducer graph_reducer(zone(), graph()); JSBuiltinReducer reducer(&graph_reducer, &jsgraph); @@ -82,12 +85,12 @@ TEST_F(JSBuiltinReducerTest, MathMax0) { Node* effect = graph()->start(); Node* control = graph()->start(); + Node* context = UndefinedConstant(); Node* frame_state = graph()->start(); TRACED_FOREACH(LanguageMode, language_mode, kLanguageModes) { - Node* call = graph()->NewNode( - javascript()->CallFunction(2, NO_CALL_FUNCTION_FLAGS, language_mode), - function, UndefinedConstant(), frame_state, frame_state, effect, - control); + Node* call = graph()->NewNode(javascript()->CallFunction(2, language_mode), + function, UndefinedConstant(), context, + frame_state, frame_state, effect, control); Reduction r = Reduce(call); ASSERT_TRUE(r.Changed()); @@ -101,14 +104,15 @@ TEST_F(JSBuiltinReducerTest, MathMax1) { Node* effect = graph()->start(); Node* control = graph()->start(); + Node* context = UndefinedConstant(); Node* frame_state = graph()->start(); TRACED_FOREACH(LanguageMode, language_mode, kLanguageModes) { TRACED_FOREACH(Type*, t0, kNumberTypes) { Node* p0 = Parameter(t0, 0); - Node* call = graph()->NewNode( - javascript()->CallFunction(3, NO_CALL_FUNCTION_FLAGS, language_mode), - function, UndefinedConstant(), p0, frame_state, frame_state, effect, - control); + Node* call = + graph()->NewNode(javascript()->CallFunction(3, language_mode), + function, UndefinedConstant(), p0, context, + frame_state, frame_state, effect, control); Reduction r = Reduce(call); ASSERT_TRUE(r.Changed()); @@ -123,6 +127,7 @@ TEST_F(JSBuiltinReducerTest, MathMax2) { Node* effect = graph()->start(); Node* control = graph()->start(); + Node* context = UndefinedConstant(); Node* frame_state = graph()->start(); TRACED_FOREACH(LanguageMode, language_mode, kLanguageModes) { TRACED_FOREACH(Type*, t0, kIntegral32Types) { @@ -130,10 +135,9 @@ TEST_F(JSBuiltinReducerTest, MathMax2) { Node* p0 = Parameter(t0, 0); Node* p1 = Parameter(t1, 1); Node* call = - graph()->NewNode(javascript()->CallFunction( - 4, NO_CALL_FUNCTION_FLAGS, language_mode), - function, UndefinedConstant(), p0, p1, frame_state, - frame_state, effect, control); + graph()->NewNode(javascript()->CallFunction(4, language_mode), + function, UndefinedConstant(), p0, p1, context, + frame_state, frame_state, effect, control); Reduction r = Reduce(call); ASSERT_TRUE(r.Changed()); @@ -154,6 +158,7 @@ TEST_F(JSBuiltinReducerTest, MathImul) { Node* effect = graph()->start(); Node* control = graph()->start(); + Node* context = UndefinedConstant(); Node* frame_state = graph()->start(); TRACED_FOREACH(LanguageMode, language_mode, kLanguageModes) { TRACED_FOREACH(Type*, t0, kIntegral32Types) { @@ -161,10 +166,9 @@ TEST_F(JSBuiltinReducerTest, MathImul) { Node* p0 = Parameter(t0, 0); Node* p1 = Parameter(t1, 1); Node* call = - graph()->NewNode(javascript()->CallFunction( - 4, NO_CALL_FUNCTION_FLAGS, language_mode), - function, UndefinedConstant(), p0, p1, frame_state, - frame_state, effect, control); + graph()->NewNode(javascript()->CallFunction(4, language_mode), + function, UndefinedConstant(), p0, p1, context, + frame_state, frame_state, effect, control); Reduction r = Reduce(call); ASSERT_TRUE(r.Changed()); @@ -184,14 +188,15 @@ TEST_F(JSBuiltinReducerTest, MathFround) { Node* effect = graph()->start(); Node* control = graph()->start(); + Node* context = UndefinedConstant(); Node* frame_state = graph()->start(); TRACED_FOREACH(LanguageMode, language_mode, kLanguageModes) { TRACED_FOREACH(Type*, t0, kNumberTypes) { Node* p0 = Parameter(t0, 0); - Node* call = graph()->NewNode( - javascript()->CallFunction(3, NO_CALL_FUNCTION_FLAGS, language_mode), - function, UndefinedConstant(), p0, frame_state, frame_state, effect, - control); + Node* call = + graph()->NewNode(javascript()->CallFunction(3, language_mode), + function, UndefinedConstant(), p0, context, + frame_state, frame_state, effect, control); Reduction r = Reduce(call); ASSERT_TRUE(r.Changed()); diff --git a/deps/v8/test/unittests/compiler/js-context-relaxation-unittest.cc b/deps/v8/test/unittests/compiler/js-context-relaxation-unittest.cc index 4cc8f17509..0fcf9f7087 100644 --- a/deps/v8/test/unittests/compiler/js-context-relaxation-unittest.cc +++ b/deps/v8/test/unittests/compiler/js-context-relaxation-unittest.cc @@ -20,7 +20,8 @@ class JSContextRelaxationTest : public GraphTest { Reduction Reduce(Node* node, MachineOperatorBuilder::Flags flags = MachineOperatorBuilder::kNoFlags) { MachineOperatorBuilder machine(zone(), kMachPtr, flags); - JSGraph jsgraph(isolate(), graph(), common(), javascript(), &machine); + JSGraph jsgraph(isolate(), graph(), common(), javascript(), nullptr, + &machine); // TODO(titzer): mock the GraphReducer here for better unit testing. GraphReducer graph_reducer(zone(), graph()); JSContextRelaxation reducer; @@ -29,7 +30,8 @@ class JSContextRelaxationTest : public GraphTest { Node* EmptyFrameState() { MachineOperatorBuilder machine(zone()); - JSGraph jsgraph(isolate(), graph(), common(), javascript(), &machine); + JSGraph jsgraph(isolate(), graph(), common(), javascript(), nullptr, + &machine); return jsgraph.EmptyFrameState(); } @@ -80,10 +82,9 @@ TEST_F(JSContextRelaxationTest, 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); + Node* node = graph()->NewNode( + javascript()->CallFunction(2, STRICT, VectorSlotPair()), input0, input1, + context, frame_state, frame_state, effect, control); Reduction const r = Reduce(node); EXPECT_TRUE(r.Changed()); EXPECT_EQ(outer_context, NodeProperties::GetContextInput(node)); @@ -99,10 +100,9 @@ TEST_F(JSContextRelaxationTest, 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); + Node* node = graph()->NewNode( + javascript()->CallFunction(2, STRICT, VectorSlotPair()), input0, input1, + context, frame_state, frame_state, effect, control); Reduction const r = Reduce(node); EXPECT_FALSE(r.Changed()); EXPECT_EQ(context, NodeProperties::GetContextInput(node)); @@ -118,10 +118,9 @@ TEST_F(JSContextRelaxationTest, 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); + Node* node = graph()->NewNode( + javascript()->CallFunction(2, STRICT, VectorSlotPair()), input0, input1, + context, frame_state, frame_state, effect, control); Reduction const r = Reduce(node); EXPECT_TRUE(r.Changed()); EXPECT_EQ(outer_context, NodeProperties::GetContextInput(node)); @@ -137,10 +136,9 @@ TEST_F(JSContextRelaxationTest, 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); + Node* node = graph()->NewNode( + javascript()->CallFunction(2, STRICT, VectorSlotPair()), input0, input1, + context, frame_state, frame_state, effect, control); Reduction const r = Reduce(node); EXPECT_FALSE(r.Changed()); EXPECT_EQ(context, NodeProperties::GetContextInput(node)); @@ -159,10 +157,9 @@ TEST_F(JSContextRelaxationTest, op, graph()->start(), graph()->start(), outer_context, 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); + Node* node = graph()->NewNode( + javascript()->CallFunction(2, STRICT, VectorSlotPair()), input0, input1, + context, frame_state_2, frame_state_2, effect, control); Reduction const r = Reduce(node); EXPECT_TRUE(r.Changed()); EXPECT_EQ(outer_context, NodeProperties::GetContextInput(node)); @@ -185,10 +182,9 @@ TEST_F(JSContextRelaxationTest, 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); + Node* node = graph()->NewNode( + javascript()->CallFunction(2, STRICT, VectorSlotPair()), input0, input1, + context, frame_state_2, frame_state_2, effect, control); Reduction const r = Reduce(node); EXPECT_TRUE(r.Changed()); EXPECT_EQ(outer_context, NodeProperties::GetContextInput(node)); @@ -209,10 +205,9 @@ TEST_F(JSContextRelaxationTest, graph()->NewNode(op, graph()->start(), outer_context, 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); + Node* node = graph()->NewNode( + javascript()->CallFunction(2, STRICT, VectorSlotPair()), input0, input1, + context, frame_state_2, frame_state_2, effect, control); Reduction const r = Reduce(node); EXPECT_TRUE(r.Changed()); EXPECT_EQ(outer_context, NodeProperties::GetContextInput(node)); @@ -235,10 +230,9 @@ TEST_F(JSContextRelaxationTest, 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); + Node* node = graph()->NewNode( + javascript()->CallFunction(2, STRICT, VectorSlotPair()), input0, input1, + context, frame_state_2, frame_state_2, effect, control); Reduction const r = Reduce(node); EXPECT_TRUE(r.Changed()); EXPECT_EQ(nested_context, NodeProperties::GetContextInput(node)); @@ -258,10 +252,9 @@ TEST_F(JSContextRelaxationTest, op, graph()->start(), graph()->start(), outer_context, 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); + Node* node = graph()->NewNode( + javascript()->CallFunction(2, STRICT, VectorSlotPair()), input0, input1, + context, frame_state_2, frame_state_2, effect, control); Reduction const r = Reduce(node); EXPECT_TRUE(r.Changed()); EXPECT_EQ(nested_context, NodeProperties::GetContextInput(node)); @@ -274,17 +267,16 @@ TEST_F(JSContextRelaxationTest, Node* const input1 = Parameter(1); Node* const context = Parameter(2); Node* const outer_context = Parameter(3); - const Operator* op = javascript()->CreateFunctionContext(); + const Operator* op = javascript()->CreateFunctionContext(0); Node* const effect = graph()->start(); Node* const control = graph()->start(); Node* nested_context = graph()->NewNode(op, graph()->start(), outer_context, 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); + Node* node = graph()->NewNode( + javascript()->CallFunction(2, STRICT, VectorSlotPair()), input0, input1, + context, frame_state_2, frame_state_2, effect, control); Reduction const r = Reduce(node); EXPECT_FALSE(r.Changed()); EXPECT_EQ(context, NodeProperties::GetContextInput(node)); diff --git a/deps/v8/test/unittests/compiler/js-intrinsic-lowering-unittest.cc b/deps/v8/test/unittests/compiler/js-intrinsic-lowering-unittest.cc index 9d5b649471..a22f660c21 100644 --- a/deps/v8/test/unittests/compiler/js-intrinsic-lowering-unittest.cc +++ b/deps/v8/test/unittests/compiler/js-intrinsic-lowering-unittest.cc @@ -32,7 +32,9 @@ class JSIntrinsicLoweringTest : public GraphTest { Reduction Reduce(Node* node, MachineOperatorBuilder::Flags flags = MachineOperatorBuilder::kNoFlags) { MachineOperatorBuilder machine(zone(), kMachPtr, flags); - JSGraph jsgraph(isolate(), graph(), common(), javascript(), &machine); + SimplifiedOperatorBuilder simplified(zone()); + JSGraph jsgraph(isolate(), graph(), common(), javascript(), &simplified, + &machine); // TODO(titzer): mock the GraphReducer here for better unit testing. GraphReducer graph_reducer(zone(), graph()); JSIntrinsicLowering reducer(&graph_reducer, &jsgraph, @@ -42,7 +44,8 @@ class JSIntrinsicLoweringTest : public GraphTest { Node* EmptyFrameState() { MachineOperatorBuilder machine(zone()); - JSGraph jsgraph(isolate(), graph(), common(), javascript(), &machine); + JSGraph jsgraph(isolate(), graph(), common(), javascript(), nullptr, + &machine); return jsgraph.EmptyFrameState(); } @@ -299,30 +302,6 @@ TEST_F(JSIntrinsicLoweringTest, InlineJSValueGetValue) { // ----------------------------------------------------------------------------- -// %_Likely - -TEST_F(JSIntrinsicLoweringTest, Likely) { - Node* const input = Parameter(0); - Node* const context = Parameter(1); - Node* const effect = graph()->start(); - Node* const control = graph()->start(); - Node* const likely = - graph()->NewNode(javascript()->CallRuntime(Runtime::kInlineLikely, 1), - input, context, effect, control); - Node* const to_boolean = - graph()->NewNode(javascript()->ToBoolean(), likely, context, effect); - Diamond d(graph(), common(), to_boolean); - graph()->SetEnd(graph()->NewNode(common()->End(1), d.merge)); - - ASSERT_EQ(BranchHint::kNone, BranchHintOf(d.branch->op())); - Reduction const r = Reduce(likely); - ASSERT_TRUE(r.Changed()); - EXPECT_THAT(r.replacement(), input); - ASSERT_EQ(BranchHint::kTrue, BranchHintOf(d.branch->op())); -} - - -// ----------------------------------------------------------------------------- // %_MathFloor @@ -370,9 +349,8 @@ TEST_F(JSIntrinsicLoweringTest, InlineStringGetLength) { javascript()->CallRuntime(Runtime::kInlineStringGetLength, 1), input, context, effect, control)); ASSERT_TRUE(r.Changed()); - EXPECT_THAT(r.replacement(), - IsLoadField(AccessBuilder::ForStringLength(zone()), input, effect, - control)); + EXPECT_THAT(r.replacement(), IsLoadField(AccessBuilder::ForStringLength(), + input, effect, control)); } @@ -394,30 +372,6 @@ TEST_F(JSIntrinsicLoweringTest, InlineMathClz32) { // ----------------------------------------------------------------------------- -// %_Unlikely - -TEST_F(JSIntrinsicLoweringTest, Unlikely) { - Node* const input = Parameter(0); - Node* const context = Parameter(1); - Node* const effect = graph()->start(); - Node* const control = graph()->start(); - Node* const unlikely = - graph()->NewNode(javascript()->CallRuntime(Runtime::kInlineUnlikely, 1), - input, context, effect, control); - Node* const to_boolean = - graph()->NewNode(javascript()->ToBoolean(), unlikely, context, effect); - Diamond d(graph(), common(), to_boolean); - graph()->SetEnd(graph()->NewNode(common()->End(1), d.merge)); - - ASSERT_EQ(BranchHint::kNone, BranchHintOf(d.branch->op())); - Reduction const r = Reduce(unlikely); - ASSERT_TRUE(r.Changed()); - EXPECT_THAT(r.replacement(), input); - ASSERT_EQ(BranchHint::kFalse, BranchHintOf(d.branch->op())); -} - - -// ----------------------------------------------------------------------------- // %_ValueOf diff --git a/deps/v8/test/unittests/compiler/js-operator-unittest.cc b/deps/v8/test/unittests/compiler/js-operator-unittest.cc index a1f3973734..0461a0d625 100644 --- a/deps/v8/test/unittests/compiler/js-operator-unittest.cc +++ b/deps/v8/test/unittests/compiler/js-operator-unittest.cc @@ -74,7 +74,7 @@ const SharedOperator kSharedOperators[] = { SHARED(UnaryNot, Operator::kEliminatable, 1, 0, 1, 0, 1, 1, 0), SHARED(ToBoolean, Operator::kEliminatable, 1, 0, 1, 0, 1, 1, 0), SHARED(ToNumber, Operator::kNoProperties, 1, 1, 1, 1, 1, 1, 2), - SHARED(ToString, Operator::kNoProperties, 1, 0, 1, 1, 1, 1, 2), + SHARED(ToString, Operator::kNoProperties, 1, 1, 1, 1, 1, 1, 2), SHARED(ToName, Operator::kNoProperties, 1, 1, 1, 1, 1, 1, 2), SHARED(ToObject, Operator::kNoProperties, 1, 1, 1, 1, 1, 1, 2), SHARED(Yield, Operator::kNoProperties, 1, 0, 1, 1, 1, 1, 2), @@ -82,7 +82,6 @@ const SharedOperator kSharedOperators[] = { SHARED(HasProperty, Operator::kNoProperties, 2, 1, 1, 1, 1, 1, 2), SHARED(TypeOf, Operator::kEliminatable, 1, 0, 1, 0, 1, 1, 0), SHARED(InstanceOf, Operator::kNoProperties, 2, 1, 1, 1, 1, 1, 2), - SHARED(CreateFunctionContext, Operator::kNoProperties, 1, 0, 1, 1, 1, 1, 2), SHARED(CreateWithContext, Operator::kNoProperties, 2, 1, 1, 1, 1, 1, 2), SHARED(CreateModuleContext, Operator::kNoProperties, 2, 0, 1, 1, 1, 1, 2), #undef SHARED 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 f3f1b733fc..dece25def1 100644 --- a/deps/v8/test/unittests/compiler/js-type-feedback-unittest.cc +++ b/deps/v8/test/unittests/compiler/js-type-feedback-unittest.cc @@ -40,7 +40,9 @@ class JSTypeFeedbackTest : public TypedGraphTest { isolate()->native_context()->global_object(), isolate()); MachineOperatorBuilder machine(zone()); - JSGraph jsgraph(isolate(), graph(), common(), javascript(), &machine); + SimplifiedOperatorBuilder simplified(zone()); + JSGraph jsgraph(isolate(), graph(), common(), javascript(), &simplified, + &machine); JSTypeFeedbackTable table(zone()); // TODO(titzer): mock the GraphReducer here for better unit testing. GraphReducer graph_reducer(zone(), graph()); @@ -51,7 +53,8 @@ class JSTypeFeedbackTest : public TypedGraphTest { Node* EmptyFrameState() { MachineOperatorBuilder machine(zone()); - JSGraph jsgraph(isolate(), graph(), common(), javascript(), &machine); + JSGraph jsgraph(isolate(), graph(), common(), javascript(), nullptr, + &machine); return jsgraph.EmptyFrameState(); } @@ -78,15 +81,13 @@ class JSTypeFeedbackTest : public TypedGraphTest { const char* string, Node* effect, Node* control, JSTypeFeedbackSpecializer::DeoptimizationMode mode) { VectorSlotPair feedback; - Node* global = UndefinedConstant(); Node* vector = UndefinedConstant(); Node* context = UndefinedConstant(); Handle<Name> name = isolate()->factory()->InternalizeUtf8String(string); const Operator* op = javascript()->LoadGlobal(name, feedback); - Node* load = - graph()->NewNode(op, context, global, vector, context, - EmptyFrameState(), EmptyFrameState(), effect, control); + Node* load = graph()->NewNode(op, vector, context, EmptyFrameState(), + EmptyFrameState(), effect, control); Node* if_success = graph()->NewNode(common()->IfSuccess(), load); return graph()->NewNode(common()->Return(), load, load, if_success); } 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 da964db23a..37dc1f3eb5 100644 --- a/deps/v8/test/unittests/compiler/js-typed-lowering-unittest.cc +++ b/deps/v8/test/unittests/compiler/js-typed-lowering-unittest.cc @@ -74,19 +74,36 @@ const LanguageMode kLanguageModes[] = {SLOPPY, STRICT, STRONG}; class JSTypedLoweringTest : public TypedGraphTest { public: - JSTypedLoweringTest() : TypedGraphTest(3), javascript_(zone()) {} + JSTypedLoweringTest() + : TypedGraphTest(3), javascript_(zone()), deps_(isolate(), zone()) {} ~JSTypedLoweringTest() override {} protected: Reduction Reduce(Node* node) { MachineOperatorBuilder machine(zone()); - JSGraph jsgraph(isolate(), graph(), common(), javascript(), &machine); + SimplifiedOperatorBuilder simplified(zone()); + JSGraph jsgraph(isolate(), graph(), common(), javascript(), &simplified, + &machine); // TODO(titzer): mock the GraphReducer here for better unit testing. GraphReducer graph_reducer(zone(), graph()); - JSTypedLowering reducer(&graph_reducer, &jsgraph, zone()); + JSTypedLowering reducer(&graph_reducer, &deps_, + JSTypedLowering::kDeoptimizationEnabled, &jsgraph, + zone()); return reducer.Reduce(node); } + Node* FrameState(Handle<SharedFunctionInfo> shared, Node* outer_frame_state) { + Node* state_values = graph()->NewNode(common()->StateValues(0)); + return graph()->NewNode( + common()->FrameState(BailoutId::None(), + OutputFrameStateCombine::Ignore(), + common()->CreateFrameStateFunctionInfo( + FrameStateType::kJavaScriptFunction, 1, 0, + shared, CALL_MAINTAINS_NATIVE_CONTEXT)), + state_values, state_values, state_values, NumberConstant(0), + UndefinedConstant(), outer_frame_state); + } + Handle<JSArrayBuffer> NewArrayBuffer(void* bytes, size_t byte_length) { Handle<JSArrayBuffer> buffer = factory()->NewJSArrayBuffer(); JSArrayBuffer::Setup(buffer, isolate(), true, bytes, byte_length); @@ -102,6 +119,7 @@ class JSTypedLoweringTest : public TypedGraphTest { private: JSOperatorBuilder javascript_; + CompilationDependencies deps_; }; @@ -189,11 +207,10 @@ TEST_F(JSTypedLoweringTest, JSUnaryNotWithString) { Reduction r = Reduce(graph()->NewNode(javascript()->UnaryNot(), input, context, graph()->start())); ASSERT_TRUE(r.Changed()); - EXPECT_THAT( - r.replacement(), - IsNumberEqual(IsLoadField(AccessBuilder::ForStringLength(zone()), input, - graph()->start(), graph()->start()), - IsNumberConstant(0.0))); + EXPECT_THAT(r.replacement(), + IsNumberEqual(IsLoadField(AccessBuilder::ForStringLength(), input, + graph()->start(), graph()->start()), + IsNumberConstant(0.0))); } @@ -388,8 +405,8 @@ TEST_F(JSTypedLoweringTest, JSToBooleanWithString) { EXPECT_THAT( r.replacement(), IsNumberLessThan(IsNumberConstant(0.0), - IsLoadField(AccessBuilder::ForStringLength(zone()), - input, graph()->start(), graph()->start()))); + IsLoadField(AccessBuilder::ForStringLength(), input, + graph()->start(), graph()->start()))); } @@ -421,6 +438,56 @@ TEST_F(JSTypedLoweringTest, JSToNumberWithPlainPrimitive) { // ----------------------------------------------------------------------------- +// JSToObject + + +TEST_F(JSTypedLoweringTest, JSToObjectWithAny) { + Node* const input = Parameter(Type::Any(), 0); + Node* const context = Parameter(Type::Any(), 1); + Node* const frame_state = EmptyFrameState(); + Node* const effect = graph()->start(); + Node* const control = graph()->start(); + Reduction r = Reduce(graph()->NewNode(javascript()->ToObject(), input, + context, frame_state, effect, control)); + ASSERT_TRUE(r.Changed()); + EXPECT_THAT(r.replacement(), IsPhi(kMachAnyTagged, _, _, _)); +} + + +TEST_F(JSTypedLoweringTest, JSToObjectWithReceiver) { + Node* const input = Parameter(Type::Receiver(), 0); + Node* const context = Parameter(Type::Any(), 1); + Node* const frame_state = EmptyFrameState(); + Node* const effect = graph()->start(); + Node* const control = graph()->start(); + Reduction r = Reduce(graph()->NewNode(javascript()->ToObject(), input, + context, frame_state, effect, control)); + ASSERT_TRUE(r.Changed()); + EXPECT_EQ(input, r.replacement()); +} + + +// ----------------------------------------------------------------------------- +// JSToString + + +TEST_F(JSTypedLoweringTest, JSToStringWithBoolean) { + Node* const input = Parameter(Type::Boolean(), 0); + Node* const context = Parameter(Type::Any(), 1); + Node* const frame_state = EmptyFrameState(); + Node* const effect = graph()->start(); + Node* const control = graph()->start(); + Reduction r = Reduce(graph()->NewNode(javascript()->ToString(), input, + context, frame_state, effect, control)); + ASSERT_TRUE(r.Changed()); + EXPECT_THAT( + r.replacement(), + IsSelect(kMachAnyTagged, input, IsHeapConstant(factory()->true_string()), + IsHeapConstant(factory()->false_string()))); +} + + +// ----------------------------------------------------------------------------- // JSStrictEqual @@ -659,7 +726,7 @@ TEST_F(JSTypedLoweringTest, JSLoadPropertyFromExternalTypedArray) { Node* effect = graph()->start(); Node* control = graph()->start(); Reduction r = Reduce( - graph()->NewNode(javascript()->LoadProperty(feedback, language_mode), + graph()->NewNode(javascript()->LoadProperty(language_mode, feedback), base, key, vector, context, EmptyFrameState(), EmptyFrameState(), effect, control)); @@ -703,7 +770,7 @@ TEST_F(JSTypedLoweringTest, JSLoadPropertyFromExternalTypedArrayWithSafeKey) { Node* effect = graph()->start(); Node* control = graph()->start(); Reduction r = Reduce( - graph()->NewNode(javascript()->LoadProperty(feedback, language_mode), + graph()->NewNode(javascript()->LoadProperty(language_mode, feedback), base, key, vector, context, EmptyFrameState(), EmptyFrameState(), effect, control)); @@ -862,41 +929,6 @@ TEST_F(JSTypedLoweringTest, JSStorePropertyToExternalTypedArrayWithSafeKey) { // ----------------------------------------------------------------------------- -// JSLoadGlobal - - -TEST_F(JSTypedLoweringTest, JSLoadGlobalConstants) { - Handle<String> names[] = { - Handle<String>(isolate()->heap()->undefined_string(), isolate()), - Handle<String>(isolate()->heap()->infinity_string(), isolate()), - Handle<String>(isolate()->heap()->nan_string(), isolate()) // -- - }; - Matcher<Node*> matches[] = { - IsHeapConstant( - Handle<HeapObject>(isolate()->heap()->undefined_value(), isolate())), - IsNumberConstant(std::numeric_limits<double>::infinity()), - IsNumberConstant(IsNaN()) // -- - }; - - VectorSlotPair feedback; - Node* global = UndefinedConstant(); - Node* vector = UndefinedConstant(); - Node* context = UndefinedConstant(); - Node* effect = graph()->start(); - Node* control = graph()->start(); - - for (size_t i = 0; i < arraysize(names); i++) { - Reduction r = Reduce(graph()->NewNode( - javascript()->LoadGlobal(names[i], feedback), context, global, vector, - context, EmptyFrameState(), EmptyFrameState(), effect, control)); - - ASSERT_TRUE(r.Changed()); - EXPECT_THAT(r.replacement(), matches[i]); - } -} - - -// ----------------------------------------------------------------------------- // JSLoadNamed @@ -910,83 +942,12 @@ TEST_F(JSTypedLoweringTest, JSLoadNamedStringLength) { Node* const control = graph()->start(); TRACED_FOREACH(LanguageMode, language_mode, kLanguageModes) { Reduction const r = Reduce( - graph()->NewNode(javascript()->LoadNamed(name, feedback, language_mode), + graph()->NewNode(javascript()->LoadNamed(language_mode, name, feedback), receiver, vector, context, EmptyFrameState(), EmptyFrameState(), effect, control)); ASSERT_TRUE(r.Changed()); - EXPECT_THAT(r.replacement(), - IsLoadField(AccessBuilder::ForStringLength(zone()), receiver, - effect, control)); - } -} - - -// ----------------------------------------------------------------------------- -// JSLoadDynamicGlobal - - -TEST_F(JSTypedLoweringTest, JSLoadDynamicGlobal) { - Node* const context = Parameter(Type::Any()); - Node* const vector = UndefinedConstant(); - Node* const frame_state = EmptyFrameState(); - Node* const effect = graph()->start(); - Node* const control = graph()->start(); - Handle<String> name = factory()->object_string(); - VectorSlotPair feedback; - 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_INSIDE_TYPEOF), - vector, context, context, frame_state, frame_state, effect, control)); - ASSERT_TRUE(r.Changed()); - EXPECT_THAT( - r.replacement(), - IsPhi(kMachAnyTagged, _, _, - IsMerge( - IsIfTrue(IsBranch( - IsReferenceEqual( - Type::Tagged(), - IsLoadContext( - ContextAccess(i, Context::EXTENSION_INDEX, false), - context), - IsNumberConstant(BitEq(0.0))), - control)), - _))); - } -} - - -// ----------------------------------------------------------------------------- -// JSLoadDynamicContext - - -TEST_F(JSTypedLoweringTest, JSLoadDynamicContext) { - Node* const context = Parameter(Type::Any()); - Node* const frame_state = EmptyFrameState(); - Node* const effect = graph()->start(); - Node* const control = graph()->start(); - Handle<String> name = factory()->object_string(); - for (int i = 0; i < DynamicContextAccess::kMaxCheckDepth; ++i) { - uint32_t bitset = 1 << i; // Only single check. - Reduction r = Reduce( - graph()->NewNode(javascript()->LoadDynamicContext(name, bitset, 23, 42), - context, context, frame_state, effect, control)); - ASSERT_TRUE(r.Changed()); - EXPECT_THAT( - r.replacement(), - IsPhi(kMachAnyTagged, - IsLoadContext(ContextAccess(23, 42, false), context), _, - IsMerge( - IsIfTrue(IsBranch( - IsReferenceEqual( - Type::Tagged(), - IsLoadContext( - ContextAccess(i, Context::EXTENSION_INDEX, false), - context), - IsNumberConstant(BitEq(0.0))), - control)), - _))); + EXPECT_THAT(r.replacement(), IsLoadField(AccessBuilder::ForStringLength(), + receiver, effect, control)); } } @@ -1018,6 +979,72 @@ TEST_F(JSTypedLoweringTest, JSAddWithString) { // ----------------------------------------------------------------------------- +// JSCreateArguments + + +TEST_F(JSTypedLoweringTest, JSCreateArgumentsViaStub) { + Node* const closure = Parameter(Type::Any()); + Node* const context = UndefinedConstant(); + Node* const effect = graph()->start(); + Node* const control = graph()->start(); + Handle<SharedFunctionInfo> shared(isolate()->object_function()->shared()); + Node* const frame_state = FrameState(shared, graph()->start()); + Reduction r = Reduce( + graph()->NewNode(javascript()->CreateArguments( + CreateArgumentsParameters::kMappedArguments, 0), + closure, context, frame_state, effect, control)); + ASSERT_TRUE(r.Changed()); + EXPECT_THAT(r.replacement(), + IsCall(_, IsHeapConstant(CodeFactory::ArgumentsAccess( + isolate(), false, false) + .code()), + closure, IsNumberConstant(0), _, effect, control)); +} + + +TEST_F(JSTypedLoweringTest, JSCreateArgumentsInlinedMapped) { + Node* const closure = Parameter(Type::Any()); + Node* const context = UndefinedConstant(); + Node* const effect = graph()->start(); + Node* const control = graph()->start(); + Handle<SharedFunctionInfo> shared(isolate()->object_function()->shared()); + Node* const frame_state_outer = FrameState(shared, graph()->start()); + Node* const frame_state_inner = FrameState(shared, frame_state_outer); + Reduction r = Reduce( + graph()->NewNode(javascript()->CreateArguments( + CreateArgumentsParameters::kMappedArguments, 0), + closure, context, frame_state_inner, effect, control)); + ASSERT_TRUE(r.Changed()); + EXPECT_THAT(r.replacement(), + IsFinishRegion( + IsAllocate(IsNumberConstant(Heap::kSloppyArgumentsObjectSize), + IsBeginRegion(effect), control), + _)); +} + + +TEST_F(JSTypedLoweringTest, JSCreateArgumentsInlinedUnmapped) { + Node* const closure = Parameter(Type::Any()); + Node* const context = UndefinedConstant(); + Node* const effect = graph()->start(); + Node* const control = graph()->start(); + Handle<SharedFunctionInfo> shared(isolate()->object_function()->shared()); + Node* const frame_state_outer = FrameState(shared, graph()->start()); + Node* const frame_state_inner = FrameState(shared, frame_state_outer); + Reduction r = Reduce( + graph()->NewNode(javascript()->CreateArguments( + CreateArgumentsParameters::kUnmappedArguments, 0), + closure, context, frame_state_inner, effect, control)); + ASSERT_TRUE(r.Changed()); + EXPECT_THAT(r.replacement(), + IsFinishRegion( + IsAllocate(IsNumberConstant(Heap::kStrictArgumentsObjectSize), + IsBeginRegion(effect), control), + _)); +} + + +// ----------------------------------------------------------------------------- // JSCreateClosure @@ -1087,11 +1114,47 @@ TEST_F(JSTypedLoweringTest, JSCreateLiteralObject) { // ----------------------------------------------------------------------------- +// JSCreateFunctionContext + + +TEST_F(JSTypedLoweringTest, JSCreateFunctionContextViaInlinedAllocation) { + Node* const closure = Parameter(Type::Any()); + Node* const context = Parameter(Type::Any()); + Node* const effect = graph()->start(); + Node* const control = graph()->start(); + Reduction const r = + Reduce(graph()->NewNode(javascript()->CreateFunctionContext(8), closure, + context, effect, control)); + ASSERT_TRUE(r.Changed()); + EXPECT_THAT(r.replacement(), + IsFinishRegion(IsAllocate(IsNumberConstant(Context::SizeFor( + 8 + Context::MIN_CONTEXT_SLOTS)), + IsBeginRegion(effect), control), + _)); +} + + +TEST_F(JSTypedLoweringTest, JSCreateFunctionContextViaStub) { + Node* const closure = Parameter(Type::Any()); + Node* const context = Parameter(Type::Any()); + Node* const effect = graph()->start(); + Node* const control = graph()->start(); + Reduction const r = + Reduce(graph()->NewNode(javascript()->CreateFunctionContext(32), closure, + context, effect, control)); + ASSERT_TRUE(r.Changed()); + EXPECT_THAT(r.replacement(), + IsCall(_, IsHeapConstant( + CodeFactory::FastNewContext(isolate(), 32).code()), + closure, context, effect, control)); +} + + +// ----------------------------------------------------------------------------- // JSCreateWithContext TEST_F(JSTypedLoweringTest, JSCreateWithContext) { - FLAG_turbo_allocate = true; Node* const object = Parameter(Type::Receiver()); Node* const closure = Parameter(Type::Any()); Node* const context = Parameter(Type::Any()); @@ -1103,10 +1166,74 @@ TEST_F(JSTypedLoweringTest, JSCreateWithContext) { closure, context, frame_state, effect, control)); ASSERT_TRUE(r.Changed()); EXPECT_THAT(r.replacement(), - IsFinish(IsAllocate(IsNumberConstant(Context::SizeFor( - Context::MIN_CONTEXT_SLOTS)), - effect, control), - _)); + IsFinishRegion(IsAllocate(IsNumberConstant(Context::SizeFor( + Context::MIN_CONTEXT_SLOTS)), + IsBeginRegion(effect), control), + _)); +} + + +// ----------------------------------------------------------------------------- +// JSInstanceOf +// Test that instanceOf is reduced if and only if the right-hand side is a +// function constant. Functional correctness is ensured elsewhere. + + +TEST_F(JSTypedLoweringTest, JSInstanceOfSpecializationWithoutSmiCheck) { + Node* const context = Parameter(Type::Any()); + Node* const frame_state = EmptyFrameState(); + Node* const effect = graph()->start(); + Node* const control = graph()->start(); + + // Reduce if left-hand side is known to be an object. + Node* instanceOf = + graph()->NewNode(javascript()->InstanceOf(), Parameter(Type::Object(), 0), + HeapConstant(isolate()->object_function()), context, + frame_state, effect, control); + Node* dummy = graph()->NewNode(javascript()->ToObject(), instanceOf, context, + frame_state, effect, control); + Reduction r = Reduce(instanceOf); + ASSERT_TRUE(r.Changed()); + ASSERT_EQ(r.replacement(), dummy->InputAt(0)); + ASSERT_NE(instanceOf, dummy->InputAt(0)); +} + + +TEST_F(JSTypedLoweringTest, JSInstanceOfSpecializationWithSmiCheck) { + Node* const context = Parameter(Type::Any()); + Node* const frame_state = EmptyFrameState(); + Node* const effect = graph()->start(); + Node* const control = graph()->start(); + + // Reduce if left-hand side could be a Smi. + Node* instanceOf = + graph()->NewNode(javascript()->InstanceOf(), Parameter(Type::Any(), 0), + HeapConstant(isolate()->object_function()), context, + frame_state, effect, control); + Node* dummy = graph()->NewNode(javascript()->ToObject(), instanceOf, context, + frame_state, effect, control); + Reduction r = Reduce(instanceOf); + ASSERT_TRUE(r.Changed()); + ASSERT_EQ(r.replacement(), dummy->InputAt(0)); + ASSERT_NE(instanceOf, dummy->InputAt(0)); +} + + +TEST_F(JSTypedLoweringTest, JSInstanceOfNoSpecialization) { + Node* const context = Parameter(Type::Any()); + Node* const frame_state = EmptyFrameState(); + Node* const effect = graph()->start(); + Node* const control = graph()->start(); + + // Do not reduce if right-hand side is not a function constant. + Node* instanceOf = graph()->NewNode( + javascript()->InstanceOf(), Parameter(Type::Any(), 0), + Parameter(Type::Any()), context, frame_state, effect, control); + Node* dummy = graph()->NewNode(javascript()->ToObject(), instanceOf, context, + frame_state, effect, control); + Reduction r = Reduce(instanceOf); + ASSERT_FALSE(r.Changed()); + ASSERT_EQ(instanceOf, dummy->InputAt(0)); } } // namespace compiler diff --git a/deps/v8/test/unittests/compiler/live-range-unittest.cc b/deps/v8/test/unittests/compiler/live-range-unittest.cc index 886a8121c7..e802aedff1 100644 --- a/deps/v8/test/unittests/compiler/live-range-unittest.cc +++ b/deps/v8/test/unittests/compiler/live-range-unittest.cc @@ -32,11 +32,14 @@ class LiveRangeUnitTest : public TestWithZone { TopLevelLiveRange* Splinter(TopLevelLiveRange* top, int start, int end, int new_id = 0) { - TopLevelLiveRange* ret = - new (zone()) TopLevelLiveRange(new_id, MachineType::kRepTagged); + if (top->splinter() == nullptr) { + TopLevelLiveRange* ret = + new (zone()) TopLevelLiveRange(new_id, MachineType::kRepTagged); + top->SetSplinter(ret); + } top->Splinter(LifetimePosition::FromInt(start), - LifetimePosition::FromInt(end), ret, zone()); - return ret; + LifetimePosition::FromInt(end), zone()); + return top->splinter(); } // Ranges first and second match structurally. @@ -377,6 +380,25 @@ TEST_F(LiveRangeUnitTest, SplinterMultipleIntervalsRight) { } +TEST_F(LiveRangeUnitTest, SplinterMergeMultipleTimes) { + TopLevelLiveRange* range = + TestRangeBuilder(zone()).Add(0, 3).Add(5, 10).Add(12, 16).Build(); + Splinter(range, 4, 6); + Splinter(range, 8, 14); + TopLevelLiveRange* splinter = range->splinter(); + EXPECT_EQ(nullptr, range->next()); + EXPECT_EQ(nullptr, splinter->next()); + EXPECT_EQ(range, splinter->splintered_from()); + + TopLevelLiveRange* expected_source = + TestRangeBuilder(zone()).Add(0, 3).Add(6, 8).Add(14, 16).Build(); + TopLevelLiveRange* expected_splinter = + TestRangeBuilder(zone()).Add(5, 6).Add(8, 10).Add(12, 14).Build(); + EXPECT_TRUE(RangesMatch(expected_source, range)); + EXPECT_TRUE(RangesMatch(expected_splinter, splinter)); +} + + TEST_F(LiveRangeUnitTest, MergeMultipleIntervalsRight) { TopLevelLiveRange* original = TestRangeBuilder(zone()).Add(0, 3).Add(5, 8).Build(); @@ -416,8 +438,9 @@ TEST_F(LiveRangeUnitTest, IDGeneration) { TopLevelLiveRange* splinter = new (zone()) TopLevelLiveRange(101, MachineType::kRepTagged); + vreg->SetSplinter(splinter); vreg->Splinter(LifetimePosition::FromInt(4), LifetimePosition::FromInt(12), - splinter, zone()); + zone()); EXPECT_EQ(101, splinter->vreg()); EXPECT_EQ(1, splinter->relative_id()); diff --git a/deps/v8/test/unittests/compiler/liveness-analyzer-unittest.cc b/deps/v8/test/unittests/compiler/liveness-analyzer-unittest.cc index 9016e04e25..3f6a658e82 100644 --- a/deps/v8/test/unittests/compiler/liveness-analyzer-unittest.cc +++ b/deps/v8/test/unittests/compiler/liveness-analyzer-unittest.cc @@ -25,7 +25,8 @@ class LivenessAnalysisTest : public GraphTest { : locals_count_(locals_count), machine_(zone(), kRepWord32), javascript_(zone()), - jsgraph_(isolate(), graph(), common(), &javascript_, &machine_), + jsgraph_(isolate(), graph(), common(), &javascript_, nullptr, + &machine_), analyzer_(locals_count, zone()), empty_values_(graph()->NewNode(common()->StateValues(0), 0, nullptr)), next_checkpoint_id_(0), 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 13a5b6f3bb..6f7ed3aca4 100644 --- a/deps/v8/test/unittests/compiler/machine-operator-reducer-unittest.cc +++ b/deps/v8/test/unittests/compiler/machine-operator-reducer-unittest.cc @@ -29,7 +29,8 @@ class MachineOperatorReducerTest : public TypedGraphTest { protected: Reduction Reduce(Node* node) { JSOperatorBuilder javascript(zone()); - JSGraph jsgraph(isolate(), graph(), common(), &javascript, &machine_); + JSGraph jsgraph(isolate(), graph(), common(), &javascript, nullptr, + &machine_); MachineOperatorReducer reducer(&jsgraph); return reducer.Reduce(node); } @@ -1645,6 +1646,18 @@ TEST_F(MachineOperatorReducerTest, StoreRepWord16WithWord32SarAndWord32Shl) { } } + +TEST_F(MachineOperatorReducerTest, RoundPlusTruncate) { + Node* p0 = Parameter(0); + Node* t0 = graph()->NewNode(machine()->RoundInt64ToFloat64(), p0); + Node* t1 = graph()->NewNode( + machine()->TruncateFloat64ToInt32(TruncationMode::kJavaScript), t0); + + Reduction r = Reduce(t1); + ASSERT_TRUE(r.Changed()); + EXPECT_THAT(r.replacement(), p0); +} + } // namespace compiler } // namespace internal } // namespace v8 diff --git a/deps/v8/test/unittests/compiler/mips/instruction-selector-mips-unittest.cc b/deps/v8/test/unittests/compiler/mips/instruction-selector-mips-unittest.cc index b88f4695c8..a16ad7a31f 100644 --- a/deps/v8/test/unittests/compiler/mips/instruction-selector-mips-unittest.cc +++ b/deps/v8/test/unittests/compiler/mips/instruction-selector-mips-unittest.cc @@ -646,7 +646,7 @@ TEST_P(InstructionSelectorMemoryAccessTest, LoadWithParameters) { TEST_P(InstructionSelectorMemoryAccessTest, StoreWithParameters) { const MemoryAccess memacc = GetParam(); StreamBuilder m(this, kMachInt32, kMachPtr, kMachInt32, memacc.type); - m.Store(memacc.type, m.Parameter(0), m.Parameter(1)); + m.Store(memacc.type, m.Parameter(0), m.Parameter(1), kNoWriteBarrier); m.Return(m.Int32Constant(0)); Stream s = m.Build(); ASSERT_EQ(1U, s.size()); @@ -696,8 +696,8 @@ TEST_P(InstructionSelectorMemoryAccessImmTest, StoreWithImmediateIndex) { const MemoryAccessImm memacc = GetParam(); TRACED_FOREACH(int32_t, index, memacc.immediates) { StreamBuilder m(this, kMachInt32, kMachPtr, memacc.type); - m.Store(memacc.type, m.Parameter(0), m.Int32Constant(index), - m.Parameter(1)); + m.Store(memacc.type, m.Parameter(0), m.Int32Constant(index), m.Parameter(1), + kNoWriteBarrier); m.Return(m.Int32Constant(0)); Stream s = m.Build(); ASSERT_EQ(1U, s.size()); @@ -748,8 +748,8 @@ TEST_P(InstructionSelectorMemoryAccessImmMoreThan16bitTest, const MemoryAccessImm1 memacc = GetParam(); TRACED_FOREACH(int32_t, index, memacc.immediates) { StreamBuilder m(this, kMachInt32, kMachPtr, memacc.type); - m.Store(memacc.type, m.Parameter(0), m.Int32Constant(index), - m.Parameter(1)); + m.Store(memacc.type, m.Parameter(0), m.Int32Constant(index), m.Parameter(1), + kNoWriteBarrier); m.Return(m.Int32Constant(0)); Stream s = m.Build(); ASSERT_EQ(2U, s.size()); @@ -845,6 +845,71 @@ TEST_F(InstructionSelectorTest, Float64Abs) { EXPECT_EQ(s.ToVreg(n), s.ToVreg(s[0]->Output())); } + +TEST_F(InstructionSelectorTest, Float32Max) { + StreamBuilder m(this, kMachFloat32, kMachFloat32, kMachFloat32); + Node* const p0 = m.Parameter(0); + Node* const p1 = m.Parameter(1); + Node* const n = m.Float32Max(p0, p1); + m.Return(n); + Stream s = m.Build(); + // Float32Max is `(b < a) ? a : b`. + ASSERT_EQ(1U, s.size()); + EXPECT_EQ(kMipsFloat32Max, s[0]->arch_opcode()); + ASSERT_EQ(2U, s[0]->InputCount()); + ASSERT_EQ(1U, s[0]->OutputCount()); + EXPECT_EQ(s.ToVreg(n), s.ToVreg(s[0]->Output())); +} + + +TEST_F(InstructionSelectorTest, Float32Min) { + StreamBuilder m(this, kMachFloat32, kMachFloat32, kMachFloat32); + Node* const p0 = m.Parameter(0); + Node* const p1 = m.Parameter(1); + Node* const n = m.Float32Min(p0, p1); + m.Return(n); + Stream s = m.Build(); + // Float32Min is `(a < b) ? a : b`. + ASSERT_EQ(1U, s.size()); + EXPECT_EQ(kMipsFloat32Min, s[0]->arch_opcode()); + ASSERT_EQ(2U, s[0]->InputCount()); + ASSERT_EQ(1U, s[0]->OutputCount()); + EXPECT_EQ(s.ToVreg(n), s.ToVreg(s[0]->Output())); +} + + +TEST_F(InstructionSelectorTest, Float64Max) { + StreamBuilder m(this, kMachFloat64, kMachFloat64, kMachFloat64); + Node* const p0 = m.Parameter(0); + Node* const p1 = m.Parameter(1); + Node* const n = m.Float64Max(p0, p1); + m.Return(n); + Stream s = m.Build(); + // Float64Max is `(b < a) ? a : b`. + ASSERT_EQ(1U, s.size()); + EXPECT_EQ(kMipsFloat64Max, s[0]->arch_opcode()); + ASSERT_EQ(2U, s[0]->InputCount()); + ASSERT_EQ(1U, s[0]->OutputCount()); + EXPECT_EQ(s.ToVreg(n), s.ToVreg(s[0]->Output())); +} + + +TEST_F(InstructionSelectorTest, Float64Min) { + StreamBuilder m(this, kMachFloat64, kMachFloat64, kMachFloat64); + Node* const p0 = m.Parameter(0); + Node* const p1 = m.Parameter(1); + Node* const n = m.Float64Min(p0, p1); + m.Return(n); + Stream s = m.Build(); + // Float64Min is `(a < b) ? a : b`. + ASSERT_EQ(1U, s.size()); + EXPECT_EQ(kMipsFloat64Min, s[0]->arch_opcode()); + ASSERT_EQ(2U, s[0]->InputCount()); + ASSERT_EQ(1U, s[0]->OutputCount()); + EXPECT_EQ(s.ToVreg(n), s.ToVreg(s[0]->Output())); +} + + } // namespace compiler } // namespace internal } // namespace v8 diff --git a/deps/v8/test/unittests/compiler/mips64/instruction-selector-mips64-unittest.cc b/deps/v8/test/unittests/compiler/mips64/instruction-selector-mips64-unittest.cc index fe57eb5e28..148667333b 100644 --- a/deps/v8/test/unittests/compiler/mips64/instruction-selector-mips64-unittest.cc +++ b/deps/v8/test/unittests/compiler/mips64/instruction-selector-mips64-unittest.cc @@ -649,7 +649,7 @@ TEST_P(InstructionSelectorMemoryAccessTest, LoadWithParameters) { TEST_P(InstructionSelectorMemoryAccessTest, StoreWithParameters) { const MemoryAccess memacc = GetParam(); StreamBuilder m(this, kMachInt32, kMachPtr, kMachInt32, memacc.type); - m.Store(memacc.type, m.Parameter(0), m.Parameter(1)); + m.Store(memacc.type, m.Parameter(0), m.Parameter(1), kNoWriteBarrier); m.Return(m.Int32Constant(0)); Stream s = m.Build(); ASSERT_EQ(1U, s.size()); @@ -697,8 +697,8 @@ TEST_P(InstructionSelectorMemoryAccessImmTest, StoreWithImmediateIndex) { const MemoryAccessImm memacc = GetParam(); TRACED_FOREACH(int32_t, index, memacc.immediates) { StreamBuilder m(this, kMachInt32, kMachPtr, memacc.type); - m.Store(memacc.type, m.Parameter(0), m.Int32Constant(index), - m.Parameter(1)); + m.Store(memacc.type, m.Parameter(0), m.Int32Constant(index), m.Parameter(1), + kNoWriteBarrier); m.Return(m.Int32Constant(0)); Stream s = m.Build(); ASSERT_EQ(1U, s.size()); @@ -746,8 +746,8 @@ TEST_P(InstructionSelectorMemoryAccessImmMoreThan16bitTest, const MemoryAccessImm1 memacc = GetParam(); TRACED_FOREACH(int32_t, index, memacc.immediates) { StreamBuilder m(this, kMachInt32, kMachPtr, memacc.type); - m.Store(memacc.type, m.Parameter(0), m.Int32Constant(index), - m.Parameter(1)); + m.Store(memacc.type, m.Parameter(0), m.Int32Constant(index), m.Parameter(1), + kNoWriteBarrier); m.Return(m.Int32Constant(0)); Stream s = m.Build(); ASSERT_EQ(2U, s.size()); @@ -841,6 +841,21 @@ TEST_F(InstructionSelectorTest, Word32Clz) { } +TEST_F(InstructionSelectorTest, Word64Clz) { + StreamBuilder m(this, kMachUint64, kMachUint64); + Node* const p0 = m.Parameter(0); + Node* const n = m.Word64Clz(p0); + m.Return(n); + Stream s = m.Build(); + ASSERT_EQ(1U, s.size()); + EXPECT_EQ(kMips64Dclz, s[0]->arch_opcode()); + ASSERT_EQ(1U, s[0]->InputCount()); + EXPECT_EQ(s.ToVreg(p0), s.ToVreg(s[0]->InputAt(0))); + ASSERT_EQ(1U, s[0]->OutputCount()); + EXPECT_EQ(s.ToVreg(n), s.ToVreg(s[0]->Output())); +} + + TEST_F(InstructionSelectorTest, Float32Abs) { StreamBuilder m(this, kMachFloat32, kMachFloat32); Node* const p0 = m.Parameter(0); @@ -870,6 +885,70 @@ TEST_F(InstructionSelectorTest, Float64Abs) { EXPECT_EQ(s.ToVreg(n), s.ToVreg(s[0]->Output())); } + +TEST_F(InstructionSelectorTest, Float32Max) { + StreamBuilder m(this, kMachFloat32, kMachFloat32, kMachFloat32); + Node* const p0 = m.Parameter(0); + Node* const p1 = m.Parameter(1); + Node* const n = m.Float32Max(p0, p1); + m.Return(n); + Stream s = m.Build(); + // Float32Max is `(b < a) ? a : b`. + ASSERT_EQ(1U, s.size()); + EXPECT_EQ(kMips64Float32Max, s[0]->arch_opcode()); + ASSERT_EQ(2U, s[0]->InputCount()); + ASSERT_EQ(1U, s[0]->OutputCount()); + EXPECT_EQ(s.ToVreg(n), s.ToVreg(s[0]->Output())); +} + + +TEST_F(InstructionSelectorTest, Float32Min) { + StreamBuilder m(this, kMachFloat32, kMachFloat32, kMachFloat32); + Node* const p0 = m.Parameter(0); + Node* const p1 = m.Parameter(1); + Node* const n = m.Float32Min(p0, p1); + m.Return(n); + Stream s = m.Build(); + // Float32Min is `(a < b) ? a : b`. + ASSERT_EQ(1U, s.size()); + EXPECT_EQ(kMips64Float32Min, s[0]->arch_opcode()); + ASSERT_EQ(2U, s[0]->InputCount()); + ASSERT_EQ(1U, s[0]->OutputCount()); + EXPECT_EQ(s.ToVreg(n), s.ToVreg(s[0]->Output())); +} + + +TEST_F(InstructionSelectorTest, Float64Max) { + StreamBuilder m(this, kMachFloat64, kMachFloat64, kMachFloat64); + Node* const p0 = m.Parameter(0); + Node* const p1 = m.Parameter(1); + Node* const n = m.Float64Max(p0, p1); + m.Return(n); + Stream s = m.Build(); + // Float64Max is `(b < a) ? a : b`. + ASSERT_EQ(1U, s.size()); + EXPECT_EQ(kMips64Float64Max, s[0]->arch_opcode()); + ASSERT_EQ(2U, s[0]->InputCount()); + ASSERT_EQ(1U, s[0]->OutputCount()); + EXPECT_EQ(s.ToVreg(n), s.ToVreg(s[0]->Output())); +} + + +TEST_F(InstructionSelectorTest, Float64Min) { + StreamBuilder m(this, kMachFloat64, kMachFloat64, kMachFloat64); + Node* const p0 = m.Parameter(0); + Node* const p1 = m.Parameter(1); + Node* const n = m.Float64Min(p0, p1); + m.Return(n); + Stream s = m.Build(); + // Float64Min is `(a < b) ? a : b`. + ASSERT_EQ(1U, s.size()); + EXPECT_EQ(kMips64Float64Min, s[0]->arch_opcode()); + ASSERT_EQ(2U, s[0]->InputCount()); + ASSERT_EQ(1U, s[0]->OutputCount()); + EXPECT_EQ(s.ToVreg(n), s.ToVreg(s[0]->Output())); +} + } // namespace compiler } // namespace internal } // namespace v8 diff --git a/deps/v8/test/unittests/compiler/move-optimizer-unittest.cc b/deps/v8/test/unittests/compiler/move-optimizer-unittest.cc index fb2b6ad457..66eb9abc4f 100644 --- a/deps/v8/test/unittests/compiler/move-optimizer-unittest.cc +++ b/deps/v8/test/unittests/compiler/move-optimizer-unittest.cc @@ -67,10 +67,16 @@ class MoveOptimizerTest : public InstructionSequenceTest { case kConstant: return ConstantOperand(op.value_); case kFixedSlot: - return StackSlotOperand(kRepWord32, op.value_); + return AllocatedOperand(LocationOperand::STACK_SLOT, kRepWord32, + op.value_); case kFixedRegister: CHECK(0 <= op.value_ && op.value_ < num_general_registers()); - return RegisterOperand(kRepWord32, op.value_); + return AllocatedOperand(LocationOperand::REGISTER, kRepWord32, + op.value_); + case kExplicit: + CHECK(0 <= op.value_ && op.value_ < num_general_registers()); + return ExplicitOperand(LocationOperand::REGISTER, kRepWord32, + op.value_); default: break; } @@ -97,6 +103,30 @@ TEST_F(MoveOptimizerTest, RemovesRedundant) { } +TEST_F(MoveOptimizerTest, RemovesRedundantExplicit) { + int first_reg_index = + RegisterConfiguration::ArchDefault(RegisterConfiguration::TURBOFAN) + ->GetAllocatableGeneralCode(0); + int second_reg_index = + RegisterConfiguration::ArchDefault(RegisterConfiguration::TURBOFAN) + ->GetAllocatableGeneralCode(1); + + StartBlock(); + auto first_instr = EmitNop(); + AddMove(first_instr, Reg(first_reg_index), ExplicitReg(second_reg_index)); + auto last_instr = EmitNop(); + AddMove(last_instr, Reg(second_reg_index), Reg(first_reg_index)); + EndBlock(Last()); + + Optimize(); + + CHECK_EQ(0, NonRedundantSize(first_instr->parallel_moves()[0])); + auto move = last_instr->parallel_moves()[0]; + CHECK_EQ(1, NonRedundantSize(move)); + CHECK(Contains(move, Reg(first_reg_index), ExplicitReg(second_reg_index))); +} + + TEST_F(MoveOptimizerTest, SplitsConstants) { StartBlock(); EndBlock(Last()); @@ -177,6 +207,45 @@ TEST_F(MoveOptimizerTest, SimpleMergeCycle) { CHECK(Contains(move, Reg(1), Reg(0))); } + +TEST_F(MoveOptimizerTest, GapsCanMoveOverInstruction) { + StartBlock(); + int const_index = 1; + DefineConstant(const_index); + Instruction* ctant_def = LastInstruction(); + AddMove(ctant_def, Reg(1), Reg(0)); + + Instruction* last = EmitNop(); + AddMove(last, Const(const_index), Reg(0)); + AddMove(last, Reg(0), Reg(1)); + EndBlock(Last()); + Optimize(); + + ParallelMove* inst1_start = + ctant_def->GetParallelMove(Instruction::GapPosition::START); + ParallelMove* inst1_end = + ctant_def->GetParallelMove(Instruction::GapPosition::END); + ParallelMove* last_start = + last->GetParallelMove(Instruction::GapPosition::START); + CHECK(inst1_start == nullptr || inst1_start->size() == 0); + CHECK(inst1_end == nullptr || inst1_end->size() == 0); + CHECK(last_start->size() == 2); + int redundants = 0; + int assignment = 0; + for (MoveOperands* move : *last_start) { + if (move->IsRedundant()) { + ++redundants; + } else { + ++assignment; + CHECK(move->destination().IsRegister()); + CHECK(move->source().IsConstant()); + } + } + CHECK_EQ(1, redundants); + CHECK_EQ(1, assignment); +} + + } // namespace compiler } // namespace internal } // namespace v8 diff --git a/deps/v8/test/unittests/compiler/node-matchers-unittest.cc b/deps/v8/test/unittests/compiler/node-matchers-unittest.cc index 57174cc56b..f0cc407445 100644 --- a/deps/v8/test/unittests/compiler/node-matchers-unittest.cc +++ b/deps/v8/test/unittests/compiler/node-matchers-unittest.cc @@ -38,7 +38,8 @@ void CheckBaseWithIndexAndDisplacement(Matcher* matcher, Node* index, int scale, EXPECT_EQ(base, matcher->base()); EXPECT_EQ(displacement, matcher->displacement()); } -}; + +} // namespace TEST_F(NodeMatcherTest, ScaledWithOffset32Matcher) { diff --git a/deps/v8/test/unittests/compiler/node-test-utils.cc b/deps/v8/test/unittests/compiler/node-test-utils.cc index 2ca1b78d09..34afc8822b 100644 --- a/deps/v8/test/unittests/compiler/node-test-utils.cc +++ b/deps/v8/test/unittests/compiler/node-test-utils.cc @@ -261,11 +261,34 @@ class IsControl3Matcher final : public NodeMatcher { }; -class IsFinishMatcher final : public NodeMatcher { +class IsBeginRegionMatcher final : public NodeMatcher { public: - IsFinishMatcher(const Matcher<Node*>& value_matcher, - const Matcher<Node*>& effect_matcher) - : NodeMatcher(IrOpcode::kFinish), + explicit IsBeginRegionMatcher(const Matcher<Node*>& effect_matcher) + : NodeMatcher(IrOpcode::kBeginRegion), effect_matcher_(effect_matcher) {} + + void DescribeTo(std::ostream* os) const final { + NodeMatcher::DescribeTo(os); + *os << " whose effect ("; + effect_matcher_.DescribeTo(os); + *os << ")"; + } + + bool MatchAndExplain(Node* node, MatchResultListener* listener) const final { + return (NodeMatcher::MatchAndExplain(node, listener) && + PrintMatchAndExplain(NodeProperties::GetEffectInput(node), "effect", + effect_matcher_, listener)); + } + + private: + const Matcher<Node*> effect_matcher_; +}; + + +class IsFinishRegionMatcher final : public NodeMatcher { + public: + IsFinishRegionMatcher(const Matcher<Node*>& value_matcher, + const Matcher<Node*>& effect_matcher) + : NodeMatcher(IrOpcode::kFinishRegion), value_matcher_(value_matcher), effect_matcher_(effect_matcher) {} @@ -1501,14 +1524,14 @@ Matcher<Node*> IsIfDefault(const Matcher<Node*>& control_matcher) { } -Matcher<Node*> IsValueEffect(const Matcher<Node*>& value_matcher) { - return MakeMatcher(new IsUnopMatcher(IrOpcode::kValueEffect, value_matcher)); +Matcher<Node*> IsBeginRegion(const Matcher<Node*>& effect_matcher) { + return MakeMatcher(new IsBeginRegionMatcher(effect_matcher)); } -Matcher<Node*> IsFinish(const Matcher<Node*>& value_matcher, - const Matcher<Node*>& effect_matcher) { - return MakeMatcher(new IsFinishMatcher(value_matcher, effect_matcher)); +Matcher<Node*> IsFinishRegion(const Matcher<Node*>& value_matcher, + const Matcher<Node*>& effect_matcher) { + return MakeMatcher(new IsFinishRegionMatcher(value_matcher, effect_matcher)); } @@ -1989,14 +2012,17 @@ IS_BINOP_MATCHER(NumberShiftLeft) IS_BINOP_MATCHER(NumberShiftRight) IS_BINOP_MATCHER(NumberShiftRightLogical) IS_BINOP_MATCHER(Word32And) +IS_BINOP_MATCHER(Word32Or) IS_BINOP_MATCHER(Word32Sar) IS_BINOP_MATCHER(Word32Shl) IS_BINOP_MATCHER(Word32Shr) IS_BINOP_MATCHER(Word32Ror) IS_BINOP_MATCHER(Word32Equal) IS_BINOP_MATCHER(Word64And) +IS_BINOP_MATCHER(Word64Or) IS_BINOP_MATCHER(Word64Sar) IS_BINOP_MATCHER(Word64Shl) +IS_BINOP_MATCHER(Word64Shr) IS_BINOP_MATCHER(Word64Equal) IS_BINOP_MATCHER(Int32AddWithOverflow) IS_BINOP_MATCHER(Int32Add) @@ -2008,6 +2034,7 @@ IS_BINOP_MATCHER(Uint32LessThan) IS_BINOP_MATCHER(Uint32LessThanOrEqual) IS_BINOP_MATCHER(Int64Add) IS_BINOP_MATCHER(Int64Sub) +IS_BINOP_MATCHER(Int64Mul) IS_BINOP_MATCHER(JSAdd) IS_BINOP_MATCHER(Float32Max) IS_BINOP_MATCHER(Float32Min) @@ -2036,6 +2063,7 @@ IS_UNOP_MATCHER(ChangeUint32ToUint64) IS_UNOP_MATCHER(TruncateFloat64ToFloat32) IS_UNOP_MATCHER(TruncateFloat64ToInt32) IS_UNOP_MATCHER(TruncateInt64ToInt32) +IS_UNOP_MATCHER(RoundInt64ToFloat64) IS_UNOP_MATCHER(Float32Abs) IS_UNOP_MATCHER(Float64Abs) IS_UNOP_MATCHER(Float64Sqrt) diff --git a/deps/v8/test/unittests/compiler/node-test-utils.h b/deps/v8/test/unittests/compiler/node-test-utils.h index 7042d9943b..ffdad5812a 100644 --- a/deps/v8/test/unittests/compiler/node-test-utils.h +++ b/deps/v8/test/unittests/compiler/node-test-utils.h @@ -63,9 +63,9 @@ Matcher<Node*> IsSwitch(const Matcher<Node*>& value_matcher, Matcher<Node*> IsIfValue(const Matcher<int32_t>& value_matcher, const Matcher<Node*>& control_matcher); Matcher<Node*> IsIfDefault(const Matcher<Node*>& control_matcher); -Matcher<Node*> IsValueEffect(const Matcher<Node*>& value_matcher); -Matcher<Node*> IsFinish(const Matcher<Node*>& value_matcher, - const Matcher<Node*>& effect_matcher); +Matcher<Node*> IsBeginRegion(const Matcher<Node*>& effect_matcher); +Matcher<Node*> IsFinishRegion(const Matcher<Node*>& value_matcher, + const Matcher<Node*>& effect_matcher); Matcher<Node*> IsReturn(const Matcher<Node*>& value_matcher, const Matcher<Node*>& effect_matcher, const Matcher<Node*>& control_matcher); @@ -256,6 +256,8 @@ Matcher<Node*> IsStore(const Matcher<StoreRepresentation>& rep_matcher, const Matcher<Node*>& control_matcher); Matcher<Node*> IsWord32And(const Matcher<Node*>& lhs_matcher, const Matcher<Node*>& rhs_matcher); +Matcher<Node*> IsWord32Or(const Matcher<Node*>& lhs_matcher, + const Matcher<Node*>& rhs_matcher); Matcher<Node*> IsWord32Sar(const Matcher<Node*>& lhs_matcher, const Matcher<Node*>& rhs_matcher); Matcher<Node*> IsWord32Shl(const Matcher<Node*>& lhs_matcher, @@ -269,8 +271,12 @@ Matcher<Node*> IsWord32Equal(const Matcher<Node*>& lhs_matcher, Matcher<Node*> IsWord32Clz(const Matcher<Node*>& value_matcher); Matcher<Node*> IsWord64And(const Matcher<Node*>& lhs_matcher, const Matcher<Node*>& rhs_matcher); +Matcher<Node*> IsWord64Or(const Matcher<Node*>& lhs_matcher, + const Matcher<Node*>& rhs_matcher); Matcher<Node*> IsWord64Shl(const Matcher<Node*>& lhs_matcher, const Matcher<Node*>& rhs_matcher); +Matcher<Node*> IsWord64Shr(const Matcher<Node*>& lhs_matcher, + const Matcher<Node*>& rhs_matcher); Matcher<Node*> IsWord64Sar(const Matcher<Node*>& lhs_matcher, const Matcher<Node*>& rhs_matcher); Matcher<Node*> IsWord64Equal(const Matcher<Node*>& lhs_matcher, @@ -295,6 +301,8 @@ 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*> IsInt64Mul(const Matcher<Node*>& lhs_matcher, + const Matcher<Node*>& rhs_matcher); Matcher<Node*> IsJSAdd(const Matcher<Node*>& lhs_matcher, const Matcher<Node*>& rhs_matcher); Matcher<Node*> IsChangeFloat64ToInt32(const Matcher<Node*>& input_matcher); @@ -306,6 +314,7 @@ Matcher<Node*> IsChangeUint32ToUint64(const Matcher<Node*>& input_matcher); Matcher<Node*> IsTruncateFloat64ToFloat32(const Matcher<Node*>& input_matcher); Matcher<Node*> IsTruncateFloat64ToInt32(const Matcher<Node*>& input_matcher); Matcher<Node*> IsTruncateInt64ToInt32(const Matcher<Node*>& input_matcher); +Matcher<Node*> IsRoundInt64ToFloat64(const Matcher<Node*>& input_matcher); Matcher<Node*> IsFloat32Max(const Matcher<Node*>& lhs_matcher, const Matcher<Node*>& rhs_matcher); Matcher<Node*> IsFloat32Min(const Matcher<Node*>& lhs_matcher, diff --git a/deps/v8/test/unittests/compiler/register-allocator-unittest.cc b/deps/v8/test/unittests/compiler/register-allocator-unittest.cc index 23a118b6ad..c5ff90f301 100644 --- a/deps/v8/test/unittests/compiler/register-allocator-unittest.cc +++ b/deps/v8/test/unittests/compiler/register-allocator-unittest.cc @@ -41,7 +41,8 @@ bool AllocatedOperandMatches( const AllocatedOperand& op, const InstructionSequenceTest::TestOperand& test_op) { return AreOperandsOfSameType(op, test_op) && - (op.index() == test_op.value_ || + ((op.IsRegister() ? op.GetRegister().code() : op.index()) == + test_op.value_ || test_op.value_ == InstructionSequenceTest::kNoValue); } @@ -75,7 +76,8 @@ bool IsParallelMovePresent(int instr_index, Instruction::GapPosition gap_pos, } return found_match; } -} + +} // namespace class RegisterAllocatorTest : public InstructionSequenceTest { @@ -722,7 +724,8 @@ class SlotConstraintTest : public RegisterAllocatorTest, private: typedef ::testing::WithParamInterface<::testing::tuple<ParameterType, int>> B; }; -} + +} // namespace #if GTEST_HAS_COMBINE diff --git a/deps/v8/test/unittests/compiler/scheduler-unittest.cc b/deps/v8/test/unittests/compiler/scheduler-unittest.cc index 45d555d7a1..af43b2efff 100644 --- a/deps/v8/test/unittests/compiler/scheduler-unittest.cc +++ b/deps/v8/test/unittests/compiler/scheduler-unittest.cc @@ -1124,13 +1124,11 @@ TARGET_TEST_F(SchedulerTest, Terminate) { Node* loop = graph()->NewNode(common()->Loop(2), start, start); loop->ReplaceInput(1, loop); // self loop, NTL. - Node* effect = graph()->NewNode(common()->EffectPhi(1), start, loop); + Node* effect = graph()->NewNode(common()->EffectPhi(2), start, start, loop); + effect->ReplaceInput(1, effect); // self loop. Node* terminate = graph()->NewNode(common()->Terminate(), effect, loop); - effect->ReplaceInput(1, terminate); - Node* end = graph()->NewNode(common()->End(1), terminate); - graph()->SetEnd(end); Schedule* schedule = ComputeAndVerifySchedule(6); diff --git a/deps/v8/test/unittests/compiler/simplified-operator-reducer-unittest.cc b/deps/v8/test/unittests/compiler/simplified-operator-reducer-unittest.cc index 79e530f228..f571898107 100644 --- a/deps/v8/test/unittests/compiler/simplified-operator-reducer-unittest.cc +++ b/deps/v8/test/unittests/compiler/simplified-operator-reducer-unittest.cc @@ -30,7 +30,8 @@ class SimplifiedOperatorReducerTest : public TypedGraphTest { Reduction Reduce(Node* node) { MachineOperatorBuilder machine(zone()); JSOperatorBuilder javascript(zone()); - JSGraph jsgraph(isolate(), graph(), common(), &javascript, &machine); + JSGraph jsgraph(isolate(), graph(), common(), &javascript, simplified(), + &machine); SimplifiedOperatorReducer reducer(&jsgraph); return reducer.Reduce(node); } diff --git a/deps/v8/test/unittests/compiler/simplified-operator-unittest.cc b/deps/v8/test/unittests/compiler/simplified-operator-unittest.cc index 7e4329ea3a..b09840710a 100644 --- a/deps/v8/test/unittests/compiler/simplified-operator-unittest.cc +++ b/deps/v8/test/unittests/compiler/simplified-operator-unittest.cc @@ -48,6 +48,12 @@ const PureOperator kPureOperators[] = { PURE(NumberMultiply, Operator::kCommutative, 2), PURE(NumberDivide, Operator::kNoProperties, 2), PURE(NumberModulus, Operator::kNoProperties, 2), + PURE(NumberBitwiseOr, Operator::kCommutative, 2), + PURE(NumberBitwiseXor, Operator::kCommutative, 2), + PURE(NumberBitwiseAnd, Operator::kCommutative, 2), + PURE(NumberShiftLeft, Operator::kNoProperties, 2), + PURE(NumberShiftRight, Operator::kNoProperties, 2), + PURE(NumberShiftRightLogical, Operator::kNoProperties, 2), PURE(NumberToInt32, Operator::kNoProperties, 1), PURE(NumberToUint32, Operator::kNoProperties, 1), PURE(PlainPrimitiveToNumber, Operator::kNoProperties, 1), diff --git a/deps/v8/test/unittests/compiler/state-values-utils-unittest.cc b/deps/v8/test/unittests/compiler/state-values-utils-unittest.cc index e6f4701598..311b90a8d1 100644 --- a/deps/v8/test/unittests/compiler/state-values-utils-unittest.cc +++ b/deps/v8/test/unittests/compiler/state-values-utils-unittest.cc @@ -95,7 +95,8 @@ TEST_F(StateValuesIteratorTest, TreeFromVector) { TRACED_FOREACH(int, count, sizes) { JSOperatorBuilder javascript(zone()); MachineOperatorBuilder machine(zone()); - JSGraph jsgraph(isolate(), graph(), common(), &javascript, &machine); + JSGraph jsgraph(isolate(), graph(), common(), &javascript, nullptr, + &machine); // Generate the input vector. NodeVector inputs(zone()); @@ -124,7 +125,8 @@ TEST_F(StateValuesIteratorTest, BuildTreeIdentical) { TRACED_FOREACH(int, count, sizes) { JSOperatorBuilder javascript(zone()); MachineOperatorBuilder machine(zone()); - JSGraph jsgraph(isolate(), graph(), common(), &javascript, &machine); + JSGraph jsgraph(isolate(), graph(), common(), &javascript, nullptr, + &machine); // Generate the input vector. NodeVector inputs(zone()); diff --git a/deps/v8/test/unittests/compiler/typer-unittest.cc b/deps/v8/test/unittests/compiler/typer-unittest.cc index 7113bf2eec..4a462cef10 100644 --- a/deps/v8/test/unittests/compiler/typer-unittest.cc +++ b/deps/v8/test/unittests/compiler/typer-unittest.cc @@ -11,9 +11,9 @@ #include "test/cctest/types-fuzz.h" #include "test/unittests/compiler/graph-unittest.h" -using namespace v8::internal; -using namespace v8::internal::compiler; - +namespace v8 { +namespace internal { +namespace compiler { // TODO(titzer): generate a large set of deterministic inputs for these tests. class TyperTest : public TypedGraphTest { @@ -417,3 +417,7 @@ TEST_F(TyperTest, TypeRegressInt32Constant) { EXPECT_TRUE(type->Is(NewRange(i, i))); } } + +} // namespace compiler +} // namespace internal +} // namespace v8 diff --git a/deps/v8/test/unittests/compiler/x64/instruction-selector-x64-unittest.cc b/deps/v8/test/unittests/compiler/x64/instruction-selector-x64-unittest.cc index 0b46b32306..f28087c54c 100644 --- a/deps/v8/test/unittests/compiler/x64/instruction-selector-x64-unittest.cc +++ b/deps/v8/test/unittests/compiler/x64/instruction-selector-x64-unittest.cc @@ -124,7 +124,8 @@ TEST_P(InstructionSelectorMemoryAccessTest, LoadWithParameters) { TEST_P(InstructionSelectorMemoryAccessTest, StoreWithParameters) { const MemoryAccess memacc = GetParam(); StreamBuilder m(this, kMachInt32, kMachPtr, kMachInt32, memacc.type); - m.Store(memacc.type, m.Parameter(0), m.Parameter(1), m.Parameter(2)); + m.Store(memacc.type, m.Parameter(0), m.Parameter(1), m.Parameter(2), + kNoWriteBarrier); m.Return(m.Int32Constant(0)); Stream s = m.Build(); ASSERT_EQ(1U, s.size()); |