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

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

Issue 1419373007: [Interpreter] Adds implementation of bytecode graph builder for LoadICSloppy/Strict (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: removed extra spaces from code snippets in test-run-bytecode-graph-builder Created 5 years, 1 month 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
OLDNEW
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"
16 #include "src/interpreter/interpreter.h"
15 #include "src/parser.h" 17 #include "src/parser.h"
16 #include "test/unittests/compiler/compiler-test-utils.h" 18 #include "test/unittests/compiler/compiler-test-utils.h"
17 #include "test/unittests/compiler/graph-unittest.h" 19 #include "test/unittests/compiler/graph-unittest.h"
18 #include "test/unittests/compiler/node-test-utils.h" 20 #include "test/unittests/compiler/node-test-utils.h"
19 #include "test/unittests/test-utils.h" 21 #include "test/unittests/test-utils.h"
20 22
21 using ::testing::_; 23 using ::testing::_;
22 24
23 namespace v8 { 25 namespace v8 {
24 namespace internal { 26 namespace internal {
25 namespace compiler { 27 namespace compiler {
26 28
29 #define SPACE()
30
31 #define REPEAT_2(SEP, ...) __VA_ARGS__ SEP() __VA_ARGS__
32 #define REPEAT_4(SEP, ...) \
33 REPEAT_2(SEP, __VA_ARGS__) SEP() REPEAT_2(SEP, __VA_ARGS__)
34 #define REPEAT_8(SEP, ...) \
35 REPEAT_4(SEP, __VA_ARGS__) SEP() REPEAT_4(SEP, __VA_ARGS__)
36 #define REPEAT_16(SEP, ...) \
37 REPEAT_8(SEP, __VA_ARGS__) SEP() REPEAT_8(SEP, __VA_ARGS__)
38 #define REPEAT_32(SEP, ...) \
39 REPEAT_16(SEP, __VA_ARGS__) SEP() REPEAT_16(SEP, __VA_ARGS__)
40 #define REPEAT_64(SEP, ...) \
41 REPEAT_32(SEP, __VA_ARGS__) SEP() REPEAT_32(SEP, __VA_ARGS__)
42 #define REPEAT_128(SEP, ...) \
43 REPEAT_64(SEP, __VA_ARGS__) SEP() REPEAT_64(SEP, __VA_ARGS__)
44 #define REPEAT_256(SEP, ...) \
45 REPEAT_128(SEP, __VA_ARGS__) SEP() REPEAT_128(SEP, __VA_ARGS__)
46
47 #define REPEAT_127(SEP, ...) \
48 REPEAT_64(SEP, __VA_ARGS__) \
49 SEP() \
50 REPEAT_32(SEP, __VA_ARGS__) \
51 SEP() \
52 REPEAT_16(SEP, __VA_ARGS__) \
53 SEP() \
54 REPEAT_8(SEP, __VA_ARGS__) \
55 SEP() \
56 REPEAT_4(SEP, __VA_ARGS__) SEP() REPEAT_2(SEP, __VA_ARGS__) SEP() __VA_ARGS__
57
58
59 class GraphGeneratorHelper {
rmcilroy 2015/11/10 11:23:19 As discussed offline, pull the BytecodeArray code
mythria 2015/11/10 17:02:51 Done.
60 public:
61 const char* kFunctionName = "f";
62
63 GraphGeneratorHelper(Isolate* isolate, Zone* zone)
64 : isolate_(isolate), zone_(zone) {
65 i::FLAG_ignition = true;
66 i::FLAG_always_opt = false;
67 i::FLAG_vector_stores = true;
68 // Set ignition filter flag via SetFlagsFromString to avoid double-free
69 // (or potential leak with StrDup() based on ownership confusion).
70 ScopedVector<char> ignition_filter(64);
71 SNPrintF(ignition_filter, "--ignition-filter=%s", kFunctionName);
72 FlagList::SetFlagsFromString(ignition_filter.start(),
73 ignition_filter.length());
74 // Ensure handler table is generated.
75 isolate_->interpreter()->Initialize();
76 v8::Context::New(v8::Isolate::GetCurrent())->Enter();
rmcilroy 2015/11/10 11:23:19 nit - move this down to MakeGraph I think (you als
mythria 2015/11/10 17:02:51 Done.
77 }
78
79 Graph* MakeGraph(const char* script, const char* function_name) {
rmcilroy 2015/11/10 11:23:19 nit - private
mythria 2015/11/10 17:02:51 I removed this function after merging graph genera
80 v8::Local<v8::Context> context =
81 v8::Isolate::GetCurrent()->GetCurrentContext();
82 v8::Local<v8::String> v8_function_name =
83 v8::String::NewFromUtf8(v8::Isolate::GetCurrent(), function_name,
84 v8::NewStringType::kNormal)
85 .ToLocalChecked();
86
87 CompileRun(script);
88
89 Local<Function> api_function = Local<Function>::Cast(
90 context->Global()->Get(context, v8_function_name).ToLocalChecked());
91 Handle<JSFunction> function =
92 Handle<JSFunction>::cast(v8::Utils::OpenHandle(*api_function));
93 CHECK(function->shared()->HasBytecodeArray());
94
95 ParseInfo parse_info(zone_, function);
96 CompilationInfo compilation_info(&parse_info);
97
98 MachineOperatorBuilder* machine = new (zone_) MachineOperatorBuilder(
99 zone_, kMachPtr, InstructionSelector::SupportedMachineOperatorFlags());
100 CommonOperatorBuilder* common = new (zone_) CommonOperatorBuilder(zone_);
101 JSOperatorBuilder* javascript = new (zone_) JSOperatorBuilder(zone_);
102 Graph* graph = new (zone_) Graph(zone_);
103 JSGraph* jsgraph = new (zone_)
104 JSGraph(isolate_, graph, common, javascript, nullptr, machine);
105
106 BytecodeGraphBuilder graph_builder(zone_, &compilation_info, jsgraph);
107 graph_builder.CreateGraph();
108 return graph;
109 }
110
111 Graph* MakeGraphForFunctionBody(const char* body) {
112 ScopedVector<char> program(3072);
113 SNPrintF(program, "function %s() { %s }\n%s();", kFunctionName, body,
114 kFunctionName);
115 return MakeGraph(program.start(), kFunctionName);
116 }
117
118 Graph* MakeGraphForFunction(const char* function) {
119 ScopedVector<char> program(3072);
120 SNPrintF(program, "%s\n%s();", function, kFunctionName);
121 return MakeGraph(program.start(), kFunctionName);
122 }
123
124 Graph* MakeGraphForScript(const char* script) {
125 ScopedVector<char> program(3072);
126 SNPrintF(program, "%s", script);
127 return MakeGraph(program.start(), kFunctionName);
128 }
129
130 private:
131 Isolate* isolate_;
132 Zone* zone_;
133
134 static Local<Value> CompileRun(const char* script) {
135 v8::Local<v8::String> v8_script =
136 v8::String::NewFromUtf8(v8::Isolate::GetCurrent(), script,
137 v8::NewStringType::kNormal)
138 .ToLocalChecked();
139 v8::Local<v8::Context> context =
140 v8::Isolate::GetCurrent()->GetCurrentContext();
141 v8::Local<v8::Script> compiled_script =
142 (v8::Script::Compile(context, v8_script).ToLocalChecked());
143 return compiled_script->Run(context).ToLocalChecked();
144 }
145 };
146
147
27 class BytecodeGraphBuilderTest : public TestWithIsolateAndZone { 148 class BytecodeGraphBuilderTest : public TestWithIsolateAndZone {
28 public: 149 public:
29 BytecodeGraphBuilderTest() : array_builder_(isolate(), zone()) {} 150 BytecodeGraphBuilderTest() : array_builder_(isolate(), zone()) {}
30 151
31 Graph* GetCompletedGraph(); 152 Graph* GetCompletedGraph();
32 153
33 Matcher<Node*> IsUndefinedConstant(); 154 Matcher<Node*> IsUndefinedConstant();
34 Matcher<Node*> IsNullConstant(); 155 Matcher<Node*> IsNullConstant();
35 Matcher<Node*> IsTheHoleConstant(); 156 Matcher<Node*> IsTheHoleConstant();
36 Matcher<Node*> IsFalseConstant(); 157 Matcher<Node*> IsFalseConstant();
37 Matcher<Node*> IsTrueConstant(); 158 Matcher<Node*> IsTrueConstant();
159 Matcher<Node*> IsIntPtrConstant(int value);
160 Matcher<Node*> IsFeedbackVector(Node* effect, Node* control);
38 161
39 interpreter::BytecodeArrayBuilder* array_builder() { return &array_builder_; } 162 interpreter::BytecodeArrayBuilder* array_builder() { return &array_builder_; }
40 163
41 private: 164 private:
42 interpreter::BytecodeArrayBuilder array_builder_; 165 interpreter::BytecodeArrayBuilder array_builder_;
43 166
44 DISALLOW_COPY_AND_ASSIGN(BytecodeGraphBuilderTest); 167 DISALLOW_COPY_AND_ASSIGN(BytecodeGraphBuilderTest);
45 }; 168 };
46 169
47 170
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
89 Matcher<Node*> BytecodeGraphBuilderTest::IsFalseConstant() { 212 Matcher<Node*> BytecodeGraphBuilderTest::IsFalseConstant() {
90 return IsHeapConstant(factory()->false_value()); 213 return IsHeapConstant(factory()->false_value());
91 } 214 }
92 215
93 216
94 Matcher<Node*> BytecodeGraphBuilderTest::IsTrueConstant() { 217 Matcher<Node*> BytecodeGraphBuilderTest::IsTrueConstant() {
95 return IsHeapConstant(factory()->true_value()); 218 return IsHeapConstant(factory()->true_value());
96 } 219 }
97 220
98 221
222 Matcher<Node*> BytecodeGraphBuilderTest::IsIntPtrConstant(int value) {
223 if (kPointerSize == 8) {
224 return IsInt64Constant(value);
225 } else {
226 return IsInt32Constant(value);
227 }
228 }
229
230
231 Matcher<Node*> BytecodeGraphBuilderTest::IsFeedbackVector(Node* effect,
232 Node* control) {
233 int offset = SharedFunctionInfo::kFeedbackVectorOffset - kHeapObjectTag;
234 int offset1 = JSFunction::kSharedFunctionInfoOffset - kHeapObjectTag;
235
236 return IsLoad(kMachAnyTagged,
237 IsLoad(kMachAnyTagged,
238 IsParameter(Linkage::kJSFunctionCallClosureParamIndex),
239 IsIntPtrConstant(offset1), effect, control),
240 IsIntPtrConstant(offset), effect, control);
241 }
242
243
99 TEST_F(BytecodeGraphBuilderTest, ReturnUndefined) { 244 TEST_F(BytecodeGraphBuilderTest, ReturnUndefined) {
100 array_builder()->set_locals_count(0); 245 array_builder()->set_locals_count(0);
101 array_builder()->set_context_count(0); 246 array_builder()->set_context_count(0);
102 array_builder()->set_parameter_count(1); 247 array_builder()->set_parameter_count(1);
103 array_builder()->LoadUndefined().Return(); 248 array_builder()->LoadUndefined().Return();
104 249
105 Graph* graph = GetCompletedGraph(); 250 Graph* graph = GetCompletedGraph();
106 Node* end = graph->end(); 251 Node* end = graph->end();
107 EXPECT_EQ(1, end->InputCount()); 252 EXPECT_EQ(1, end->InputCount());
108 Node* ret = end->InputAt(0); 253 Node* ret = end->InputAt(0);
(...skipping 138 matching lines...) Expand 10 before | Expand all | Expand 10 after
247 392
248 Graph* graph = GetCompletedGraph(); 393 Graph* graph = GetCompletedGraph();
249 Node* end = graph->end(); 394 Node* end = graph->end();
250 EXPECT_EQ(1, end->InputCount()); 395 EXPECT_EQ(1, end->InputCount());
251 Node* ret = end->InputAt(0); 396 Node* ret = end->InputAt(0);
252 EXPECT_THAT( 397 EXPECT_THAT(
253 ret, IsReturn(IsJSAdd(IsNumberConstant(kLeft), IsNumberConstant(kRight)), 398 ret, IsReturn(IsJSAdd(IsNumberConstant(kLeft), IsNumberConstant(kRight)),
254 _, _)); 399 _, _));
255 } 400 }
256 401
402
403 TEST_F(BytecodeGraphBuilderTest, NamedLoadSloppy) {
404 GraphGeneratorHelper helper(isolate(), zone());
405 const char* code_snippet = "function f(p1) {return p1.val;}; f({val:10});";
406 Graph* graph = helper.MakeGraphForScript(code_snippet);
407
408 Node* ret = graph->end()->InputAt(0);
409 Node* effect = graph->start();
410 Node* control = graph->start();
411 Handle<Name> name = StringTable::LookupString(
412 isolate(), factory()->NewStringFromStaticChars("val"));
413
414 EXPECT_THAT(ret, IsReturn(IsJSLoadNamed(name, IsParameter(1),
rmcilroy 2015/11/10 11:23:19 As discussed offline, pull this out into matchers
mythria 2015/11/10 17:02:51 Done.
415 IsFeedbackVector(effect, control),
416 effect, control),
417 _, _));
418 }
419
420
421 TEST_F(BytecodeGraphBuilderTest, NamedLoadStrict) {
422 GraphGeneratorHelper helper(isolate(), zone());
423 const char* code_snippet =
424 "function f(p1) {'use strict'; return p1.val;}; f({val:10});";
425 Graph* graph = helper.MakeGraphForScript(code_snippet);
426
427 Node* ret = graph->end()->InputAt(0);
428 Node* effect = graph->start();
429 Node* control = graph->start();
430 Handle<Name> name = StringTable::LookupString(
431 isolate(), factory()->NewStringFromStaticChars("val"));
432
433 EXPECT_THAT(ret, IsReturn(IsJSLoadNamed(name, IsParameter(1),
434 IsFeedbackVector(effect, control),
435 effect, control),
436 _, _));
437 }
438
439
440 TEST_F(BytecodeGraphBuilderTest, NamedLoadSloppyWide) {
441 GraphGeneratorHelper helper(isolate(), zone());
442 const char code_snippet[] = "function f(p1) {var b; "
443 REPEAT_127(SPACE, " b = p1.val; ")
444 "return p1.val;}; f({val:10});";
rmcilroy 2015/11/10 11:23:19 As discussed offline, let's make the repeated and
mythria 2015/11/10 17:02:51 Done.
445 Graph* graph = helper.MakeGraphForScript(code_snippet);
446
447 Node* ret = graph->end()->InputAt(0);
448 Node* start = graph->start();
449 Handle<Name> name = StringTable::LookupString(
450 isolate(), factory()->NewStringFromStaticChars("val"));
rmcilroy 2015/11/10 11:23:19 nit - make a static helper for this in GraphGenera
mythria 2015/11/10 17:02:51 Done.
451
452 EXPECT_THAT(ret,
453 IsReturn(IsJSLoadNamed(
454 name, IsParameter(1), IsFeedbackVector(start, start),
455 IsJSLoadNamed(name, _, _, _, _), IsIfSuccess(_)),
456 _, _));
457 }
458
459
460 TEST_F(BytecodeGraphBuilderTest, NamedLoadStrictWide) {
461 GraphGeneratorHelper helper(isolate(), zone());
462 const char code_snippet[] = "function f(p1) {'use strict'; var b;"
463 REPEAT_127(SPACE, " b = p1.val; ")
464 "return p1.val;}; f({val:10});";
465 Graph* graph = helper.MakeGraphForScript(code_snippet);
466
467 Node* ret = graph->end()->InputAt(0);
468 Node* start = graph->start();
469 Handle<Name> name = StringTable::LookupString(
470 isolate(), factory()->NewStringFromStaticChars("val"));
471
472 EXPECT_THAT(ret,
473 IsReturn(IsJSLoadNamed(
474 name, IsParameter(1), IsFeedbackVector(start, start),
475 IsJSLoadNamed(name, _, _, _, _), IsIfSuccess(_)),
476 _, _));
477 }
478
257 } // namespace compiler 479 } // namespace compiler
258 } // namespace internal 480 } // namespace internal
259 } // namespace v8 481 } // namespace v8
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698