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

Side by Side Diff: test/cctest/test-ast-expression-visitor.cc

Issue 1968383002: Remove Expression::bounds_, in order to conserve memory during parsing. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Remove Expression::bounds_ Created 4 years, 7 months 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 | « test/cctest/test-asm-validator.cc ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 <stdlib.h> 5 #include <stdlib.h>
6 #include <map>
6 7
7 #include "src/v8.h" 8 #include "src/v8.h"
8 9
9 #include "src/ast/ast.h" 10 #include "src/ast/ast.h"
10 #include "src/ast/ast-expression-visitor.h" 11 #include "src/ast/ast-expression-visitor.h"
11 #include "src/ast/scopes.h" 12 #include "src/ast/scopes.h"
12 #include "src/parsing/parser.h" 13 #include "src/parsing/parser.h"
13 #include "src/parsing/rewriter.h" 14 #include "src/parsing/rewriter.h"
14 #include "test/cctest/cctest.h" 15 #include "test/cctest/cctest.h"
15 #include "test/cctest/expression-type-collector.h" 16 #include "test/cctest/expression-type-collector.h"
16 #include "test/cctest/expression-type-collector-macros.h" 17 #include "test/cctest/expression-type-collector-macros.h"
17 18
18 using namespace v8::internal; 19 using namespace v8::internal;
19 20
20 namespace { 21 namespace {
21 22
22 static void CollectTypes(HandleAndZoneScope* handles, const char* source, 23 class NodeTypeCounter : public AstExpressionVisitor {
23 ZoneVector<ExpressionTypeEntry>* dst) { 24 public:
24 i::Isolate* isolate = CcTest::i_isolate(); 25 typedef std::map<AstNode::NodeType, int> Counters;
25 i::Factory* factory = isolate->factory();
26 26
27 i::Handle<i::String> source_code = 27 NodeTypeCounter(Isolate* isolate, Expression* expr, Counters* counts)
28 factory->NewStringFromUtf8(i::CStrVector(source)).ToHandleChecked(); 28 : AstExpressionVisitor(isolate, expr), counts_(counts) {}
29 29
30 i::Handle<i::Script> script = factory->NewScript(source_code); 30 protected:
31 void VisitExpression(Expression* expr) override {
32 (*counts_)[expr->node_type()]++;
33 }
31 34
32 i::ParseInfo info(handles->main_zone(), script); 35 private:
33 i::Parser parser(&info); 36 Counters* counts_;
34 info.set_global(); 37 };
35 info.set_lazy(false);
36 info.set_allow_lazy_parsing(false);
37 info.set_toplevel(true);
38
39 CHECK(i::Compiler::ParseAndAnalyze(&info));
40
41 ExpressionTypeCollector(
42 isolate,
43 info.scope()->declarations()->at(0)->AsFunctionDeclaration()->fun(), dst)
44 .Run();
45 }
46 38
47 } // namespace 39 } // namespace
48 40
49 41 TEST(VisitExpression) {
50 TEST(VisitExpressions) {
51 v8::V8::Initialize();
52 HandleAndZoneScope handles;
53 ZoneVector<ExpressionTypeEntry> types(handles.main_zone());
54 const char test_function[] = 42 const char test_function[] =
55 "function GeometricMean(stdlib, foreign, buffer) {\n" 43 "function GeometricMean(stdlib, foreign, buffer) {\n"
56 " \"use asm\";\n" 44 " \"use asm\";\n"
57 "\n" 45 "\n"
58 " var exp = stdlib.Math.exp;\n" 46 " var exp = stdlib.Math.exp;\n"
59 " var log = stdlib.Math.log;\n" 47 " var log = stdlib.Math.log;\n"
60 " var values = new stdlib.Float64Array(buffer);\n" 48 " var values = new stdlib.Float64Array(buffer);\n"
61 "\n" 49 "\n"
62 " function logSum(start, end) {\n" 50 " function logSum(start, end) {\n"
63 " start = start|0;\n" 51 " start = start|0;\n"
(...skipping 13 matching lines...) Expand all
77 " function geometricMean(start, end) {\n" 65 " function geometricMean(start, end) {\n"
78 " start = start|0;\n" 66 " start = start|0;\n"
79 " end = end|0;\n" 67 " end = end|0;\n"
80 "\n" 68 "\n"
81 " return +exp(+logSum(start, end) / +((end - start)|0));\n" 69 " return +exp(+logSum(start, end) / +((end - start)|0));\n"
82 " }\n" 70 " }\n"
83 "\n" 71 "\n"
84 " return { geometricMean: geometricMean };\n" 72 " return { geometricMean: geometricMean };\n"
85 "}\n"; 73 "}\n";
86 74
87 CollectTypes(&handles, test_function, &types); 75 // Parse + compile test_function, and extract the AST node for it.
88 CHECK_TYPES_BEGIN {
89 // function logSum
90 CHECK_EXPR(FunctionLiteral, Bounds::Unbounded()) {
91 CHECK_EXPR(FunctionLiteral, Bounds::Unbounded()) {
92 CHECK_EXPR(Assignment, Bounds::Unbounded()) {
93 CHECK_VAR(start, Bounds::Unbounded());
94 CHECK_EXPR(BinaryOperation, Bounds::Unbounded()) {
95 CHECK_VAR(start, Bounds::Unbounded());
96 CHECK_EXPR(Literal, Bounds::Unbounded());
97 }
98 }
99 CHECK_EXPR(Assignment, Bounds::Unbounded()) {
100 CHECK_VAR(end, Bounds::Unbounded());
101 CHECK_EXPR(BinaryOperation, Bounds::Unbounded()) {
102 CHECK_VAR(end, Bounds::Unbounded());
103 CHECK_EXPR(Literal, Bounds::Unbounded());
104 }
105 }
106 CHECK_EXPR(Assignment, Bounds::Unbounded()) {
107 CHECK_VAR(sum, Bounds::Unbounded());
108 CHECK_EXPR(Literal, Bounds::Unbounded());
109 }
110 CHECK_EXPR(Assignment, Bounds::Unbounded()) {
111 CHECK_VAR(p, Bounds::Unbounded());
112 CHECK_EXPR(Literal, Bounds::Unbounded());
113 }
114 CHECK_EXPR(Assignment, Bounds::Unbounded()) {
115 CHECK_VAR(q, Bounds::Unbounded());
116 CHECK_EXPR(Literal, Bounds::Unbounded());
117 }
118 // for (p = start << 3, q = end << 3;
119 CHECK_EXPR(BinaryOperation, Bounds::Unbounded()) {
120 CHECK_EXPR(Assignment, Bounds::Unbounded()) {
121 CHECK_VAR(p, Bounds::Unbounded());
122 CHECK_EXPR(BinaryOperation, Bounds::Unbounded()) {
123 CHECK_VAR(start, Bounds::Unbounded());
124 CHECK_EXPR(Literal, Bounds::Unbounded());
125 }
126 }
127 CHECK_EXPR(Assignment, Bounds::Unbounded()) {
128 CHECK_VAR(q, Bounds::Unbounded());
129 CHECK_EXPR(BinaryOperation, Bounds::Unbounded()) {
130 CHECK_VAR(end, Bounds::Unbounded());
131 CHECK_EXPR(Literal, Bounds::Unbounded());
132 }
133 }
134 }
135 // (p|0) < (q|0);
136 CHECK_EXPR(CompareOperation, Bounds::Unbounded()) {
137 CHECK_EXPR(BinaryOperation, Bounds::Unbounded()) {
138 CHECK_VAR(p, Bounds::Unbounded());
139 CHECK_EXPR(Literal, Bounds::Unbounded());
140 }
141 CHECK_EXPR(BinaryOperation, Bounds::Unbounded()) {
142 CHECK_VAR(q, Bounds::Unbounded());
143 CHECK_EXPR(Literal, Bounds::Unbounded());
144 }
145 }
146 // p = (p + 8)|0) {\n"
147 CHECK_EXPR(Assignment, Bounds::Unbounded()) {
148 CHECK_VAR(p, Bounds::Unbounded());
149 CHECK_EXPR(BinaryOperation, Bounds::Unbounded()) {
150 CHECK_EXPR(BinaryOperation, Bounds::Unbounded()) {
151 CHECK_VAR(p, Bounds::Unbounded());
152 CHECK_EXPR(Literal, Bounds::Unbounded());
153 }
154 CHECK_EXPR(Literal, Bounds::Unbounded());
155 }
156 }
157 // sum = sum + +log(values[p>>3]);
158 CHECK_EXPR(Assignment, Bounds::Unbounded()) {
159 CHECK_VAR(sum, Bounds::Unbounded());
160 CHECK_EXPR(BinaryOperation, Bounds::Unbounded()) {
161 CHECK_VAR(sum, Bounds::Unbounded());
162 CHECK_EXPR(BinaryOperation, Bounds::Unbounded()) {
163 CHECK_EXPR(Call, Bounds::Unbounded()) {
164 CHECK_VAR(log, Bounds::Unbounded());
165 CHECK_EXPR(Property, Bounds::Unbounded()) {
166 CHECK_VAR(values, Bounds::Unbounded());
167 CHECK_EXPR(BinaryOperation, Bounds::Unbounded()) {
168 CHECK_VAR(p, Bounds::Unbounded());
169 CHECK_EXPR(Literal, Bounds::Unbounded());
170 }
171 }
172 }
173 CHECK_EXPR(Literal, Bounds::Unbounded());
174 }
175 }
176 }
177 // return +sum;
178 CHECK_EXPR(BinaryOperation, Bounds::Unbounded()) {
179 CHECK_VAR(sum, Bounds::Unbounded());
180 CHECK_EXPR(Literal, Bounds::Unbounded());
181 }
182 }
183 // function geometricMean
184 CHECK_EXPR(FunctionLiteral, Bounds::Unbounded()) {
185 CHECK_EXPR(Assignment, Bounds::Unbounded()) {
186 CHECK_VAR(start, Bounds::Unbounded());
187 CHECK_EXPR(BinaryOperation, Bounds::Unbounded()) {
188 CHECK_VAR(start, Bounds::Unbounded());
189 CHECK_EXPR(Literal, Bounds::Unbounded());
190 }
191 }
192 CHECK_EXPR(Assignment, Bounds::Unbounded()) {
193 CHECK_VAR(end, Bounds::Unbounded());
194 CHECK_EXPR(BinaryOperation, Bounds::Unbounded()) {
195 CHECK_VAR(end, Bounds::Unbounded());
196 CHECK_EXPR(Literal, Bounds::Unbounded());
197 }
198 }
199 // return +exp(+logSum(start, end) / +((end - start)|0));
200 CHECK_EXPR(BinaryOperation, Bounds::Unbounded()) {
201 CHECK_EXPR(Call, Bounds::Unbounded()) {
202 CHECK_VAR(exp, Bounds::Unbounded());
203 CHECK_EXPR(BinaryOperation, Bounds::Unbounded()) {
204 CHECK_EXPR(BinaryOperation, Bounds::Unbounded()) {
205 CHECK_EXPR(Call, Bounds::Unbounded()) {
206 CHECK_VAR(logSum, Bounds::Unbounded());
207 CHECK_VAR(start, Bounds::Unbounded());
208 CHECK_VAR(end, Bounds::Unbounded());
209 }
210 CHECK_EXPR(Literal, Bounds::Unbounded());
211 }
212 CHECK_EXPR(BinaryOperation, Bounds::Unbounded()) {
213 CHECK_EXPR(BinaryOperation, Bounds::Unbounded()) {
214 CHECK_EXPR(BinaryOperation, Bounds::Unbounded()) {
215 CHECK_VAR(end, Bounds::Unbounded());
216 CHECK_VAR(start, Bounds::Unbounded());
217 }
218 CHECK_EXPR(Literal, Bounds::Unbounded());
219 }
220 CHECK_EXPR(Literal, Bounds::Unbounded());
221 }
222 }
223 }
224 CHECK_EXPR(Literal, Bounds::Unbounded());
225 }
226 }
227 // "use asm";
228 CHECK_EXPR(Literal, Bounds::Unbounded());
229 // var exp = stdlib.Math.exp;
230 CHECK_EXPR(Assignment, Bounds::Unbounded()) {
231 CHECK_VAR(exp, Bounds::Unbounded());
232 CHECK_EXPR(Property, Bounds::Unbounded()) {
233 CHECK_EXPR(Property, Bounds::Unbounded()) {
234 CHECK_VAR(stdlib, Bounds::Unbounded());
235 CHECK_EXPR(Literal, Bounds::Unbounded());
236 }
237 CHECK_EXPR(Literal, Bounds::Unbounded());
238 }
239 }
240 // var log = stdlib.Math.log;
241 CHECK_EXPR(Assignment, Bounds::Unbounded()) {
242 CHECK_VAR(log, Bounds::Unbounded());
243 CHECK_EXPR(Property, Bounds::Unbounded()) {
244 CHECK_EXPR(Property, Bounds::Unbounded()) {
245 CHECK_VAR(stdlib, Bounds::Unbounded());
246 CHECK_EXPR(Literal, Bounds::Unbounded());
247 }
248 CHECK_EXPR(Literal, Bounds::Unbounded());
249 }
250 }
251 // var values = new stdlib.Float64Array(buffer);
252 CHECK_EXPR(Assignment, Bounds::Unbounded()) {
253 CHECK_VAR(values, Bounds::Unbounded());
254 CHECK_EXPR(CallNew, Bounds::Unbounded()) {
255 CHECK_EXPR(Property, Bounds::Unbounded()) {
256 CHECK_VAR(stdlib, Bounds::Unbounded());
257 CHECK_EXPR(Literal, Bounds::Unbounded());
258 }
259 CHECK_VAR(buffer, Bounds::Unbounded());
260 }
261 }
262 // return { geometricMean: geometricMean };
263 CHECK_EXPR(ObjectLiteral, Bounds::Unbounded()) {
264 CHECK_VAR(geometricMean, Bounds::Unbounded());
265 }
266 }
267 }
268 CHECK_TYPES_END
269 }
270
271
272 TEST(VisitConditional) {
273 v8::V8::Initialize(); 76 v8::V8::Initialize();
274 HandleAndZoneScope handles; 77 HandleAndZoneScope handles;
275 ZoneVector<ExpressionTypeEntry> types(handles.main_zone()); 78 i::Isolate* isolate = CcTest::i_isolate();
276 // Check that traversing the ternary operator works. 79 i::Handle<i::String> source_code =
277 const char test_function[] = 80 isolate->factory()
278 "function foo() {\n" 81 ->NewStringFromUtf8(i::CStrVector(test_function))
279 " var a, b, c;\n" 82 .ToHandleChecked();
280 " var x = a ? b : c;\n" 83 i::Handle<i::Script> script = isolate->factory()->NewScript(source_code);
281 "}\n"; 84 i::ParseInfo info(handles.main_zone(), script);
282 CollectTypes(&handles, test_function, &types); 85 i::Parser parser(&info);
283 CHECK_TYPES_BEGIN { 86 info.set_global();
284 CHECK_EXPR(FunctionLiteral, Bounds::Unbounded()) { 87 info.set_lazy(false);
285 CHECK_EXPR(Assignment, Bounds::Unbounded()) { 88 info.set_allow_lazy_parsing(false);
286 CHECK_VAR(x, Bounds::Unbounded()); 89 info.set_toplevel(true);
287 CHECK_EXPR(Conditional, Bounds::Unbounded()) { 90 CHECK(i::Compiler::ParseAndAnalyze(&info));
288 CHECK_VAR(a, Bounds::Unbounded()); 91 Expression* test_function_expr =
289 CHECK_VAR(b, Bounds::Unbounded()); 92 info.scope()->declarations()->at(0)->AsFunctionDeclaration()->fun();
290 CHECK_VAR(c, Bounds::Unbounded()); 93
291 } 94 // Run NodeTypeCounter and sanity check counts for 3 expression types,
292 } 95 // and for overall # of types found.
bradnelson 2016/05/12 15:43:45 Yeah that's better, this was overkill at the time.
293 } 96 NodeTypeCounter::Counters counts;
294 } 97 NodeTypeCounter(isolate, test_function_expr, &counts).Run();
295 CHECK_TYPES_END 98 CHECK_EQ(21, counts[AstNode::kBinaryOperation]);
99 CHECK_EQ(26, counts[AstNode::kLiteral]);
100 CHECK_EQ(3, counts[AstNode::kFunctionLiteral]);
101 CHECK_EQ(10, counts.size());
296 } 102 }
297
298
299 TEST(VisitEmptyForStatment) {
300 v8::V8::Initialize();
301 HandleAndZoneScope handles;
302 ZoneVector<ExpressionTypeEntry> types(handles.main_zone());
303 // Check that traversing an empty for statement works.
304 const char test_function[] =
305 "function foo() {\n"
306 " for (;;) {}\n"
307 "}\n";
308 CollectTypes(&handles, test_function, &types);
309 CHECK_TYPES_BEGIN {
310 CHECK_EXPR(FunctionLiteral, Bounds::Unbounded()) {}
311 }
312 CHECK_TYPES_END
313 }
314
315
316 TEST(VisitSwitchStatment) {
317 v8::V8::Initialize();
318 HandleAndZoneScope handles;
319 ZoneVector<ExpressionTypeEntry> types(handles.main_zone());
320 // Check that traversing a switch with a default works.
321 const char test_function[] =
322 "function foo() {\n"
323 " switch (0) { case 1: break; default: break; }\n"
324 "}\n";
325 CollectTypes(&handles, test_function, &types);
326 CHECK_TYPES_BEGIN {
327 CHECK_EXPR(FunctionLiteral, Bounds::Unbounded()) {
328 CHECK_EXPR(Assignment, Bounds::Unbounded()) {
329 CHECK_VAR(.switch_tag, Bounds::Unbounded());
330 CHECK_EXPR(Literal, Bounds::Unbounded());
331 }
332 CHECK_EXPR(Literal, Bounds::Unbounded());
333 CHECK_VAR(.switch_tag, Bounds::Unbounded());
334 CHECK_EXPR(Literal, Bounds::Unbounded());
335 }
336 }
337 CHECK_TYPES_END
338 }
339
340
341 TEST(VisitThrow) {
342 v8::V8::Initialize();
343 HandleAndZoneScope handles;
344 ZoneVector<ExpressionTypeEntry> types(handles.main_zone());
345 const char test_function[] =
346 "function foo() {\n"
347 " throw 123;\n"
348 "}\n";
349 CollectTypes(&handles, test_function, &types);
350 CHECK_TYPES_BEGIN {
351 CHECK_EXPR(FunctionLiteral, Bounds::Unbounded()) {
352 CHECK_EXPR(Throw, Bounds::Unbounded()) {
353 CHECK_EXPR(Literal, Bounds::Unbounded());
354 }
355 }
356 }
357 CHECK_TYPES_END
358 }
359
360
361 TEST(VisitYield) {
362 v8::V8::Initialize();
363 HandleAndZoneScope handles;
364 ZoneVector<ExpressionTypeEntry> types(handles.main_zone());
365 const char test_function[] =
366 "function* foo() {\n"
367 " yield 123;\n"
368 "}\n";
369 CollectTypes(&handles, test_function, &types);
370 CHECK_TYPES_BEGIN {
371 CHECK_EXPR(FunctionLiteral, Bounds::Unbounded()) {
372 // Implicit initial yield
373 CHECK_EXPR(Yield, Bounds::Unbounded()) {
374 CHECK_VAR(.generator_object, Bounds::Unbounded());
375 CHECK_EXPR(Assignment, Bounds::Unbounded()) {
376 CHECK_VAR(.generator_object, Bounds::Unbounded());
377 CHECK_EXPR(CallRuntime, Bounds::Unbounded()) {
378 CHECK_EXPR(ThisFunction, Bounds::Unbounded());
379 CHECK_EXPR(VariableProxy, Bounds::Unbounded());
380 }
381 }
382 }
383 // Explicit yield (argument wrapped with CreateIterResultObject)
384 CHECK_EXPR(Yield, Bounds::Unbounded()) {
385 CHECK_VAR(.generator_object, Bounds::Unbounded());
386 CHECK_EXPR(CallRuntime, Bounds::Unbounded()) {
387 CHECK_EXPR(Literal, Bounds::Unbounded());
388 CHECK_EXPR(Literal, Bounds::Unbounded());
389 }
390 }
391 // Argument to implicit final return
392 CHECK_EXPR(CallRuntime, Bounds::Unbounded()) { // CreateIterResultObject
393 CHECK_EXPR(Literal, Bounds::Unbounded());
394 CHECK_EXPR(Literal, Bounds::Unbounded());
395 }
396 // Implicit finally clause
397 CHECK_EXPR(CallRuntime, Bounds::Unbounded()) {
398 CHECK_VAR(.generator_object, Bounds::Unbounded());
399 }
400 }
401 }
402 CHECK_TYPES_END
403 }
404
405
406 TEST(VisitSkipping) {
407 v8::V8::Initialize();
408 HandleAndZoneScope handles;
409 ZoneVector<ExpressionTypeEntry> types(handles.main_zone());
410 const char test_function[] =
411 "function foo(x) {\n"
412 " return (x + x) + 1;\n"
413 "}\n";
414 CollectTypes(&handles, test_function, &types);
415 CHECK_TYPES_BEGIN {
416 CHECK_EXPR(FunctionLiteral, Bounds::Unbounded()) {
417 CHECK_EXPR(BinaryOperation, Bounds::Unbounded()) {
418 // Skip x + x
419 CHECK_SKIP();
420 CHECK_EXPR(Literal, Bounds::Unbounded());
421 }
422 }
423 }
424 CHECK_TYPES_END
425 }
OLDNEW
« no previous file with comments | « test/cctest/test-asm-validator.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698