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

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: Moved graph generation from bytecode into helper, so that all graph generation is at one place. 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 static const char* kFunctionName = "f";
59
60 class GraphGeneratorHelper {
61 public:
62 GraphGeneratorHelper(Isolate* isolate, Zone* zone, const char* script,
63 const char* function_name = kFunctionName)
rmcilroy 2015/11/10 18:00:15 Do you think you'll ever need the function_name pa
mythria 2015/11/11 13:39:24 Done.
64 : GraphGeneratorHelper(isolate, zone, script,
65 MaybeHandle<BytecodeArray>(), function_name) {}
66
67 GraphGeneratorHelper(Isolate* isolate, Zone* zone,
68 MaybeHandle<BytecodeArray> bytecode,
69 const char* function_name = kFunctionName)
rmcilroy 2015/11/10 18:00:15 No need for the function_name argument here - it'l
mythria 2015/11/11 13:39:24 Done.
70 : GraphGeneratorHelper(isolate, zone, nullptr, bytecode, function_name) {}
71
72 Graph* GetCompletedGraph() {
73 ParseInfo parse_info = GetParseInfo();
rmcilroy 2015/11/10 18:00:15 I'd just inline all of GetParseInfo() here and inc
mythria 2015/11/11 13:39:24 I did this more to avoid using a new to create Com
74 CompilationInfo info(&parse_info);
75 if (!bytecode_.is_null()) {
76 info.shared_info()->set_function_data(*bytecode_.ToHandleChecked());
77 }
78
79 MachineOperatorBuilder* machine = new (zone_) MachineOperatorBuilder(
80 zone_, kMachPtr, InstructionSelector::SupportedMachineOperatorFlags());
81 CommonOperatorBuilder* common = new (zone_) CommonOperatorBuilder(zone_);
82 JSOperatorBuilder* javascript = new (zone_) JSOperatorBuilder(zone_);
83 Graph* graph = new (zone_) Graph(zone_);
84 JSGraph* jsgraph = new (zone_)
85 JSGraph(isolate_, graph, common, javascript, nullptr, machine);
86
87 BytecodeGraphBuilder graph_builder(zone_, &info, jsgraph);
88 graph_builder.CreateGraph();
89 return graph;
90 }
91
92 static Handle<String> GetName(Isolate* isolate, const char* name) {
93 Handle<String> result = isolate->factory()->NewStringFromAsciiChecked(name);
94 return isolate->factory()->string_table()->LookupString(isolate, result);
95 }
96
97 private:
98 Isolate* isolate_;
99 Zone* zone_;
100 const char* script_;
101 MaybeHandle<BytecodeArray> bytecode_;
102 const char* function_name_;
rmcilroy 2015/11/10 18:00:15 Fields go below private functions: https://google.
mythria 2015/11/11 13:39:24 Done.
103
104 GraphGeneratorHelper(Isolate* isolate, Zone* zone, const char* script,
105 MaybeHandle<BytecodeArray> bytecode,
106 const char* function_name)
107 : isolate_(isolate),
108 zone_(zone),
109 script_(script),
110 bytecode_(bytecode),
111 function_name_(function_name) {
112 i::FLAG_ignition = true;
113 i::FLAG_always_opt = false;
114 i::FLAG_vector_stores = true;
115 // Set ignition filter flag via SetFlagsFromString to avoid double-free
116 // (or potential leak with StrDup() based on ownership confusion).
117 ScopedVector<char> ignition_filter(64);
118 SNPrintF(ignition_filter, "--ignition-filter=%s", function_name_);
119 FlagList::SetFlagsFromString(ignition_filter.start(),
120 ignition_filter.length());
121 // Ensure handler table is generated.
122 isolate_->interpreter()->Initialize();
123 }
124
125 ParseInfo GetParseInfo() {
126 if (script_) {
127 v8::Context::New(v8::Isolate::GetCurrent())->Enter();
128 v8::Local<v8::Context> context =
129 v8::Isolate::GetCurrent()->GetCurrentContext();
130 CompileRun(script_);
131
132 Local<Function> api_function =
133 Local<Function>::Cast(context->Global()
134 ->Get(context, v8_str(function_name_))
135 .ToLocalChecked());
136 Handle<JSFunction> function =
137 Handle<JSFunction>::cast(v8::Utils::OpenHandle(*api_function));
138 CHECK(function->shared()->HasBytecodeArray());
139
140 context->Exit();
141 return ParseInfo(zone_, function);
142 } else {
rmcilroy 2015/11/10 18:00:15 DCHECK(!bytecode_.is_null());
mythria 2015/11/11 13:39:25 Done.
143 Handle<String> name =
144 isolate_->factory()->NewStringFromAsciiChecked(function_name_);
145 std::string script_str("function " + std::string(function_name_) +
146 "() {}");
147 Handle<String> script =
148 isolate_->factory()->NewStringFromAsciiChecked(script_str.c_str());
149 Handle<SharedFunctionInfo> shared_info =
150 isolate_->factory()->NewSharedFunctionInfo(name, MaybeHandle<Code>());
151 shared_info->set_script(*isolate_->factory()->NewScript(script));
152 return ParseInfo(zone_, shared_info);
153 }
154 }
155
156 static v8::Local<v8::String> v8_str(const char* string) {
157 v8::Local<v8::String> v8_string =
158 v8::String::NewFromUtf8(v8::Isolate::GetCurrent(), string,
159 v8::NewStringType::kNormal)
160 .ToLocalChecked();
161 return v8_string;
162 }
163
164 static Local<Value> CompileRun(const char* source) {
165 v8::Local<v8::Context> context =
166 v8::Isolate::GetCurrent()->GetCurrentContext();
167 v8::Local<v8::Script> compiled_script =
168 (v8::Script::Compile(context, v8_str(source)).ToLocalChecked());
169 return compiled_script->Run(context).ToLocalChecked();
170 }
171 };
172
173
27 class BytecodeGraphBuilderTest : public TestWithIsolateAndZone { 174 class BytecodeGraphBuilderTest : public TestWithIsolateAndZone {
28 public: 175 public:
29 BytecodeGraphBuilderTest() : array_builder_(isolate(), zone()) {} 176 BytecodeGraphBuilderTest() : array_builder_(isolate(), zone()) {}
30 177
31 Graph* GetCompletedGraph();
32
33 Matcher<Node*> IsUndefinedConstant(); 178 Matcher<Node*> IsUndefinedConstant();
34 Matcher<Node*> IsNullConstant(); 179 Matcher<Node*> IsNullConstant();
35 Matcher<Node*> IsTheHoleConstant(); 180 Matcher<Node*> IsTheHoleConstant();
36 Matcher<Node*> IsFalseConstant(); 181 Matcher<Node*> IsFalseConstant();
37 Matcher<Node*> IsTrueConstant(); 182 Matcher<Node*> IsTrueConstant();
183 Matcher<Node*> IsIntPtrConstant(int value);
184 Matcher<Node*> IsFeedbackVector(Node* effect, Node* control);
38 185
39 interpreter::BytecodeArrayBuilder* array_builder() { return &array_builder_; } 186 interpreter::BytecodeArrayBuilder* array_builder() { return &array_builder_; }
40 187
41 private: 188 private:
42 interpreter::BytecodeArrayBuilder array_builder_; 189 interpreter::BytecodeArrayBuilder array_builder_;
43 190
44 DISALLOW_COPY_AND_ASSIGN(BytecodeGraphBuilderTest); 191 DISALLOW_COPY_AND_ASSIGN(BytecodeGraphBuilderTest);
45 }; 192 };
46 193
47 194
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 = new (zone())
55 JSGraph(isolate(), graph, common, javascript, nullptr, 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() { 195 Matcher<Node*> BytecodeGraphBuilderTest::IsUndefinedConstant() {
75 return IsHeapConstant(factory()->undefined_value()); 196 return IsHeapConstant(factory()->undefined_value());
76 } 197 }
77 198
78 199
79 Matcher<Node*> BytecodeGraphBuilderTest::IsNullConstant() { 200 Matcher<Node*> BytecodeGraphBuilderTest::IsNullConstant() {
80 return IsHeapConstant(factory()->null_value()); 201 return IsHeapConstant(factory()->null_value());
81 } 202 }
82 203
83 204
84 Matcher<Node*> BytecodeGraphBuilderTest::IsTheHoleConstant() { 205 Matcher<Node*> BytecodeGraphBuilderTest::IsTheHoleConstant() {
85 return IsHeapConstant(factory()->the_hole_value()); 206 return IsHeapConstant(factory()->the_hole_value());
86 } 207 }
87 208
88 209
89 Matcher<Node*> BytecodeGraphBuilderTest::IsFalseConstant() { 210 Matcher<Node*> BytecodeGraphBuilderTest::IsFalseConstant() {
90 return IsHeapConstant(factory()->false_value()); 211 return IsHeapConstant(factory()->false_value());
91 } 212 }
92 213
93 214
94 Matcher<Node*> BytecodeGraphBuilderTest::IsTrueConstant() { 215 Matcher<Node*> BytecodeGraphBuilderTest::IsTrueConstant() {
95 return IsHeapConstant(factory()->true_value()); 216 return IsHeapConstant(factory()->true_value());
96 } 217 }
97 218
98 219
220 Matcher<Node*> BytecodeGraphBuilderTest::IsIntPtrConstant(int value) {
221 if (kPointerSize == 8) {
222 return IsInt64Constant(value);
223 } else {
224 return IsInt32Constant(value);
225 }
226 }
227
228
229 Matcher<Node*> BytecodeGraphBuilderTest::IsFeedbackVector(Node* effect,
230 Node* control) {
231 int offset = SharedFunctionInfo::kFeedbackVectorOffset - kHeapObjectTag;
232 int offset1 = JSFunction::kSharedFunctionInfoOffset - kHeapObjectTag;
233
234 return IsLoad(kMachAnyTagged,
235 IsLoad(kMachAnyTagged,
236 IsParameter(Linkage::kJSFunctionCallClosureParamIndex),
237 IsIntPtrConstant(offset1), effect, control),
238 IsIntPtrConstant(offset), effect, control);
239 }
240
241
99 TEST_F(BytecodeGraphBuilderTest, ReturnUndefined) { 242 TEST_F(BytecodeGraphBuilderTest, ReturnUndefined) {
100 array_builder()->set_locals_count(0); 243 array_builder()->set_locals_count(0);
101 array_builder()->set_context_count(0); 244 array_builder()->set_context_count(0);
102 array_builder()->set_parameter_count(1); 245 array_builder()->set_parameter_count(1);
103 array_builder()->LoadUndefined().Return(); 246 array_builder()->LoadUndefined().Return();
104 247
105 Graph* graph = GetCompletedGraph(); 248 GraphGeneratorHelper helper(isolate(), zone(),
249 array_builder()->ToBytecodeArray());
250 Graph* graph = helper.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);
109 Node* effect = graph->start(); 254 Node* effect = graph->start();
110 Node* control = graph->start(); 255 Node* control = graph->start();
111 EXPECT_THAT(ret, IsReturn(IsUndefinedConstant(), effect, control)); 256 EXPECT_THAT(ret, IsReturn(IsUndefinedConstant(), effect, control));
112 } 257 }
113 258
114 259
115 TEST_F(BytecodeGraphBuilderTest, ReturnNull) { 260 TEST_F(BytecodeGraphBuilderTest, ReturnNull) {
116 array_builder()->set_locals_count(0); 261 array_builder()->set_locals_count(0);
117 array_builder()->set_context_count(0); 262 array_builder()->set_context_count(0);
118 array_builder()->set_parameter_count(1); 263 array_builder()->set_parameter_count(1);
119 array_builder()->LoadNull().Return(); 264 array_builder()->LoadNull().Return();
120 265
121 Graph* graph = GetCompletedGraph(); 266 GraphGeneratorHelper helper(isolate(), zone(),
267 array_builder()->ToBytecodeArray());
268 Graph* graph = helper.GetCompletedGraph();
122 Node* end = graph->end(); 269 Node* end = graph->end();
123 EXPECT_EQ(1, end->InputCount()); 270 EXPECT_EQ(1, end->InputCount());
124 Node* ret = end->InputAt(0); 271 Node* ret = end->InputAt(0);
125 EXPECT_THAT(ret, IsReturn(IsNullConstant(), graph->start(), graph->start())); 272 EXPECT_THAT(ret, IsReturn(IsNullConstant(), graph->start(), graph->start()));
126 } 273 }
127 274
128 275
129 TEST_F(BytecodeGraphBuilderTest, ReturnTheHole) { 276 TEST_F(BytecodeGraphBuilderTest, ReturnTheHole) {
130 array_builder()->set_locals_count(0); 277 array_builder()->set_locals_count(0);
131 array_builder()->set_context_count(0); 278 array_builder()->set_context_count(0);
132 array_builder()->set_parameter_count(1); 279 array_builder()->set_parameter_count(1);
133 array_builder()->LoadTheHole().Return(); 280 array_builder()->LoadTheHole().Return();
134 281
135 Graph* graph = GetCompletedGraph(); 282 GraphGeneratorHelper helper(isolate(), zone(),
283 array_builder()->ToBytecodeArray());
284 Graph* graph = helper.GetCompletedGraph();
136 Node* end = graph->end(); 285 Node* end = graph->end();
137 EXPECT_EQ(1, end->InputCount()); 286 EXPECT_EQ(1, end->InputCount());
138 Node* ret = end->InputAt(0); 287 Node* ret = end->InputAt(0);
139 Node* effect = graph->start(); 288 Node* effect = graph->start();
140 Node* control = graph->start(); 289 Node* control = graph->start();
141 EXPECT_THAT(ret, IsReturn(IsTheHoleConstant(), effect, control)); 290 EXPECT_THAT(ret, IsReturn(IsTheHoleConstant(), effect, control));
142 } 291 }
143 292
144 293
145 TEST_F(BytecodeGraphBuilderTest, ReturnTrue) { 294 TEST_F(BytecodeGraphBuilderTest, ReturnTrue) {
146 array_builder()->set_locals_count(0); 295 array_builder()->set_locals_count(0);
147 array_builder()->set_context_count(0); 296 array_builder()->set_context_count(0);
148 array_builder()->set_parameter_count(1); 297 array_builder()->set_parameter_count(1);
149 array_builder()->LoadTrue().Return(); 298 array_builder()->LoadTrue().Return();
150 299
151 Graph* graph = GetCompletedGraph(); 300 GraphGeneratorHelper helper(isolate(), zone(),
301 array_builder()->ToBytecodeArray());
302 Graph* graph = helper.GetCompletedGraph();
152 Node* end = graph->end(); 303 Node* end = graph->end();
153 EXPECT_EQ(1, end->InputCount()); 304 EXPECT_EQ(1, end->InputCount());
154 Node* ret = end->InputAt(0); 305 Node* ret = end->InputAt(0);
155 Node* effect = graph->start(); 306 Node* effect = graph->start();
156 Node* control = graph->start(); 307 Node* control = graph->start();
157 EXPECT_THAT(ret, IsReturn(IsTrueConstant(), effect, control)); 308 EXPECT_THAT(ret, IsReturn(IsTrueConstant(), effect, control));
158 } 309 }
159 310
160 311
161 TEST_F(BytecodeGraphBuilderTest, ReturnFalse) { 312 TEST_F(BytecodeGraphBuilderTest, ReturnFalse) {
162 array_builder()->set_locals_count(0); 313 array_builder()->set_locals_count(0);
163 array_builder()->set_context_count(0); 314 array_builder()->set_context_count(0);
164 array_builder()->set_parameter_count(1); 315 array_builder()->set_parameter_count(1);
165 array_builder()->LoadFalse().Return(); 316 array_builder()->LoadFalse().Return();
166 317
167 Graph* graph = GetCompletedGraph(); 318 GraphGeneratorHelper helper(isolate(), zone(),
319 array_builder()->ToBytecodeArray());
320 Graph* graph = helper.GetCompletedGraph();
168 Node* end = graph->end(); 321 Node* end = graph->end();
169 EXPECT_EQ(1, end->InputCount()); 322 EXPECT_EQ(1, end->InputCount());
170 Node* ret = end->InputAt(0); 323 Node* ret = end->InputAt(0);
171 Node* effect = graph->start(); 324 Node* effect = graph->start();
172 Node* control = graph->start(); 325 Node* control = graph->start();
173 EXPECT_THAT(ret, IsReturn(IsFalseConstant(), effect, control)); 326 EXPECT_THAT(ret, IsReturn(IsFalseConstant(), effect, control));
174 } 327 }
175 328
176 329
177 TEST_F(BytecodeGraphBuilderTest, ReturnInt8) { 330 TEST_F(BytecodeGraphBuilderTest, ReturnInt8) {
178 static const int kValue = 3; 331 static const int kValue = 3;
179 array_builder()->set_locals_count(0); 332 array_builder()->set_locals_count(0);
180 array_builder()->set_context_count(0); 333 array_builder()->set_context_count(0);
181 array_builder()->set_parameter_count(1); 334 array_builder()->set_parameter_count(1);
182 array_builder()->LoadLiteral(Smi::FromInt(kValue)).Return(); 335 array_builder()->LoadLiteral(Smi::FromInt(kValue)).Return();
183 336
184 Graph* graph = GetCompletedGraph(); 337 GraphGeneratorHelper helper(isolate(), zone(),
338 array_builder()->ToBytecodeArray());
339 Graph* graph = helper.GetCompletedGraph();
185 Node* end = graph->end(); 340 Node* end = graph->end();
186 EXPECT_EQ(1, end->InputCount()); 341 EXPECT_EQ(1, end->InputCount());
187 Node* ret = end->InputAt(0); 342 Node* ret = end->InputAt(0);
188 Node* effect = graph->start(); 343 Node* effect = graph->start();
189 Node* control = graph->start(); 344 Node* control = graph->start();
190 EXPECT_THAT(ret, IsReturn(IsNumberConstant(kValue), effect, control)); 345 EXPECT_THAT(ret, IsReturn(IsNumberConstant(kValue), effect, control));
191 } 346 }
192 347
193 348
194 TEST_F(BytecodeGraphBuilderTest, ReturnDouble) { 349 TEST_F(BytecodeGraphBuilderTest, ReturnDouble) {
195 const double kValue = 0.123456789; 350 const double kValue = 0.123456789;
196 array_builder()->set_locals_count(0); 351 array_builder()->set_locals_count(0);
197 array_builder()->set_context_count(0); 352 array_builder()->set_context_count(0);
198 array_builder()->set_parameter_count(1); 353 array_builder()->set_parameter_count(1);
199 array_builder()->LoadLiteral(factory()->NewHeapNumber(kValue)); 354 array_builder()->LoadLiteral(factory()->NewHeapNumber(kValue));
200 array_builder()->Return(); 355 array_builder()->Return();
201 356
202 Graph* graph = GetCompletedGraph(); 357 GraphGeneratorHelper helper(isolate(), zone(),
358 array_builder()->ToBytecodeArray());
359 Graph* graph = helper.GetCompletedGraph();
203 Node* end = graph->end(); 360 Node* end = graph->end();
204 EXPECT_EQ(1, end->InputCount()); 361 EXPECT_EQ(1, end->InputCount());
205 Node* ret = end->InputAt(0); 362 Node* ret = end->InputAt(0);
206 Node* effect = graph->start(); 363 Node* effect = graph->start();
207 Node* control = graph->start(); 364 Node* control = graph->start();
208 EXPECT_THAT(ret, IsReturn(IsNumberConstant(kValue), effect, control)); 365 EXPECT_THAT(ret, IsReturn(IsNumberConstant(kValue), effect, control));
209 } 366 }
210 367
211 368
212 TEST_F(BytecodeGraphBuilderTest, SimpleExpressionWithParameters) { 369 TEST_F(BytecodeGraphBuilderTest, SimpleExpressionWithParameters) {
213 array_builder()->set_locals_count(1); 370 array_builder()->set_locals_count(1);
214 array_builder()->set_context_count(0); 371 array_builder()->set_context_count(0);
215 array_builder()->set_parameter_count(3); 372 array_builder()->set_parameter_count(3);
216 array_builder() 373 array_builder()
217 ->LoadAccumulatorWithRegister(array_builder()->Parameter(1)) 374 ->LoadAccumulatorWithRegister(array_builder()->Parameter(1))
218 .BinaryOperation(Token::Value::ADD, array_builder()->Parameter(2), 375 .BinaryOperation(Token::Value::ADD, array_builder()->Parameter(2),
219 Strength::WEAK) 376 Strength::WEAK)
220 .StoreAccumulatorInRegister(interpreter::Register(0)) 377 .StoreAccumulatorInRegister(interpreter::Register(0))
221 .Return(); 378 .Return();
222 379
223 Graph* graph = GetCompletedGraph(); 380 GraphGeneratorHelper helper(isolate(), zone(),
381 array_builder()->ToBytecodeArray());
382 Graph* graph = helper.GetCompletedGraph();
224 Node* end = graph->end(); 383 Node* end = graph->end();
225 EXPECT_EQ(1, end->InputCount()); 384 EXPECT_EQ(1, end->InputCount());
226 Node* ret = end->InputAt(0); 385 Node* ret = end->InputAt(0);
227 // NB binary operation is <reg> <op> <acc>. The register represents 386 // NB binary operation is <reg> <op> <acc>. The register represents
228 // the left-hand side, which is why parameters appear in opposite 387 // the left-hand side, which is why parameters appear in opposite
229 // order to construction via the builder. 388 // order to construction via the builder.
230 EXPECT_THAT(ret, IsReturn(IsJSAdd(IsParameter(2), IsParameter(1)), _, _)); 389 EXPECT_THAT(ret, IsReturn(IsJSAdd(IsParameter(2), IsParameter(1)), _, _));
231 } 390 }
232 391
233 392
234 TEST_F(BytecodeGraphBuilderTest, SimpleExpressionWithRegister) { 393 TEST_F(BytecodeGraphBuilderTest, SimpleExpressionWithRegister) {
235 static const int kLeft = -655371; 394 static const int kLeft = -655371;
236 static const int kRight = +2000000; 395 static const int kRight = +2000000;
237 array_builder()->set_locals_count(1); 396 array_builder()->set_locals_count(1);
238 array_builder()->set_context_count(0); 397 array_builder()->set_context_count(0);
239 array_builder()->set_parameter_count(1); 398 array_builder()->set_parameter_count(1);
240 array_builder() 399 array_builder()
241 ->LoadLiteral(Smi::FromInt(kLeft)) 400 ->LoadLiteral(Smi::FromInt(kLeft))
242 .StoreAccumulatorInRegister(interpreter::Register(0)) 401 .StoreAccumulatorInRegister(interpreter::Register(0))
243 .LoadLiteral(Smi::FromInt(kRight)) 402 .LoadLiteral(Smi::FromInt(kRight))
244 .BinaryOperation(Token::Value::ADD, interpreter::Register(0), 403 .BinaryOperation(Token::Value::ADD, interpreter::Register(0),
245 Strength::WEAK) 404 Strength::WEAK)
246 .Return(); 405 .Return();
247 406
248 Graph* graph = GetCompletedGraph(); 407 GraphGeneratorHelper helper(isolate(), zone(),
408 array_builder()->ToBytecodeArray());
409 Graph* graph = helper.GetCompletedGraph();
249 Node* end = graph->end(); 410 Node* end = graph->end();
250 EXPECT_EQ(1, end->InputCount()); 411 EXPECT_EQ(1, end->InputCount());
251 Node* ret = end->InputAt(0); 412 Node* ret = end->InputAt(0);
252 EXPECT_THAT( 413 EXPECT_THAT(
253 ret, IsReturn(IsJSAdd(IsNumberConstant(kLeft), IsNumberConstant(kRight)), 414 ret, IsReturn(IsJSAdd(IsNumberConstant(kLeft), IsNumberConstant(kRight)),
254 _, _)); 415 _, _));
255 } 416 }
256 417
418
419 TEST_F(BytecodeGraphBuilderTest, NamedLoadSloppy) {
420 const char* code_snippet = "function f(p1) {return p1.val;}; f({val:10});";
421 GraphGeneratorHelper helper(isolate(), zone(), code_snippet);
422 Graph* graph = helper.GetCompletedGraph();
423
424 Node* ret = graph->end()->InputAt(0);
425 Node* start = graph->start();
426
427 Handle<Name> name = GraphGeneratorHelper::GetName(isolate(), "val");
428 Matcher<Node*> feedback_vector_matcher = IsFeedbackVector(start, start);
429 Matcher<Node*> load_named_matcher = IsJSLoadNamed(
430 name, IsParameter(1), feedback_vector_matcher, start, start);
431
432 EXPECT_THAT(ret, IsReturn(load_named_matcher, _, _));
433 }
434
435
436 TEST_F(BytecodeGraphBuilderTest, NamedLoadStrict) {
437 const char* code_snippet =
438 "function f(p1) {'use strict'; return p1.val;}; f({val:10});";
439 GraphGeneratorHelper helper(isolate(), zone(), code_snippet);
440 Graph* graph = helper.GetCompletedGraph();
441
442 Node* ret = graph->end()->InputAt(0);
443 Node* start = graph->start();
444
445 Handle<Name> name = GraphGeneratorHelper::GetName(isolate(), "val");
446 Matcher<Node*> feedback_vector_matcher = IsFeedbackVector(start, start);
447 Matcher<Node*> load_named_matcher = IsJSLoadNamed(
448 name, IsParameter(1), feedback_vector_matcher, start, start);
449
450 EXPECT_THAT(ret, IsReturn(load_named_matcher, _, _));
451 }
452
453
454 TEST_F(BytecodeGraphBuilderTest, NamedLoadSloppyWide) {
455 const char code_snippet[] = "function f(p1) {var b; "
456 REPEAT_127(SPACE, " b = p1.name; ")
rmcilroy 2015/11/10 18:00:15 nit - for clarity maybe make this val_prev or some
mythria 2015/11/11 13:39:24 Done.
457 "return p1.val;}; f({val:10, name:'abc'});";
458 GraphGeneratorHelper helper(isolate(), zone(), code_snippet);
459 Graph* graph = helper.GetCompletedGraph();
460
461 Node* ret = graph->end()->InputAt(0);
462 Node* start = graph->start();
463
464 Handle<Name> name = GraphGeneratorHelper::GetName(isolate(), "val");
465 Matcher<Node*> feedback_vector_matcher = IsFeedbackVector(start, start);
466 Matcher<Node*> effect = IsJSLoadNamed(
rmcilroy 2015/11/10 18:00:15 nit - call this preceeding_load or similar for cla
mythria 2015/11/11 13:39:24 Done.
467 GraphGeneratorHelper::GetName(isolate(), "name"), _, _, _, _);
468 Matcher<Node*> load_named_matcher_wide = IsJSLoadNamed(
469 name, IsParameter(1), feedback_vector_matcher, effect, IsIfSuccess(_));
470
471 EXPECT_THAT(ret, IsReturn(load_named_matcher_wide, _, _));
472 }
473
474
475 TEST_F(BytecodeGraphBuilderTest, NamedLoadStrictWide) {
476 const char code_snippet[] = "function f(p1) {'use strict'; var b;"
477 REPEAT_127(SPACE, " b = p1.name; ")
rmcilroy 2015/11/10 18:00:15 ditto
mythria 2015/11/11 13:39:24 Done.
478 "return p1.val;}; f({val:10, name:'abc'});";
479 GraphGeneratorHelper helper(isolate(), zone(), code_snippet);
480 Graph* graph = helper.GetCompletedGraph();
481
482 Node* ret = graph->end()->InputAt(0);
483 Node* start = graph->start();
484
485 Handle<Name> name = GraphGeneratorHelper::GetName(isolate(), "val");
486 Matcher<Node*> feedback_vector_matcher = IsFeedbackVector(start, start);
487 Matcher<Node*> effect = IsJSLoadNamed(
rmcilroy 2015/11/10 18:00:15 ditto
mythria 2015/11/11 13:39:24 Done.
488 GraphGeneratorHelper::GetName(isolate(), "name"), _, _, _, _);
489 Matcher<Node*> load_named_matcher_wide = IsJSLoadNamed(
490 name, IsParameter(1), feedback_vector_matcher, effect, IsIfSuccess(_));
491
492 EXPECT_THAT(ret, IsReturn(load_named_matcher_wide, _, _));
493 }
494
257 } // namespace compiler 495 } // namespace compiler
258 } // namespace internal 496 } // namespace internal
259 } // namespace v8 497 } // namespace v8
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698