OLD | NEW |
1 // Copyright 2015 the V8 project authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include <iostream> | 5 #include <iostream> |
6 | 6 |
7 #include "src/compiler/bytecode-graph-builder.h" | 7 #include "src/compiler/bytecode-graph-builder.h" |
8 #include "src/compiler/common-operator.h" | 8 #include "src/compiler/common-operator.h" |
9 #include "src/compiler/graph-visualizer.h" | 9 #include "src/compiler/graph-visualizer.h" |
10 #include "src/compiler/instruction.h" | 10 #include "src/compiler/instruction.h" |
11 #include "src/compiler/instruction-selector.h" | 11 #include "src/compiler/instruction-selector.h" |
12 #include "src/compiler/js-graph.h" | 12 #include "src/compiler/js-graph.h" |
13 #include "src/compiler/js-operator.h" | 13 #include "src/compiler/js-operator.h" |
| 14 #include "src/compiler/linkage.h" |
14 #include "src/interpreter/bytecode-array-builder.h" | 15 #include "src/interpreter/bytecode-array-builder.h" |
15 #include "src/parser.h" | 16 #include "src/parser.h" |
16 #include "test/unittests/compiler/compiler-test-utils.h" | 17 #include "test/unittests/compiler/compiler-test-utils.h" |
17 #include "test/unittests/compiler/graph-unittest.h" | 18 #include "test/unittests/compiler/graph-unittest.h" |
18 #include "test/unittests/compiler/node-test-utils.h" | 19 #include "test/unittests/compiler/node-test-utils.h" |
19 #include "test/unittests/test-utils.h" | 20 #include "test/unittests/test-utils.h" |
20 | 21 |
21 using ::testing::_; | 22 using ::testing::_; |
22 | 23 |
23 namespace v8 { | 24 namespace v8 { |
24 namespace internal { | 25 namespace internal { |
25 namespace compiler { | 26 namespace compiler { |
26 | 27 |
| 28 static const LanguageMode kLanguageModes[] = {LanguageMode::SLOPPY, |
| 29 LanguageMode::STRICT}; |
| 30 |
| 31 Handle<TypeFeedbackVector> NewTypeFeedbackVector(Isolate* isolate, |
| 32 FeedbackVectorSpec* spec) { |
| 33 Handle<TypeFeedbackMetadata> vector_metadata = |
| 34 TypeFeedbackMetadata::New(isolate, spec); |
| 35 return TypeFeedbackVector::New(isolate, vector_metadata); |
| 36 } |
| 37 |
27 class BytecodeGraphBuilderTest : public TestWithIsolateAndZone { | 38 class BytecodeGraphBuilderTest : public TestWithIsolateAndZone { |
28 public: | 39 public: |
29 BytecodeGraphBuilderTest() : array_builder_(isolate(), zone()) {} | 40 BytecodeGraphBuilderTest() {} |
30 | 41 |
31 Graph* GetCompletedGraph(); | 42 Graph* GetCompletedGraph(Handle<BytecodeArray> bytecode_array, |
| 43 MaybeHandle<TypeFeedbackVector> feedback_vector = |
| 44 MaybeHandle<TypeFeedbackVector>(), |
| 45 LanguageMode language_mode = LanguageMode::SLOPPY); |
32 | 46 |
33 Matcher<Node*> IsUndefinedConstant(); | 47 Matcher<Node*> IsUndefinedConstant(); |
34 Matcher<Node*> IsNullConstant(); | 48 Matcher<Node*> IsNullConstant(); |
35 Matcher<Node*> IsTheHoleConstant(); | 49 Matcher<Node*> IsTheHoleConstant(); |
36 Matcher<Node*> IsFalseConstant(); | 50 Matcher<Node*> IsFalseConstant(); |
37 Matcher<Node*> IsTrueConstant(); | 51 Matcher<Node*> IsTrueConstant(); |
| 52 Matcher<Node*> IsIntPtrConstant(int value); |
| 53 Matcher<Node*> IsFeedbackVector(Node* effect, Node* control); |
38 | 54 |
39 interpreter::BytecodeArrayBuilder* array_builder() { return &array_builder_; } | 55 static Handle<String> GetName(Isolate* isolate, const char* name) { |
| 56 Handle<String> result = isolate->factory()->NewStringFromAsciiChecked(name); |
| 57 return isolate->factory()->string_table()->LookupString(isolate, result); |
| 58 } |
40 | 59 |
41 private: | 60 private: |
42 interpreter::BytecodeArrayBuilder array_builder_; | |
43 | |
44 DISALLOW_COPY_AND_ASSIGN(BytecodeGraphBuilderTest); | 61 DISALLOW_COPY_AND_ASSIGN(BytecodeGraphBuilderTest); |
45 }; | 62 }; |
46 | 63 |
47 | 64 |
48 Graph* BytecodeGraphBuilderTest::GetCompletedGraph() { | 65 Graph* BytecodeGraphBuilderTest::GetCompletedGraph( |
| 66 Handle<BytecodeArray> bytecode_array, |
| 67 MaybeHandle<TypeFeedbackVector> feedback_vector, |
| 68 LanguageMode language_mode) { |
49 MachineOperatorBuilder* machine = new (zone()) MachineOperatorBuilder( | 69 MachineOperatorBuilder* machine = new (zone()) MachineOperatorBuilder( |
50 zone(), kMachPtr, InstructionSelector::SupportedMachineOperatorFlags()); | 70 zone(), kMachPtr, InstructionSelector::SupportedMachineOperatorFlags()); |
51 CommonOperatorBuilder* common = new (zone()) CommonOperatorBuilder(zone()); | 71 CommonOperatorBuilder* common = new (zone()) CommonOperatorBuilder(zone()); |
52 JSOperatorBuilder* javascript = new (zone()) JSOperatorBuilder(zone()); | 72 JSOperatorBuilder* javascript = new (zone()) JSOperatorBuilder(zone()); |
53 Graph* graph = new (zone()) Graph(zone()); | 73 Graph* graph = new (zone()) Graph(zone()); |
54 JSGraph* jsgraph = new (zone()) | 74 JSGraph* jsgraph = new (zone()) |
55 JSGraph(isolate(), graph, common, javascript, nullptr, machine); | 75 JSGraph(isolate(), graph, common, javascript, nullptr, machine); |
56 | 76 |
57 Handle<String> name = factory()->NewStringFromStaticChars("test"); | 77 Handle<String> name = factory()->NewStringFromStaticChars("test"); |
58 Handle<String> script = factory()->NewStringFromStaticChars("test() {}"); | 78 Handle<String> script = factory()->NewStringFromStaticChars("test() {}"); |
59 Handle<SharedFunctionInfo> shared_info = | 79 Handle<SharedFunctionInfo> shared_info = |
60 factory()->NewSharedFunctionInfo(name, MaybeHandle<Code>()); | 80 factory()->NewSharedFunctionInfo(name, MaybeHandle<Code>()); |
61 shared_info->set_script(*factory()->NewScript(script)); | 81 shared_info->set_script(*factory()->NewScript(script)); |
| 82 if (!feedback_vector.is_null()) { |
| 83 shared_info->set_feedback_vector(*feedback_vector.ToHandleChecked()); |
| 84 } |
62 | 85 |
63 ParseInfo parse_info(zone(), shared_info); | 86 ParseInfo parse_info(zone(), shared_info); |
| 87 parse_info.set_language_mode(language_mode); |
64 CompilationInfo info(&parse_info); | 88 CompilationInfo info(&parse_info); |
65 Handle<BytecodeArray> bytecode_array = array_builder()->ToBytecodeArray(); | |
66 info.shared_info()->set_function_data(*bytecode_array); | 89 info.shared_info()->set_function_data(*bytecode_array); |
67 | 90 |
68 BytecodeGraphBuilder graph_builder(zone(), &info, jsgraph); | 91 BytecodeGraphBuilder graph_builder(zone(), &info, jsgraph); |
69 graph_builder.CreateGraph(); | 92 graph_builder.CreateGraph(); |
70 return graph; | 93 return graph; |
71 } | 94 } |
72 | 95 |
73 | 96 |
74 Matcher<Node*> BytecodeGraphBuilderTest::IsUndefinedConstant() { | 97 Matcher<Node*> BytecodeGraphBuilderTest::IsUndefinedConstant() { |
75 return IsHeapConstant(factory()->undefined_value()); | 98 return IsHeapConstant(factory()->undefined_value()); |
(...skipping 13 matching lines...) Expand all Loading... |
89 Matcher<Node*> BytecodeGraphBuilderTest::IsFalseConstant() { | 112 Matcher<Node*> BytecodeGraphBuilderTest::IsFalseConstant() { |
90 return IsHeapConstant(factory()->false_value()); | 113 return IsHeapConstant(factory()->false_value()); |
91 } | 114 } |
92 | 115 |
93 | 116 |
94 Matcher<Node*> BytecodeGraphBuilderTest::IsTrueConstant() { | 117 Matcher<Node*> BytecodeGraphBuilderTest::IsTrueConstant() { |
95 return IsHeapConstant(factory()->true_value()); | 118 return IsHeapConstant(factory()->true_value()); |
96 } | 119 } |
97 | 120 |
98 | 121 |
| 122 Matcher<Node*> BytecodeGraphBuilderTest::IsIntPtrConstant(int value) { |
| 123 if (kPointerSize == 8) { |
| 124 return IsInt64Constant(value); |
| 125 } else { |
| 126 return IsInt32Constant(value); |
| 127 } |
| 128 } |
| 129 |
| 130 |
| 131 Matcher<Node*> BytecodeGraphBuilderTest::IsFeedbackVector(Node* effect, |
| 132 Node* control) { |
| 133 int offset = SharedFunctionInfo::kFeedbackVectorOffset - kHeapObjectTag; |
| 134 int offset1 = JSFunction::kSharedFunctionInfoOffset - kHeapObjectTag; |
| 135 |
| 136 return IsLoad(kMachAnyTagged, |
| 137 IsLoad(kMachAnyTagged, |
| 138 IsParameter(Linkage::kJSFunctionCallClosureParamIndex), |
| 139 IsIntPtrConstant(offset1), effect, control), |
| 140 IsIntPtrConstant(offset), effect, control); |
| 141 } |
| 142 |
| 143 |
99 TEST_F(BytecodeGraphBuilderTest, ReturnUndefined) { | 144 TEST_F(BytecodeGraphBuilderTest, ReturnUndefined) { |
100 array_builder()->set_locals_count(0); | 145 interpreter::BytecodeArrayBuilder array_builder(isolate(), zone()); |
101 array_builder()->set_context_count(0); | 146 array_builder.set_locals_count(0); |
102 array_builder()->set_parameter_count(1); | 147 array_builder.set_context_count(0); |
103 array_builder()->LoadUndefined().Return(); | 148 array_builder.set_parameter_count(1); |
| 149 array_builder.LoadUndefined().Return(); |
104 | 150 |
105 Graph* graph = GetCompletedGraph(); | 151 Graph* graph = GetCompletedGraph(array_builder.ToBytecodeArray()); |
106 Node* end = graph->end(); | 152 Node* end = graph->end(); |
107 EXPECT_EQ(1, end->InputCount()); | 153 EXPECT_EQ(1, end->InputCount()); |
108 Node* ret = end->InputAt(0); | 154 Node* ret = end->InputAt(0); |
109 Node* effect = graph->start(); | 155 Node* effect = graph->start(); |
110 Node* control = graph->start(); | 156 Node* control = graph->start(); |
111 EXPECT_THAT(ret, IsReturn(IsUndefinedConstant(), effect, control)); | 157 EXPECT_THAT(ret, IsReturn(IsUndefinedConstant(), effect, control)); |
112 } | 158 } |
113 | 159 |
114 | 160 |
115 TEST_F(BytecodeGraphBuilderTest, ReturnNull) { | 161 TEST_F(BytecodeGraphBuilderTest, ReturnNull) { |
116 array_builder()->set_locals_count(0); | 162 interpreter::BytecodeArrayBuilder array_builder(isolate(), zone()); |
117 array_builder()->set_context_count(0); | 163 array_builder.set_locals_count(0); |
118 array_builder()->set_parameter_count(1); | 164 array_builder.set_context_count(0); |
119 array_builder()->LoadNull().Return(); | 165 array_builder.set_parameter_count(1); |
| 166 array_builder.LoadNull().Return(); |
120 | 167 |
121 Graph* graph = GetCompletedGraph(); | 168 Graph* graph = GetCompletedGraph(array_builder.ToBytecodeArray()); |
122 Node* end = graph->end(); | 169 Node* end = graph->end(); |
123 EXPECT_EQ(1, end->InputCount()); | 170 EXPECT_EQ(1, end->InputCount()); |
124 Node* ret = end->InputAt(0); | 171 Node* ret = end->InputAt(0); |
125 EXPECT_THAT(ret, IsReturn(IsNullConstant(), graph->start(), graph->start())); | 172 EXPECT_THAT(ret, IsReturn(IsNullConstant(), graph->start(), graph->start())); |
126 } | 173 } |
127 | 174 |
128 | 175 |
129 TEST_F(BytecodeGraphBuilderTest, ReturnTheHole) { | 176 TEST_F(BytecodeGraphBuilderTest, ReturnTheHole) { |
130 array_builder()->set_locals_count(0); | 177 interpreter::BytecodeArrayBuilder array_builder(isolate(), zone()); |
131 array_builder()->set_context_count(0); | 178 array_builder.set_locals_count(0); |
132 array_builder()->set_parameter_count(1); | 179 array_builder.set_context_count(0); |
133 array_builder()->LoadTheHole().Return(); | 180 array_builder.set_parameter_count(1); |
| 181 array_builder.LoadTheHole().Return(); |
134 | 182 |
135 Graph* graph = GetCompletedGraph(); | 183 Graph* graph = GetCompletedGraph(array_builder.ToBytecodeArray()); |
136 Node* end = graph->end(); | 184 Node* end = graph->end(); |
137 EXPECT_EQ(1, end->InputCount()); | 185 EXPECT_EQ(1, end->InputCount()); |
138 Node* ret = end->InputAt(0); | 186 Node* ret = end->InputAt(0); |
139 Node* effect = graph->start(); | 187 Node* effect = graph->start(); |
140 Node* control = graph->start(); | 188 Node* control = graph->start(); |
141 EXPECT_THAT(ret, IsReturn(IsTheHoleConstant(), effect, control)); | 189 EXPECT_THAT(ret, IsReturn(IsTheHoleConstant(), effect, control)); |
142 } | 190 } |
143 | 191 |
144 | 192 |
145 TEST_F(BytecodeGraphBuilderTest, ReturnTrue) { | 193 TEST_F(BytecodeGraphBuilderTest, ReturnTrue) { |
146 array_builder()->set_locals_count(0); | 194 interpreter::BytecodeArrayBuilder array_builder(isolate(), zone()); |
147 array_builder()->set_context_count(0); | 195 array_builder.set_locals_count(0); |
148 array_builder()->set_parameter_count(1); | 196 array_builder.set_context_count(0); |
149 array_builder()->LoadTrue().Return(); | 197 array_builder.set_parameter_count(1); |
| 198 array_builder.LoadTrue().Return(); |
150 | 199 |
151 Graph* graph = GetCompletedGraph(); | 200 Graph* graph = GetCompletedGraph(array_builder.ToBytecodeArray()); |
152 Node* end = graph->end(); | 201 Node* end = graph->end(); |
153 EXPECT_EQ(1, end->InputCount()); | 202 EXPECT_EQ(1, end->InputCount()); |
154 Node* ret = end->InputAt(0); | 203 Node* ret = end->InputAt(0); |
155 Node* effect = graph->start(); | 204 Node* effect = graph->start(); |
156 Node* control = graph->start(); | 205 Node* control = graph->start(); |
157 EXPECT_THAT(ret, IsReturn(IsTrueConstant(), effect, control)); | 206 EXPECT_THAT(ret, IsReturn(IsTrueConstant(), effect, control)); |
158 } | 207 } |
159 | 208 |
160 | 209 |
161 TEST_F(BytecodeGraphBuilderTest, ReturnFalse) { | 210 TEST_F(BytecodeGraphBuilderTest, ReturnFalse) { |
162 array_builder()->set_locals_count(0); | 211 interpreter::BytecodeArrayBuilder array_builder(isolate(), zone()); |
163 array_builder()->set_context_count(0); | 212 array_builder.set_locals_count(0); |
164 array_builder()->set_parameter_count(1); | 213 array_builder.set_context_count(0); |
165 array_builder()->LoadFalse().Return(); | 214 array_builder.set_parameter_count(1); |
| 215 array_builder.LoadFalse().Return(); |
166 | 216 |
167 Graph* graph = GetCompletedGraph(); | 217 Graph* graph = GetCompletedGraph(array_builder.ToBytecodeArray()); |
168 Node* end = graph->end(); | 218 Node* end = graph->end(); |
169 EXPECT_EQ(1, end->InputCount()); | 219 EXPECT_EQ(1, end->InputCount()); |
170 Node* ret = end->InputAt(0); | 220 Node* ret = end->InputAt(0); |
171 Node* effect = graph->start(); | 221 Node* effect = graph->start(); |
172 Node* control = graph->start(); | 222 Node* control = graph->start(); |
173 EXPECT_THAT(ret, IsReturn(IsFalseConstant(), effect, control)); | 223 EXPECT_THAT(ret, IsReturn(IsFalseConstant(), effect, control)); |
174 } | 224 } |
175 | 225 |
176 | 226 |
177 TEST_F(BytecodeGraphBuilderTest, ReturnInt8) { | 227 TEST_F(BytecodeGraphBuilderTest, ReturnInt8) { |
| 228 interpreter::BytecodeArrayBuilder array_builder(isolate(), zone()); |
178 static const int kValue = 3; | 229 static const int kValue = 3; |
179 array_builder()->set_locals_count(0); | 230 array_builder.set_locals_count(0); |
180 array_builder()->set_context_count(0); | 231 array_builder.set_context_count(0); |
181 array_builder()->set_parameter_count(1); | 232 array_builder.set_parameter_count(1); |
182 array_builder()->LoadLiteral(Smi::FromInt(kValue)).Return(); | 233 array_builder.LoadLiteral(Smi::FromInt(kValue)).Return(); |
183 | 234 |
184 Graph* graph = GetCompletedGraph(); | 235 Graph* graph = GetCompletedGraph(array_builder.ToBytecodeArray()); |
185 Node* end = graph->end(); | 236 Node* end = graph->end(); |
186 EXPECT_EQ(1, end->InputCount()); | 237 EXPECT_EQ(1, end->InputCount()); |
187 Node* ret = end->InputAt(0); | 238 Node* ret = end->InputAt(0); |
188 Node* effect = graph->start(); | 239 Node* effect = graph->start(); |
189 Node* control = graph->start(); | 240 Node* control = graph->start(); |
190 EXPECT_THAT(ret, IsReturn(IsNumberConstant(kValue), effect, control)); | 241 EXPECT_THAT(ret, IsReturn(IsNumberConstant(kValue), effect, control)); |
191 } | 242 } |
192 | 243 |
193 | 244 |
194 TEST_F(BytecodeGraphBuilderTest, ReturnDouble) { | 245 TEST_F(BytecodeGraphBuilderTest, ReturnDouble) { |
| 246 interpreter::BytecodeArrayBuilder array_builder(isolate(), zone()); |
195 const double kValue = 0.123456789; | 247 const double kValue = 0.123456789; |
196 array_builder()->set_locals_count(0); | 248 array_builder.set_locals_count(0); |
197 array_builder()->set_context_count(0); | 249 array_builder.set_context_count(0); |
198 array_builder()->set_parameter_count(1); | 250 array_builder.set_parameter_count(1); |
199 array_builder()->LoadLiteral(factory()->NewHeapNumber(kValue)); | 251 array_builder.LoadLiteral(factory()->NewHeapNumber(kValue)); |
200 array_builder()->Return(); | 252 array_builder.Return(); |
201 | 253 |
202 Graph* graph = GetCompletedGraph(); | 254 Graph* graph = GetCompletedGraph(array_builder.ToBytecodeArray()); |
203 Node* end = graph->end(); | 255 Node* end = graph->end(); |
204 EXPECT_EQ(1, end->InputCount()); | 256 EXPECT_EQ(1, end->InputCount()); |
205 Node* ret = end->InputAt(0); | 257 Node* ret = end->InputAt(0); |
206 Node* effect = graph->start(); | 258 Node* effect = graph->start(); |
207 Node* control = graph->start(); | 259 Node* control = graph->start(); |
208 EXPECT_THAT(ret, IsReturn(IsNumberConstant(kValue), effect, control)); | 260 EXPECT_THAT(ret, IsReturn(IsNumberConstant(kValue), effect, control)); |
209 } | 261 } |
210 | 262 |
211 | 263 |
212 TEST_F(BytecodeGraphBuilderTest, SimpleExpressionWithParameters) { | 264 TEST_F(BytecodeGraphBuilderTest, SimpleExpressionWithParameters) { |
213 array_builder()->set_locals_count(1); | 265 interpreter::BytecodeArrayBuilder array_builder(isolate(), zone()); |
214 array_builder()->set_context_count(0); | 266 array_builder.set_locals_count(1); |
215 array_builder()->set_parameter_count(3); | 267 array_builder.set_context_count(0); |
216 array_builder() | 268 array_builder.set_parameter_count(3); |
217 ->LoadAccumulatorWithRegister(array_builder()->Parameter(1)) | 269 array_builder.LoadAccumulatorWithRegister(array_builder.Parameter(1)) |
218 .BinaryOperation(Token::Value::ADD, array_builder()->Parameter(2), | 270 .BinaryOperation(Token::Value::ADD, array_builder.Parameter(2), |
219 Strength::WEAK) | 271 Strength::WEAK) |
220 .StoreAccumulatorInRegister(interpreter::Register(0)) | 272 .StoreAccumulatorInRegister(interpreter::Register(0)) |
221 .Return(); | 273 .Return(); |
222 | 274 |
223 Graph* graph = GetCompletedGraph(); | 275 Graph* graph = GetCompletedGraph(array_builder.ToBytecodeArray()); |
224 Node* end = graph->end(); | 276 Node* end = graph->end(); |
225 EXPECT_EQ(1, end->InputCount()); | 277 EXPECT_EQ(1, end->InputCount()); |
226 Node* ret = end->InputAt(0); | 278 Node* ret = end->InputAt(0); |
227 // NB binary operation is <reg> <op> <acc>. The register represents | 279 // NB binary operation is <reg> <op> <acc>. The register represents |
228 // the left-hand side, which is why parameters appear in opposite | 280 // the left-hand side, which is why parameters appear in opposite |
229 // order to construction via the builder. | 281 // order to construction via the builder. |
230 EXPECT_THAT(ret, IsReturn(IsJSAdd(IsParameter(2), IsParameter(1)), _, _)); | 282 EXPECT_THAT(ret, IsReturn(IsJSAdd(IsParameter(2), IsParameter(1)), _, _)); |
231 } | 283 } |
232 | 284 |
233 | 285 |
234 TEST_F(BytecodeGraphBuilderTest, SimpleExpressionWithRegister) { | 286 TEST_F(BytecodeGraphBuilderTest, SimpleExpressionWithRegister) { |
| 287 interpreter::BytecodeArrayBuilder array_builder(isolate(), zone()); |
235 static const int kLeft = -655371; | 288 static const int kLeft = -655371; |
236 static const int kRight = +2000000; | 289 static const int kRight = +2000000; |
237 array_builder()->set_locals_count(1); | 290 array_builder.set_locals_count(1); |
238 array_builder()->set_context_count(0); | 291 array_builder.set_context_count(0); |
239 array_builder()->set_parameter_count(1); | 292 array_builder.set_parameter_count(1); |
240 array_builder() | 293 array_builder.LoadLiteral(Smi::FromInt(kLeft)) |
241 ->LoadLiteral(Smi::FromInt(kLeft)) | |
242 .StoreAccumulatorInRegister(interpreter::Register(0)) | 294 .StoreAccumulatorInRegister(interpreter::Register(0)) |
243 .LoadLiteral(Smi::FromInt(kRight)) | 295 .LoadLiteral(Smi::FromInt(kRight)) |
244 .BinaryOperation(Token::Value::ADD, interpreter::Register(0), | 296 .BinaryOperation(Token::Value::ADD, interpreter::Register(0), |
245 Strength::WEAK) | 297 Strength::WEAK) |
246 .Return(); | 298 .Return(); |
247 | 299 |
248 Graph* graph = GetCompletedGraph(); | 300 Graph* graph = GetCompletedGraph(array_builder.ToBytecodeArray()); |
249 Node* end = graph->end(); | 301 Node* end = graph->end(); |
250 EXPECT_EQ(1, end->InputCount()); | 302 EXPECT_EQ(1, end->InputCount()); |
251 Node* ret = end->InputAt(0); | 303 Node* ret = end->InputAt(0); |
252 EXPECT_THAT( | 304 EXPECT_THAT( |
253 ret, IsReturn(IsJSAdd(IsNumberConstant(kLeft), IsNumberConstant(kRight)), | 305 ret, IsReturn(IsJSAdd(IsNumberConstant(kLeft), IsNumberConstant(kRight)), |
254 _, _)); | 306 _, _)); |
255 } | 307 } |
256 | 308 |
| 309 |
| 310 TEST_F(BytecodeGraphBuilderTest, NamedLoad) { |
| 311 const bool kWideBytecode[] = {false, true}; |
| 312 TRACED_FOREACH(LanguageMode, language_mode, kLanguageModes) { |
| 313 TRACED_FOREACH(bool, wide_bytecode, kWideBytecode) { |
| 314 FeedbackVectorSpec feedback_spec(zone()); |
| 315 if (wide_bytecode) { |
| 316 for (int i = 0; i < 128; i++) { |
| 317 feedback_spec.AddLoadICSlot(); |
| 318 } |
| 319 } |
| 320 FeedbackVectorSlot slot = feedback_spec.AddLoadICSlot(); |
| 321 Handle<TypeFeedbackVector> vector = |
| 322 NewTypeFeedbackVector(isolate(), &feedback_spec); |
| 323 |
| 324 interpreter::BytecodeArrayBuilder array_builder(isolate(), zone()); |
| 325 array_builder.set_locals_count(1); |
| 326 array_builder.set_context_count(0); |
| 327 array_builder.set_parameter_count(2); |
| 328 |
| 329 Handle<Name> name = GetName(isolate(), "val"); |
| 330 size_t name_index = array_builder.GetConstantPoolEntry(name); |
| 331 |
| 332 array_builder.LoadNamedProperty(array_builder.Parameter(1), name_index, |
| 333 vector->GetIndex(slot), language_mode) |
| 334 .Return(); |
| 335 Graph* graph = GetCompletedGraph(array_builder.ToBytecodeArray(), vector, |
| 336 language_mode); |
| 337 |
| 338 Node* ret = graph->end()->InputAt(0); |
| 339 Node* start = graph->start(); |
| 340 |
| 341 Matcher<Node*> feedback_vector_matcher = IsFeedbackVector(start, start); |
| 342 Matcher<Node*> load_named_matcher = IsJSLoadNamed( |
| 343 name, IsParameter(1), feedback_vector_matcher, start, start); |
| 344 |
| 345 EXPECT_THAT(ret, IsReturn(load_named_matcher, _, _)); |
| 346 } |
| 347 } |
| 348 } |
| 349 |
257 } // namespace compiler | 350 } // namespace compiler |
258 } // namespace internal | 351 } // namespace internal |
259 } // namespace v8 | 352 } // namespace v8 |
OLD | NEW |