Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(298)

Side by Side Diff: test/unittests/compiler/bytecode-graph-builder-unittest.cc

Issue 1477783003: [Interpreter] Deprecate bytecode-graph-builder-unittest. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Additional clean up. Created 5 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « no previous file | test/unittests/compiler/node-test-utils.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(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/compiler/linkage.h"
15 #include "src/interpreter/bytecode-array-builder.h"
16 #include "src/parser.h"
17 #include "test/unittests/compiler/compiler-test-utils.h"
18 #include "test/unittests/compiler/graph-unittest.h"
19 #include "test/unittests/compiler/node-test-utils.h"
20 #include "test/unittests/test-utils.h"
21
22 using ::testing::_;
23
24 namespace v8 {
25 namespace internal {
26 namespace compiler {
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
38
39 class BytecodeGraphBuilderTest : public TestWithIsolateAndZone {
40 public:
41 BytecodeGraphBuilderTest() {}
42
43 Graph* GetCompletedGraph(Handle<BytecodeArray> bytecode_array,
44 MaybeHandle<TypeFeedbackVector> feedback_vector =
45 MaybeHandle<TypeFeedbackVector>(),
46 LanguageMode language_mode = LanguageMode::SLOPPY);
47
48 Matcher<Node*> IsUndefinedConstant();
49 Matcher<Node*> IsNullConstant();
50 Matcher<Node*> IsTheHoleConstant();
51 Matcher<Node*> IsFalseConstant();
52 Matcher<Node*> IsTrueConstant();
53 Matcher<Node*> IsIntPtrConstant(int value);
54 Matcher<Node*> IsFeedbackVector(Node* effect, Node* control);
55
56 static Handle<String> GetName(Isolate* isolate, const char* name) {
57 Handle<String> result = isolate->factory()->NewStringFromAsciiChecked(name);
58 return isolate->factory()->string_table()->LookupString(isolate, result);
59 }
60
61 private:
62 DISALLOW_COPY_AND_ASSIGN(BytecodeGraphBuilderTest);
63 };
64
65
66 Graph* BytecodeGraphBuilderTest::GetCompletedGraph(
67 Handle<BytecodeArray> bytecode_array,
68 MaybeHandle<TypeFeedbackVector> feedback_vector,
69 LanguageMode language_mode) {
70 MachineOperatorBuilder* machine = new (zone()) MachineOperatorBuilder(
71 zone(), kMachPtr, InstructionSelector::SupportedMachineOperatorFlags());
72 CommonOperatorBuilder* common = new (zone()) CommonOperatorBuilder(zone());
73 JSOperatorBuilder* javascript = new (zone()) JSOperatorBuilder(zone());
74 Graph* graph = new (zone()) Graph(zone());
75 JSGraph* jsgraph = new (zone())
76 JSGraph(isolate(), graph, common, javascript, nullptr, machine);
77
78 Handle<String> name = factory()->NewStringFromStaticChars("test");
79 Handle<String> script = factory()->NewStringFromStaticChars("test() {}");
80 Handle<SharedFunctionInfo> shared_info =
81 factory()->NewSharedFunctionInfo(name, MaybeHandle<Code>(), true);
82 shared_info->set_script(*factory()->NewScript(script));
83 if (!feedback_vector.is_null()) {
84 shared_info->set_feedback_vector(*feedback_vector.ToHandleChecked());
85 }
86
87 ParseInfo parse_info(zone(), shared_info);
88 parse_info.set_language_mode(language_mode);
89 CompilationInfo info(&parse_info);
90 info.shared_info()->set_function_data(*bytecode_array);
91
92 BytecodeGraphBuilder graph_builder(zone(), &info, jsgraph);
93 graph_builder.CreateGraph();
94 return graph;
95 }
96
97
98 Matcher<Node*> BytecodeGraphBuilderTest::IsUndefinedConstant() {
99 return IsHeapConstant(factory()->undefined_value());
100 }
101
102
103 Matcher<Node*> BytecodeGraphBuilderTest::IsNullConstant() {
104 return IsHeapConstant(factory()->null_value());
105 }
106
107
108 Matcher<Node*> BytecodeGraphBuilderTest::IsTheHoleConstant() {
109 return IsHeapConstant(factory()->the_hole_value());
110 }
111
112
113 Matcher<Node*> BytecodeGraphBuilderTest::IsFalseConstant() {
114 return IsHeapConstant(factory()->false_value());
115 }
116
117
118 Matcher<Node*> BytecodeGraphBuilderTest::IsTrueConstant() {
119 return IsHeapConstant(factory()->true_value());
120 }
121
122
123 Matcher<Node*> BytecodeGraphBuilderTest::IsIntPtrConstant(int value) {
124 if (kPointerSize == 8) {
125 return IsInt64Constant(value);
126 } else {
127 return IsInt32Constant(value);
128 }
129 }
130
131
132 Matcher<Node*> BytecodeGraphBuilderTest::IsFeedbackVector(Node* effect,
133 Node* control) {
134 int offset = SharedFunctionInfo::kFeedbackVectorOffset - kHeapObjectTag;
135 int offset1 = JSFunction::kSharedFunctionInfoOffset - kHeapObjectTag;
136
137 return IsLoad(
138 kMachAnyTagged,
139 IsLoad(kMachAnyTagged, IsParameter(Linkage::kJSCallClosureParamIndex),
140 IsIntPtrConstant(offset1), effect, control),
141 IsIntPtrConstant(offset), effect, control);
142 }
143
144
145 TEST_F(BytecodeGraphBuilderTest, ReturnUndefined) {
146 interpreter::BytecodeArrayBuilder array_builder(isolate(), zone());
147 array_builder.set_locals_count(0);
148 array_builder.set_context_count(0);
149 array_builder.set_parameter_count(1);
150 array_builder.LoadUndefined().Return();
151
152 Graph* graph = GetCompletedGraph(array_builder.ToBytecodeArray());
153 Node* end = graph->end();
154 EXPECT_EQ(1, end->InputCount());
155 Node* ret = end->InputAt(0);
156 Node* effect = graph->start();
157 Node* control = graph->start();
158 EXPECT_THAT(ret, IsReturn(IsUndefinedConstant(), effect, control));
159 }
160
161
162 TEST_F(BytecodeGraphBuilderTest, ReturnNull) {
163 interpreter::BytecodeArrayBuilder array_builder(isolate(), zone());
164 array_builder.set_locals_count(0);
165 array_builder.set_context_count(0);
166 array_builder.set_parameter_count(1);
167 array_builder.LoadNull().Return();
168
169 Graph* graph = GetCompletedGraph(array_builder.ToBytecodeArray());
170 Node* end = graph->end();
171 EXPECT_EQ(1, end->InputCount());
172 Node* ret = end->InputAt(0);
173 EXPECT_THAT(ret, IsReturn(IsNullConstant(), graph->start(), graph->start()));
174 }
175
176
177 TEST_F(BytecodeGraphBuilderTest, ReturnTheHole) {
178 interpreter::BytecodeArrayBuilder array_builder(isolate(), zone());
179 array_builder.set_locals_count(0);
180 array_builder.set_context_count(0);
181 array_builder.set_parameter_count(1);
182 array_builder.LoadTheHole().Return();
183
184 Graph* graph = GetCompletedGraph(array_builder.ToBytecodeArray());
185 Node* end = graph->end();
186 EXPECT_EQ(1, end->InputCount());
187 Node* ret = end->InputAt(0);
188 Node* effect = graph->start();
189 Node* control = graph->start();
190 EXPECT_THAT(ret, IsReturn(IsTheHoleConstant(), effect, control));
191 }
192
193
194 TEST_F(BytecodeGraphBuilderTest, ReturnTrue) {
195 interpreter::BytecodeArrayBuilder array_builder(isolate(), zone());
196 array_builder.set_locals_count(0);
197 array_builder.set_context_count(0);
198 array_builder.set_parameter_count(1);
199 array_builder.LoadTrue().Return();
200
201 Graph* graph = GetCompletedGraph(array_builder.ToBytecodeArray());
202 Node* end = graph->end();
203 EXPECT_EQ(1, end->InputCount());
204 Node* ret = end->InputAt(0);
205 Node* effect = graph->start();
206 Node* control = graph->start();
207 EXPECT_THAT(ret, IsReturn(IsTrueConstant(), effect, control));
208 }
209
210
211 TEST_F(BytecodeGraphBuilderTest, ReturnFalse) {
212 interpreter::BytecodeArrayBuilder array_builder(isolate(), zone());
213 array_builder.set_locals_count(0);
214 array_builder.set_context_count(0);
215 array_builder.set_parameter_count(1);
216 array_builder.LoadFalse().Return();
217
218 Graph* graph = GetCompletedGraph(array_builder.ToBytecodeArray());
219 Node* end = graph->end();
220 EXPECT_EQ(1, end->InputCount());
221 Node* ret = end->InputAt(0);
222 Node* effect = graph->start();
223 Node* control = graph->start();
224 EXPECT_THAT(ret, IsReturn(IsFalseConstant(), effect, control));
225 }
226
227
228 TEST_F(BytecodeGraphBuilderTest, ReturnInt8) {
229 interpreter::BytecodeArrayBuilder array_builder(isolate(), zone());
230 static const int kValue = 3;
231 array_builder.set_locals_count(0);
232 array_builder.set_context_count(0);
233 array_builder.set_parameter_count(1);
234 array_builder.LoadLiteral(Smi::FromInt(kValue)).Return();
235
236 Graph* graph = GetCompletedGraph(array_builder.ToBytecodeArray());
237 Node* end = graph->end();
238 EXPECT_EQ(1, end->InputCount());
239 Node* ret = end->InputAt(0);
240 Node* effect = graph->start();
241 Node* control = graph->start();
242 EXPECT_THAT(ret, IsReturn(IsNumberConstant(kValue), effect, control));
243 }
244
245
246 TEST_F(BytecodeGraphBuilderTest, ReturnDouble) {
247 interpreter::BytecodeArrayBuilder array_builder(isolate(), zone());
248 const double kValue = 0.123456789;
249 array_builder.set_locals_count(0);
250 array_builder.set_context_count(0);
251 array_builder.set_parameter_count(1);
252 array_builder.LoadLiteral(factory()->NewHeapNumber(kValue));
253 array_builder.Return();
254
255 Graph* graph = GetCompletedGraph(array_builder.ToBytecodeArray());
256 Node* end = graph->end();
257 EXPECT_EQ(1, end->InputCount());
258 Node* ret = end->InputAt(0);
259 Node* effect = graph->start();
260 Node* control = graph->start();
261 EXPECT_THAT(ret, IsReturn(IsNumberConstant(kValue), effect, control));
262 }
263
264
265 TEST_F(BytecodeGraphBuilderTest, SimpleExpressionWithParameters) {
266 interpreter::BytecodeArrayBuilder array_builder(isolate(), zone());
267 array_builder.set_locals_count(1);
268 array_builder.set_context_count(0);
269 array_builder.set_parameter_count(3);
270 array_builder.LoadAccumulatorWithRegister(array_builder.Parameter(1))
271 .BinaryOperation(Token::Value::ADD, array_builder.Parameter(2),
272 Strength::WEAK)
273 .StoreAccumulatorInRegister(interpreter::Register(0))
274 .Return();
275
276 Graph* graph = GetCompletedGraph(array_builder.ToBytecodeArray());
277 Node* end = graph->end();
278 EXPECT_EQ(1, end->InputCount());
279 Node* ret = end->InputAt(0);
280 // NB binary operation is <reg> <op> <acc>. The register represents
281 // the left-hand side, which is why parameters appear in opposite
282 // order to construction via the builder.
283 EXPECT_THAT(ret, IsReturn(IsJSAdd(IsParameter(2), IsParameter(1)), _, _));
284 }
285
286
287 TEST_F(BytecodeGraphBuilderTest, SimpleExpressionWithRegister) {
288 interpreter::BytecodeArrayBuilder array_builder(isolate(), zone());
289 static const int kLeft = -655371;
290 static const int kRight = +2000000;
291 array_builder.set_locals_count(1);
292 array_builder.set_context_count(0);
293 array_builder.set_parameter_count(1);
294 array_builder.LoadLiteral(Smi::FromInt(kLeft))
295 .StoreAccumulatorInRegister(interpreter::Register(0))
296 .LoadLiteral(Smi::FromInt(kRight))
297 .BinaryOperation(Token::Value::ADD, interpreter::Register(0),
298 Strength::WEAK)
299 .Return();
300
301 Graph* graph = GetCompletedGraph(array_builder.ToBytecodeArray());
302 Node* end = graph->end();
303 EXPECT_EQ(1, end->InputCount());
304 Node* ret = end->InputAt(0);
305 EXPECT_THAT(
306 ret, IsReturn(IsJSAdd(IsNumberConstant(kLeft), IsNumberConstant(kRight)),
307 _, _));
308 }
309
310
311 TEST_F(BytecodeGraphBuilderTest, NamedLoad) {
312 const bool kWideBytecode[] = {false, true};
313 TRACED_FOREACH(LanguageMode, language_mode, kLanguageModes) {
314 TRACED_FOREACH(bool, wide_bytecode, kWideBytecode) {
315 FeedbackVectorSpec feedback_spec(zone());
316 if (wide_bytecode) {
317 for (int i = 0; i < 128; i++) {
318 feedback_spec.AddLoadICSlot();
319 }
320 }
321 FeedbackVectorSlot slot = feedback_spec.AddLoadICSlot();
322 Handle<TypeFeedbackVector> vector =
323 NewTypeFeedbackVector(isolate(), &feedback_spec);
324
325 interpreter::BytecodeArrayBuilder array_builder(isolate(), zone());
326 array_builder.set_locals_count(1);
327 array_builder.set_context_count(0);
328 array_builder.set_parameter_count(2);
329
330 Handle<Name> name = GetName(isolate(), "val");
331 size_t name_index = array_builder.GetConstantPoolEntry(name);
332
333 array_builder.LoadNamedProperty(array_builder.Parameter(1), name_index,
334 vector->GetIndex(slot), language_mode)
335 .Return();
336 Graph* graph = GetCompletedGraph(array_builder.ToBytecodeArray(), vector,
337 language_mode);
338
339 Node* ret = graph->end()->InputAt(0);
340 Node* start = graph->start();
341
342 Matcher<Node*> feedback_vector_matcher = IsFeedbackVector(start, start);
343 Matcher<Node*> load_named_matcher = IsJSLoadNamed(
344 name, IsParameter(1), feedback_vector_matcher, start, start);
345
346 EXPECT_THAT(ret, IsReturn(load_named_matcher, _, _));
347 }
348 }
349 }
350
351
352 TEST_F(BytecodeGraphBuilderTest, CallProperty0) {
353 FeedbackVectorSpec feedback_spec(zone());
354 FeedbackVectorSlot call_slot = feedback_spec.AddCallICSlot();
355 FeedbackVectorSlot load_slot = feedback_spec.AddLoadICSlot();
356 Handle<TypeFeedbackVector> vector =
357 NewTypeFeedbackVector(isolate(), &feedback_spec);
358
359 interpreter::BytecodeArrayBuilder array_builder(isolate(), zone());
360 array_builder.set_locals_count(1);
361 array_builder.set_context_count(0);
362 array_builder.set_parameter_count(2);
363
364 Handle<Name> func_name = GetName(isolate(), "func");
365 size_t func_name_index = array_builder.GetConstantPoolEntry(func_name);
366
367 interpreter::Register reg0 = interpreter::Register(0);
368 array_builder.LoadNamedProperty(array_builder.Parameter(1), func_name_index,
369 vector->GetIndex(load_slot),
370 LanguageMode::SLOPPY)
371 .StoreAccumulatorInRegister(reg0)
372 .Call(reg0, array_builder.Parameter(1), 0, vector->GetIndex(call_slot))
373 .Return();
374
375 Graph* graph = GetCompletedGraph(array_builder.ToBytecodeArray(), vector);
376 Node* ret = graph->end()->InputAt(0);
377 Node* start = graph->start();
378
379 Matcher<Node*> feedback_vector_matcher = IsFeedbackVector(start, start);
380 Matcher<Node*> load_named_matcher = IsJSLoadNamed(
381 func_name, IsParameter(1), feedback_vector_matcher, start, start);
382 std::vector<Matcher<Node*>> call_inputs;
383 call_inputs.push_back(load_named_matcher);
384 call_inputs.push_back(IsParameter(1));
385 Matcher<Node*> call_matcher =
386 IsJSCallFunction(call_inputs, load_named_matcher, IsIfSuccess(_));
387
388 EXPECT_THAT(ret, IsReturn(call_matcher, _, _));
389 }
390
391
392 TEST_F(BytecodeGraphBuilderTest, CallProperty2) {
393 FeedbackVectorSpec feedback_spec(zone());
394 FeedbackVectorSlot call_slot = feedback_spec.AddCallICSlot();
395 FeedbackVectorSlot load_slot = feedback_spec.AddLoadICSlot();
396 Handle<TypeFeedbackVector> vector =
397 NewTypeFeedbackVector(isolate(), &feedback_spec);
398
399 interpreter::BytecodeArrayBuilder array_builder(isolate(), zone());
400 array_builder.set_locals_count(4);
401 array_builder.set_context_count(0);
402 array_builder.set_parameter_count(4);
403
404 Handle<Name> func_name = GetName(isolate(), "func");
405 size_t func_name_index = array_builder.GetConstantPoolEntry(func_name);
406
407 interpreter::Register reg0 = interpreter::Register(0);
408 interpreter::Register reg1 = interpreter::Register(1);
409 interpreter::Register reg2 = interpreter::Register(2);
410 interpreter::Register reg3 = interpreter::Register(3);
411 array_builder.LoadNamedProperty(array_builder.Parameter(1), func_name_index,
412 vector->GetIndex(load_slot),
413 LanguageMode::SLOPPY)
414 .StoreAccumulatorInRegister(reg0)
415 .LoadAccumulatorWithRegister(array_builder.Parameter(1))
416 .StoreAccumulatorInRegister(reg1)
417 .LoadAccumulatorWithRegister(array_builder.Parameter(2))
418 .StoreAccumulatorInRegister(reg2)
419 .LoadAccumulatorWithRegister(array_builder.Parameter(3))
420 .StoreAccumulatorInRegister(reg3)
421 .Call(reg0, reg1, 2, vector->GetIndex(call_slot))
422 .Return();
423
424 Graph* graph = GetCompletedGraph(array_builder.ToBytecodeArray(), vector);
425 Node* ret = graph->end()->InputAt(0);
426 Node* start = graph->start();
427
428 Matcher<Node*> feedback_vector_matcher = IsFeedbackVector(start, start);
429 Matcher<Node*> load_named_matcher = IsJSLoadNamed(
430 func_name, IsParameter(1), feedback_vector_matcher, start, start);
431 std::vector<Matcher<Node*>> call_inputs;
432 call_inputs.push_back(load_named_matcher);
433 call_inputs.push_back(IsParameter(1));
434 call_inputs.push_back(IsParameter(2));
435 call_inputs.push_back(IsParameter(3));
436 Matcher<Node*> call_matcher =
437 IsJSCallFunction(call_inputs, load_named_matcher, IsIfSuccess(_));
438
439 EXPECT_THAT(ret, IsReturn(call_matcher, _, _));
440 }
441
442
443 TEST_F(BytecodeGraphBuilderTest, LoadGlobal) {
444 const TypeofMode kTypeOfModes[] = {TypeofMode::NOT_INSIDE_TYPEOF,
445 TypeofMode::INSIDE_TYPEOF};
446 const bool kWideBytecode[] = {false, true};
447 TRACED_FOREACH(LanguageMode, language_mode, kLanguageModes) {
448 TRACED_FOREACH(TypeofMode, typeof_mode, kTypeOfModes) {
449 TRACED_FOREACH(bool, wide_bytecode, kWideBytecode) {
450 FeedbackVectorSpec feedback_spec(zone());
451 if (wide_bytecode) {
452 for (int i = 0; i < 128; i++) {
453 feedback_spec.AddLoadICSlot();
454 }
455 }
456 FeedbackVectorSlot slot = feedback_spec.AddLoadICSlot();
457 Handle<TypeFeedbackVector> vector =
458 NewTypeFeedbackVector(isolate(), &feedback_spec);
459
460 interpreter::BytecodeArrayBuilder array_builder(isolate(), zone());
461 array_builder.set_locals_count(0);
462 array_builder.set_context_count(0);
463 array_builder.set_parameter_count(1);
464
465 Handle<Name> name = GetName(isolate(), "global");
466 size_t name_index = array_builder.GetConstantPoolEntry(name);
467
468 array_builder.LoadGlobal(name_index, vector->GetIndex(slot),
469 language_mode, typeof_mode)
470 .Return();
471 Graph* graph = GetCompletedGraph(array_builder.ToBytecodeArray(),
472 vector, language_mode);
473
474 Node* ret = graph->end()->InputAt(0);
475 Node* start = graph->start();
476
477 Matcher<Node*> feedback_vector_matcher = IsFeedbackVector(start, start);
478 Matcher<Node*> load_global_matcher = IsJSLoadGlobal(
479 name, typeof_mode, feedback_vector_matcher, start, start);
480
481 EXPECT_THAT(ret, IsReturn(load_global_matcher, _, _));
482 }
483 }
484 }
485 }
486
487
488 TEST_F(BytecodeGraphBuilderTest, StoreGlobal) {
489 const bool kWideBytecode[] = {false, true};
490 TRACED_FOREACH(LanguageMode, language_mode, kLanguageModes) {
491 TRACED_FOREACH(bool, wide_bytecode, kWideBytecode) {
492 FeedbackVectorSpec feedback_spec(zone());
493 if (wide_bytecode) {
494 for (int i = 0; i < 128; i++) {
495 feedback_spec.AddStoreICSlot();
496 }
497 }
498 FeedbackVectorSlot slot = feedback_spec.AddStoreICSlot();
499 Handle<TypeFeedbackVector> vector =
500 NewTypeFeedbackVector(isolate(), &feedback_spec);
501
502 interpreter::BytecodeArrayBuilder array_builder(isolate(), zone());
503 array_builder.set_locals_count(0);
504 array_builder.set_context_count(0);
505 array_builder.set_parameter_count(1);
506
507 Handle<Name> name = GetName(isolate(), "global");
508 size_t name_index = array_builder.GetConstantPoolEntry(name);
509
510 array_builder.LoadLiteral(Smi::FromInt(321))
511 .StoreGlobal(name_index, vector->GetIndex(slot), language_mode)
512 .Return();
513 Graph* graph = GetCompletedGraph(array_builder.ToBytecodeArray(), vector,
514 language_mode);
515
516 Node* ret = graph->end()->InputAt(0);
517 Node* start = graph->start();
518
519 Matcher<Node*> value_matcher = IsNumberConstant(321);
520 Matcher<Node*> feedback_vector_matcher = IsFeedbackVector(start, start);
521 Matcher<Node*> store_global_matcher = IsJSStoreGlobal(
522 name, value_matcher, feedback_vector_matcher, start, start);
523
524 EXPECT_THAT(ret, IsReturn(_, store_global_matcher, _));
525 }
526 }
527 }
528
529
530 TEST_F(BytecodeGraphBuilderTest, LogicalNot) {
531 interpreter::BytecodeArrayBuilder array_builder(isolate(), zone());
532 array_builder.set_locals_count(1);
533 array_builder.set_context_count(0);
534 array_builder.set_parameter_count(2);
535 array_builder.LoadAccumulatorWithRegister(array_builder.Parameter(1))
536 .LogicalNot()
537 .Return();
538
539 FeedbackVectorSpec feedback_spec(zone());
540 Handle<TypeFeedbackVector> vector =
541 NewTypeFeedbackVector(isolate(), &feedback_spec);
542 Graph* graph = GetCompletedGraph(array_builder.ToBytecodeArray(), vector);
543
544 Node* ret = graph->end()->InputAt(0);
545 EXPECT_THAT(ret, IsReturn(IsJSUnaryNot(IsParameter(1)), _, _));
546 }
547
548
549 TEST_F(BytecodeGraphBuilderTest, TypeOf) {
550 interpreter::BytecodeArrayBuilder array_builder(isolate(), zone());
551 array_builder.set_locals_count(1);
552 array_builder.set_context_count(0);
553 array_builder.set_parameter_count(2);
554 array_builder.LoadAccumulatorWithRegister(array_builder.Parameter(1))
555 .TypeOf()
556 .Return();
557
558 FeedbackVectorSpec feedback_spec(zone());
559 Handle<TypeFeedbackVector> vector =
560 NewTypeFeedbackVector(isolate(), &feedback_spec);
561 Graph* graph = GetCompletedGraph(array_builder.ToBytecodeArray(), vector);
562
563 Node* ret = graph->end()->InputAt(0);
564 EXPECT_THAT(ret, IsReturn(IsJSTypeOf(IsParameter(1)), _, _));
565 }
566
567
568 TEST_F(BytecodeGraphBuilderTest, Delete) {
569 TRACED_FOREACH(LanguageMode, language_mode, kLanguageModes) {
570 interpreter::BytecodeArrayBuilder array_builder(isolate(), zone());
571 array_builder.set_locals_count(1);
572 array_builder.set_context_count(0);
573 array_builder.set_parameter_count(2);
574 Handle<Name> name = GetName(isolate(), "val");
575 array_builder.LoadLiteral(name)
576 .Delete(array_builder.Parameter(1), language_mode)
577 .Return();
578
579 FeedbackVectorSpec feedback_spec(zone());
580 Handle<TypeFeedbackVector> vector =
581 NewTypeFeedbackVector(isolate(), &feedback_spec);
582 Graph* graph = GetCompletedGraph(array_builder.ToBytecodeArray(), vector,
583 language_mode);
584
585 Node* start = graph->start();
586 Node* ret = graph->end()->InputAt(0);
587
588 Matcher<Node*> delete_matcher =
589 IsJSDeleteProperty(IsParameter(1), IsHeapConstant(name), start, start);
590 EXPECT_THAT(ret, IsReturn(delete_matcher, _, _));
591 }
592 }
593
594
595 TEST_F(BytecodeGraphBuilderTest, KeyedLoad) {
596 const int kValue = 100;
597 const bool kWideBytecode[] = {false, true};
598 TRACED_FOREACH(LanguageMode, language_mode, kLanguageModes) {
599 TRACED_FOREACH(bool, wide_bytecode, kWideBytecode) {
600 FeedbackVectorSpec feedback_spec(zone());
601 if (wide_bytecode) {
602 for (int i = 0; i < 128; i++) {
603 feedback_spec.AddLoadICSlot();
604 }
605 }
606 FeedbackVectorSlot slot = feedback_spec.AddLoadICSlot();
607 Handle<TypeFeedbackVector> vector =
608 NewTypeFeedbackVector(isolate(), &feedback_spec);
609
610 interpreter::BytecodeArrayBuilder array_builder(isolate(), zone());
611 array_builder.set_locals_count(1);
612 array_builder.set_context_count(0);
613 array_builder.set_parameter_count(2);
614
615 array_builder.LoadLiteral(Smi::FromInt(kValue))
616 .LoadKeyedProperty(array_builder.Parameter(1), vector->GetIndex(slot),
617 language_mode)
618 .Return();
619 Graph* graph = GetCompletedGraph(array_builder.ToBytecodeArray(), vector,
620 language_mode);
621
622 Node* ret = graph->end()->InputAt(0);
623 Node* start = graph->start();
624
625 Matcher<Node*> feedback_vector_matcher = IsFeedbackVector(start, start);
626 Matcher<Node*> load_keyed_matcher =
627 IsJSLoadProperty(IsParameter(1), IsNumberConstant(kValue),
628 feedback_vector_matcher, start, start);
629
630 EXPECT_THAT(ret, IsReturn(load_keyed_matcher, _, _));
631 }
632 }
633 }
634
635
636 TEST_F(BytecodeGraphBuilderTest, NamedStore) {
637 const int kValue = 100;
638 const bool kWideBytecode[] = {false, true};
639 TRACED_FOREACH(LanguageMode, language_mode, kLanguageModes) {
640 TRACED_FOREACH(bool, wide_bytecode, kWideBytecode) {
641 FeedbackVectorSpec feedback_spec(zone());
642 if (wide_bytecode) {
643 for (int i = 0; i < 128; i++) {
644 feedback_spec.AddLoadICSlot();
645 }
646 }
647 FeedbackVectorSlot slot = feedback_spec.AddLoadICSlot();
648 Handle<TypeFeedbackVector> vector =
649 NewTypeFeedbackVector(isolate(), &feedback_spec);
650
651 interpreter::BytecodeArrayBuilder array_builder(isolate(), zone());
652 array_builder.set_locals_count(1);
653 array_builder.set_context_count(0);
654 array_builder.set_parameter_count(2);
655
656 Handle<Name> name = GetName(isolate(), "val");
657 size_t name_index = array_builder.GetConstantPoolEntry(name);
658
659 array_builder.LoadLiteral(Smi::FromInt(kValue))
660 .StoreNamedProperty(array_builder.Parameter(1), name_index,
661 vector->GetIndex(slot), language_mode)
662 .Return();
663 Graph* graph = GetCompletedGraph(array_builder.ToBytecodeArray(), vector,
664 language_mode);
665
666 Node* ret = graph->end()->InputAt(0);
667 Node* start = graph->start();
668
669 Matcher<Node*> feedback_vector_matcher = IsFeedbackVector(start, start);
670 Matcher<Node*> store_named_matcher =
671 IsJSStoreNamed(name, IsParameter(1), IsNumberConstant(kValue),
672 feedback_vector_matcher, start, start);
673
674 EXPECT_THAT(ret, IsReturn(_, store_named_matcher, _));
675 }
676 }
677 }
678
679
680 TEST_F(BytecodeGraphBuilderTest, KeyedStore) {
681 const int kValue = 100;
682 const int kKey = 10;
683 const bool kWideBytecode[] = {false, true};
684 TRACED_FOREACH(LanguageMode, language_mode, kLanguageModes) {
685 TRACED_FOREACH(bool, wide_bytecode, kWideBytecode) {
686 FeedbackVectorSpec feedback_spec(zone());
687 if (wide_bytecode) {
688 for (int i = 0; i < 128; i++) {
689 feedback_spec.AddStoreICSlot();
690 }
691 }
692 FeedbackVectorSlot slot = feedback_spec.AddStoreICSlot();
693 Handle<TypeFeedbackVector> vector =
694 NewTypeFeedbackVector(isolate(), &feedback_spec);
695
696 interpreter::BytecodeArrayBuilder array_builder(isolate(), zone());
697 array_builder.set_locals_count(1);
698 array_builder.set_context_count(0);
699 array_builder.set_parameter_count(2);
700
701 array_builder.LoadLiteral(Smi::FromInt(kKey))
702 .StoreAccumulatorInRegister(interpreter::Register(0))
703 .LoadLiteral(Smi::FromInt(kValue))
704 .StoreKeyedProperty(array_builder.Parameter(1),
705 interpreter::Register(0), vector->GetIndex(slot),
706 language_mode)
707 .Return();
708 Graph* graph = GetCompletedGraph(array_builder.ToBytecodeArray(), vector,
709 language_mode);
710
711 Node* ret = graph->end()->InputAt(0);
712 Node* start = graph->start();
713
714 Matcher<Node*> feedback_vector_matcher = IsFeedbackVector(start, start);
715 Matcher<Node*> store_keyed_matcher = IsJSStoreProperty(
716 IsParameter(1), IsNumberConstant(kKey), IsNumberConstant(kValue),
717 feedback_vector_matcher, start, start);
718
719 EXPECT_THAT(ret, IsReturn(_, store_keyed_matcher, _));
720 }
721 }
722 }
723
724
725 TEST_F(BytecodeGraphBuilderTest, CallRuntime) {
726 interpreter::BytecodeArrayBuilder array_builder(isolate(), zone());
727 array_builder.set_locals_count(2);
728 array_builder.set_context_count(0);
729 array_builder.set_parameter_count(3);
730
731 array_builder.LoadAccumulatorWithRegister(array_builder.Parameter(1))
732 .StoreAccumulatorInRegister(interpreter::Register(0))
733 .LoadAccumulatorWithRegister(array_builder.Parameter(2))
734 .StoreAccumulatorInRegister(interpreter::Register(1))
735 .CallRuntime(Runtime::kAdd, interpreter::Register(0), 2)
736 .Return();
737
738 Graph* graph = GetCompletedGraph(array_builder.ToBytecodeArray());
739 Node* start = graph->start();
740 Node* ret = graph->end()->InputAt(0);
741 std::vector<Matcher<Node*>> call_inputs;
742 call_inputs.push_back(IsParameter(1));
743 call_inputs.push_back(IsParameter(2));
744 Matcher<Node*> call_js_runtime = IsJSCallRuntime(call_inputs, start, start);
745
746 EXPECT_THAT(ret, IsReturn(call_js_runtime, call_js_runtime, IsIfSuccess(_)));
747 }
748
749
750 TEST_F(BytecodeGraphBuilderTest, CallJSRuntime) {
751 interpreter::BytecodeArrayBuilder array_builder(isolate(), zone());
752 array_builder.set_locals_count(1);
753 array_builder.set_context_count(1);
754 array_builder.set_parameter_count(2);
755
756 // function f(arg) { return %spread_arguments(arg0); }
757 interpreter::Register reg0 = interpreter::Register(0);
758 array_builder.LoadAccumulatorWithRegister(array_builder.Parameter(1))
759 .StoreAccumulatorInRegister(reg0)
760 .CallJSRuntime(Context::SPREAD_ARGUMENTS_INDEX, reg0, 1)
761 .Return();
762
763 Graph* graph = GetCompletedGraph(array_builder.ToBytecodeArray());
764 Node* ret = graph->end()->InputAt(0);
765 Matcher<Node*> load_context =
766 IsLoadContext(ContextAccess(0, Context::SPREAD_ARGUMENTS_INDEX, true), _);
767 std::vector<Matcher<Node*>> call_inputs;
768 call_inputs.push_back(load_context);
769 call_inputs.push_back(IsParameter(1));
770 Matcher<Node*> call_js_function =
771 IsJSCallFunction(call_inputs, load_context, graph->start());
772
773 EXPECT_THAT(ret,
774 IsReturn(call_js_function, call_js_function, IsIfSuccess(_)));
775 }
776
777
778 TEST_F(BytecodeGraphBuilderTest, New) {
779 interpreter::BytecodeArrayBuilder array_builder(isolate(), zone());
780 array_builder.set_locals_count(4);
781 array_builder.set_context_count(0);
782 array_builder.set_parameter_count(5);
783
784 array_builder.LoadAccumulatorWithRegister(array_builder.Parameter(1))
785 .StoreAccumulatorInRegister(interpreter::Register(0))
786 .LoadAccumulatorWithRegister(array_builder.Parameter(2))
787 .StoreAccumulatorInRegister(interpreter::Register(1))
788 .LoadAccumulatorWithRegister(array_builder.Parameter(3))
789 .StoreAccumulatorInRegister(interpreter::Register(2))
790 .LoadAccumulatorWithRegister(array_builder.Parameter(4))
791 .StoreAccumulatorInRegister(interpreter::Register(3))
792 .New(interpreter::Register(0), interpreter::Register(1), 3)
793 .Return();
794 auto bytecode_array = array_builder.ToBytecodeArray();
795 Graph* graph = GetCompletedGraph(bytecode_array);
796
797 Node* start = graph->start();
798 Node* ret = graph->end()->InputAt(0);
799 std::vector<Matcher<Node*>> construct_inputs;
800 construct_inputs.push_back(IsParameter(1));
801 construct_inputs.push_back(IsParameter(2));
802 construct_inputs.push_back(IsParameter(3));
803 construct_inputs.push_back(IsParameter(4));
804 construct_inputs.push_back(IsParameter(1));
805 Matcher<Node*> call_construct =
806 IsJSCallConstruct(construct_inputs, start, start);
807 EXPECT_THAT(ret, IsReturn(call_construct, call_construct, IsIfSuccess(_)));
808 }
809
810 } // namespace compiler
811 } // namespace internal
812 } // namespace v8
OLDNEW
« no previous file with comments | « no previous file | test/unittests/compiler/node-test-utils.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698