OLD | NEW |
(Empty) | |
| 1 // Copyright 2015 the V8 project authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. |
| 4 |
| 5 #include <iostream> |
| 6 |
| 7 #include "src/compiler/bytecode-graph-builder.h" |
| 8 #include "src/compiler/common-operator.h" |
| 9 #include "src/compiler/graph-visualizer.h" |
| 10 #include "src/compiler/instruction.h" |
| 11 #include "src/compiler/instruction-selector.h" |
| 12 #include "src/compiler/js-graph.h" |
| 13 #include "src/compiler/js-operator.h" |
| 14 #include "src/interpreter/bytecode-array-builder.h" |
| 15 #include "src/parser.h" |
| 16 #include "test/unittests/compiler/compiler-test-utils.h" |
| 17 #include "test/unittests/compiler/graph-unittest.h" |
| 18 #include "test/unittests/compiler/node-test-utils.h" |
| 19 #include "test/unittests/test-utils.h" |
| 20 |
| 21 using ::testing::_; |
| 22 |
| 23 namespace v8 { |
| 24 namespace internal { |
| 25 namespace compiler { |
| 26 |
| 27 class BytecodeGraphBuilderTest : public TestWithIsolateAndZone { |
| 28 public: |
| 29 BytecodeGraphBuilderTest() : array_builder_(isolate(), zone()) {} |
| 30 |
| 31 Graph* GetCompletedGraph(); |
| 32 |
| 33 Matcher<Node*> IsUndefinedConstant(); |
| 34 Matcher<Node*> IsNullConstant(); |
| 35 Matcher<Node*> IsTheHoleConstant(); |
| 36 Matcher<Node*> IsFalseConstant(); |
| 37 Matcher<Node*> IsTrueConstant(); |
| 38 |
| 39 interpreter::BytecodeArrayBuilder* array_builder() { return &array_builder_; } |
| 40 |
| 41 private: |
| 42 interpreter::BytecodeArrayBuilder array_builder_; |
| 43 |
| 44 DISALLOW_COPY_AND_ASSIGN(BytecodeGraphBuilderTest); |
| 45 }; |
| 46 |
| 47 |
| 48 Graph* BytecodeGraphBuilderTest::GetCompletedGraph() { |
| 49 MachineOperatorBuilder* machine = new (zone()) MachineOperatorBuilder( |
| 50 zone(), kMachPtr, InstructionSelector::SupportedMachineOperatorFlags()); |
| 51 CommonOperatorBuilder* common = new (zone()) CommonOperatorBuilder(zone()); |
| 52 JSOperatorBuilder* javascript = new (zone()) JSOperatorBuilder(zone()); |
| 53 Graph* graph = new (zone()) Graph(zone()); |
| 54 JSGraph* jsgraph = |
| 55 new (zone()) JSGraph(isolate(), graph, common, javascript, machine); |
| 56 |
| 57 Handle<String> name = factory()->NewStringFromStaticChars("test"); |
| 58 Handle<String> script = factory()->NewStringFromStaticChars("test() {}"); |
| 59 Handle<SharedFunctionInfo> shared_info = |
| 60 factory()->NewSharedFunctionInfo(name, MaybeHandle<Code>()); |
| 61 shared_info->set_script(*factory()->NewScript(script)); |
| 62 |
| 63 ParseInfo parse_info(zone(), shared_info); |
| 64 CompilationInfo info(&parse_info); |
| 65 Handle<BytecodeArray> bytecode_array = array_builder()->ToBytecodeArray(); |
| 66 info.shared_info()->set_function_data(*bytecode_array); |
| 67 |
| 68 BytecodeGraphBuilder graph_builder(zone(), &info, jsgraph); |
| 69 graph_builder.CreateGraph(); |
| 70 return graph; |
| 71 } |
| 72 |
| 73 |
| 74 Matcher<Node*> BytecodeGraphBuilderTest::IsUndefinedConstant() { |
| 75 return IsHeapConstant(factory()->undefined_value()); |
| 76 } |
| 77 |
| 78 |
| 79 Matcher<Node*> BytecodeGraphBuilderTest::IsNullConstant() { |
| 80 return IsHeapConstant(factory()->null_value()); |
| 81 } |
| 82 |
| 83 |
| 84 Matcher<Node*> BytecodeGraphBuilderTest::IsTheHoleConstant() { |
| 85 return IsHeapConstant(factory()->the_hole_value()); |
| 86 } |
| 87 |
| 88 |
| 89 Matcher<Node*> BytecodeGraphBuilderTest::IsFalseConstant() { |
| 90 return IsHeapConstant(factory()->false_value()); |
| 91 } |
| 92 |
| 93 |
| 94 Matcher<Node*> BytecodeGraphBuilderTest::IsTrueConstant() { |
| 95 return IsHeapConstant(factory()->true_value()); |
| 96 } |
| 97 |
| 98 |
| 99 TEST_F(BytecodeGraphBuilderTest, ReturnUndefined) { |
| 100 array_builder()->set_locals_count(0); |
| 101 array_builder()->set_parameter_count(1); |
| 102 array_builder()->LoadUndefined().Return(); |
| 103 |
| 104 Graph* graph = GetCompletedGraph(); |
| 105 Node* end = graph->end(); |
| 106 EXPECT_EQ(1, end->InputCount()); |
| 107 Node* ret = end->InputAt(0); |
| 108 Node* effect = graph->start(); |
| 109 Node* control = graph->start(); |
| 110 EXPECT_THAT(ret, IsReturn(IsUndefinedConstant(), effect, control)); |
| 111 } |
| 112 |
| 113 |
| 114 TEST_F(BytecodeGraphBuilderTest, ReturnNull) { |
| 115 array_builder()->set_locals_count(0); |
| 116 array_builder()->set_parameter_count(1); |
| 117 array_builder()->LoadNull().Return(); |
| 118 |
| 119 Graph* graph = GetCompletedGraph(); |
| 120 Node* end = graph->end(); |
| 121 EXPECT_EQ(1, end->InputCount()); |
| 122 Node* ret = end->InputAt(0); |
| 123 EXPECT_THAT(ret, IsReturn(IsNullConstant(), graph->start(), graph->start())); |
| 124 } |
| 125 |
| 126 |
| 127 TEST_F(BytecodeGraphBuilderTest, ReturnTheHole) { |
| 128 array_builder()->set_locals_count(0); |
| 129 array_builder()->set_parameter_count(1); |
| 130 array_builder()->LoadTheHole().Return(); |
| 131 |
| 132 Graph* graph = GetCompletedGraph(); |
| 133 Node* end = graph->end(); |
| 134 EXPECT_EQ(1, end->InputCount()); |
| 135 Node* ret = end->InputAt(0); |
| 136 Node* effect = graph->start(); |
| 137 Node* control = graph->start(); |
| 138 EXPECT_THAT(ret, IsReturn(IsTheHoleConstant(), effect, control)); |
| 139 } |
| 140 |
| 141 |
| 142 TEST_F(BytecodeGraphBuilderTest, ReturnTrue) { |
| 143 array_builder()->set_locals_count(0); |
| 144 array_builder()->set_parameter_count(1); |
| 145 array_builder()->LoadTrue().Return(); |
| 146 |
| 147 Graph* graph = GetCompletedGraph(); |
| 148 Node* end = graph->end(); |
| 149 EXPECT_EQ(1, end->InputCount()); |
| 150 Node* ret = end->InputAt(0); |
| 151 Node* effect = graph->start(); |
| 152 Node* control = graph->start(); |
| 153 EXPECT_THAT(ret, IsReturn(IsTrueConstant(), effect, control)); |
| 154 } |
| 155 |
| 156 |
| 157 TEST_F(BytecodeGraphBuilderTest, ReturnFalse) { |
| 158 array_builder()->set_locals_count(0); |
| 159 array_builder()->set_parameter_count(1); |
| 160 array_builder()->LoadFalse().Return(); |
| 161 |
| 162 Graph* graph = GetCompletedGraph(); |
| 163 Node* end = graph->end(); |
| 164 EXPECT_EQ(1, end->InputCount()); |
| 165 Node* ret = end->InputAt(0); |
| 166 Node* effect = graph->start(); |
| 167 Node* control = graph->start(); |
| 168 EXPECT_THAT(ret, IsReturn(IsFalseConstant(), effect, control)); |
| 169 } |
| 170 |
| 171 |
| 172 TEST_F(BytecodeGraphBuilderTest, ReturnInt8) { |
| 173 static const int kValue = 3; |
| 174 array_builder()->set_locals_count(0); |
| 175 array_builder()->set_parameter_count(1); |
| 176 array_builder()->LoadLiteral(Smi::FromInt(kValue)).Return(); |
| 177 |
| 178 Graph* graph = GetCompletedGraph(); |
| 179 Node* end = graph->end(); |
| 180 EXPECT_EQ(1, end->InputCount()); |
| 181 Node* ret = end->InputAt(0); |
| 182 Node* effect = graph->start(); |
| 183 Node* control = graph->start(); |
| 184 EXPECT_THAT(ret, IsReturn(IsNumberConstant(kValue), effect, control)); |
| 185 } |
| 186 |
| 187 |
| 188 TEST_F(BytecodeGraphBuilderTest, ReturnDouble) { |
| 189 const double kValue = 0.123456789; |
| 190 array_builder()->set_locals_count(0); |
| 191 array_builder()->set_parameter_count(1); |
| 192 array_builder()->LoadLiteral(factory()->NewHeapNumber(kValue)); |
| 193 array_builder()->Return(); |
| 194 |
| 195 Graph* graph = GetCompletedGraph(); |
| 196 Node* end = graph->end(); |
| 197 EXPECT_EQ(1, end->InputCount()); |
| 198 Node* ret = end->InputAt(0); |
| 199 Node* effect = graph->start(); |
| 200 Node* control = graph->start(); |
| 201 EXPECT_THAT(ret, IsReturn(IsNumberConstant(kValue), effect, control)); |
| 202 } |
| 203 |
| 204 |
| 205 TEST_F(BytecodeGraphBuilderTest, SimpleExpressionWithParameters) { |
| 206 array_builder()->set_locals_count(1); |
| 207 array_builder()->set_parameter_count(3); |
| 208 array_builder() |
| 209 ->LoadAccumulatorWithRegister(array_builder()->Parameter(1)) |
| 210 .BinaryOperation(Token::Value::ADD, array_builder()->Parameter(2)) |
| 211 .StoreAccumulatorInRegister(interpreter::Register(0)) |
| 212 .Return(); |
| 213 |
| 214 Graph* graph = GetCompletedGraph(); |
| 215 Node* end = graph->end(); |
| 216 EXPECT_EQ(1, end->InputCount()); |
| 217 Node* ret = end->InputAt(0); |
| 218 // NB binary operation is <reg> <op> <acc>. The register represents |
| 219 // the left-hand side, which is why parameters appear in opposite |
| 220 // order to construction via the builder. |
| 221 EXPECT_THAT(ret, IsReturn(IsJSAdd(IsParameter(2), IsParameter(1)), _, _)); |
| 222 } |
| 223 |
| 224 |
| 225 TEST_F(BytecodeGraphBuilderTest, SimpleExpressionWithRegister) { |
| 226 static const int kLeft = -655371; |
| 227 static const int kRight = +2000000; |
| 228 array_builder()->set_locals_count(1); |
| 229 array_builder()->set_parameter_count(1); |
| 230 array_builder() |
| 231 ->LoadLiteral(Smi::FromInt(kLeft)) |
| 232 .StoreAccumulatorInRegister(interpreter::Register(0)) |
| 233 .LoadLiteral(Smi::FromInt(kRight)) |
| 234 .BinaryOperation(Token::Value::ADD, interpreter::Register(0)) |
| 235 .Return(); |
| 236 |
| 237 Graph* graph = GetCompletedGraph(); |
| 238 Node* end = graph->end(); |
| 239 EXPECT_EQ(1, end->InputCount()); |
| 240 Node* ret = end->InputAt(0); |
| 241 EXPECT_THAT( |
| 242 ret, IsReturn(IsJSAdd(IsNumberConstant(kLeft), IsNumberConstant(kRight)), |
| 243 _, _)); |
| 244 } |
| 245 |
| 246 } // namespace compiler |
| 247 } // namespace internal |
| 248 } // namespace v8 |
OLD | NEW |