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

Side by Side Diff: tests/compiler/dart2js/inference_stats_test.dart

Issue 1220043005: dart2js send stats, includes: (Closed) Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: Created 5 years, 5 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
OLDNEW
(Empty)
1 // Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a
3 // BSD-style license that can be found in the LICENSE file.
4
5 /// Tests that we compute send metrics correctly in many simple scenarios.
6 library stats_test;
7
8 import 'dart:async';
9 import 'package:test/test.dart';
10 import 'package:compiler/src/stats/stats.dart';
11 import 'compiler_helper.dart';
12
13 main() {
14 test('nothing is reachable, nothing to count', () {
15 return _check('''
16 main() {}
17 test() { int x = 3; }
18 ''');
19 });
20
21 test('local variable read', () {
22 return _check('''
23 main() => test();
24 test() { int x = 3; int y = x; }
25 ''',
26 localSend: 1); // from `int y = x`;
27 });
28
29 test('generative constructor call', () {
30 return _check('''
31 class A {
32 get f => 1;
33 }
34 main() => test();
35 test() { new A(); }
36 ''',
37 constructorSend: 1); // from new A()
38 });
39
40 group('instance call', () {
41 test('monomorphic only one implementor', () {
42 return _check('''
43 class A {
44 get f => 1;
45 }
46 main() => test();
47 test() { new A().f; }
48 ''',
49 constructorSend: 1, // new A()
50 instanceSend: 1); // f resolved to A.f
51 });
52
53 test('monomorphic only one type possible from types', () {
54 return _check('''
55 class A {
56 get f => 1;
57 }
58 class B extends A {
59 get f => 1;
60 }
61 main() => test();
62 test() { new B().f; }
63 ''',
64 constructorSend: 1,
65 instanceSend: 1); // f resolved to B.f
66 });
67
68 test('monomorphic only one type possible from liveness', () {
69 return _check('''
70 class A {
71 get f => 1;
72 }
73 class B extends A {
74 get f => 1;
75 }
76 main() => test();
77 test() { A x = new B(); x.f; }
78 ''',
79 constructorSend: 1, // new B()
80 localSend: 1, // x in x.f
81 instanceSend: 1); // x.f known to resolve to B.f
82 });
83
84 test('monomorphic one possible, more than one live', () {
85 return _check('''
86 class A {
87 get f => 1;
88 }
89 class B extends A {
90 get f => 1;
91 }
92 main() { new A(); test(); }
93 test() { B x = new B(); x.f; }
94 ''',
95 constructorSend: 1, // new B()
96 localSend: 1, // x in x.f
97 instanceSend: 1); // x.f resolves to B.f
98 });
99
100 test('polymorphic-virtual couple possible types from liveness', () {
101 // Note: this would be an instanceSend if we used the inferrer.
102 return _check('''
103 class A {
104 get f => 1;
105 }
106 class B extends A {
107 get f => 1;
108 }
109 main() { new A(); test(); }
110 test() { A x = new B(); x.f; }
111 ''',
112 constructorSend: 1, // new B()
113 localSend: 1, // x in x.f
114 virtualSend: 1); // x.f may be A.f or B.f (types alone is not enough)
115 });
116
117 test("polymorphic-dynamic: type annotations don't help", () {
118 return _check('''
119 class A {
120 get f => 1;
121 }
122 class B extends A {
123 get f => 1;
124 }
125 main() { new A(); test(); }
126 test() { var x = new B(); x.f; }
127 ''',
128 constructorSend: 1, // new B()
129 localSend: 1, // x in x.f
130 dynamicSend: 1); // x.f could be any `f` or no `f`
131 });
132 });
133
134 group('instance this call', () {
135 test('monomorphic only one implementor', () {
136 return _check('''
137 class A {
138 get f => 1;
139 test() => this.f;
140 }
141 main() => new A().test();
142 ''',
143 testMethod: 'A.test',
144 instanceSend: 1); // this.f resolved to A.f
145 });
146
147 test('monomorphic only one type possible from types & liveness', () {
148 return _check('''
149 class A {
150 get f => 1;
151 test() => this.f;
152 }
153 class B extends A {
154 get f => 1;
155 }
156 main() => new B().test();
157 ''',
158 testMethod: 'A.test',
159 instanceSend: 1); // this.f resolved to B.f
160 });
161
162 test('polymorphic-virtual couple possible types from liveness', () {
163 // Note: this would be an instanceSend if we used the inferrer.
164 return _check('''
165 class A {
166 get f => 1;
167 test() => this.f;
168 }
169 class B extends A {
170 get f => 1;
171 }
172 main() { new A(); new B().test(); }
173 ''',
174 testMethod: 'A.test',
175 virtualSend: 1); // this.f may be A.f or B.f
176 });
177 });
178
179 group('noSuchMethod', () {
180 test('error will be thrown', () {
181 return _check('''
182 class A {
183 }
184 main() { test(); }
185 test() { new A().f; }
186 ''',
187 constructorSend: 1, // new B()
188 nsmErrorSend: 1); // f not there, A has no nSM
189 });
190
191 test('nSM will be called - one option', () {
192 return _check('''
193 class A {
194 noSuchMethod(i) => null;
195 }
196 main() { test(); }
197 test() { new A().f; }
198 ''',
199 constructorSend: 1, // new B()
200 singleNsmCallSend: 1); // f not there, A has nSM
201 });
202
203 // TODO(sigmund): is it worth splitting multiNSMvirtual?
204 test('nSM will be called - multiple options', () {
205 return _check('''
206 class A {
207 noSuchMethod(i) => null;
208 }
209 class B extends A {
210 noSuchMethod(i) => null;
211 }
212 main() { new A(); test(); }
213 test() { A x = new B(); x.f; }
214 ''',
215 constructorSend: 1, // new B()
216 localSend: 1, // x in x.f
217 multiNsmCallSend: 1); // f not there, A has nSM
218 });
219
220 // TODO(sigmund): is it worth splitting multiNSMvirtual?
221 test('nSM will be called - multiple options', () {
222 return _check('''
223 class A {
224 noSuchMethod(i) => null;
225 }
226 class B extends A {
227 // don't count A's nsm as distinct
228 }
229 main() { new A(); test(); }
230 test() { A x = new B(); x.f; }
231 ''',
232 constructorSend: 1, // new B()
233 localSend: 1, // x in x.f
234 singleNsmCallSend: 1); // f not there, A has nSM
235 });
236
237 test('nSM will be called - multiple options', () {
238 return _check('''
239 class A {
240 noSuchMethod(i) => null;
241 }
242 class B extends A {
243 get f => null;
244 }
245 main() { new A(); test(); }
246 test() { A x = new B(); x.f; }
247 ''',
248 constructorSend: 1, // new B()
249 localSend: 1, // x in x.f
250 dynamicSend: 1); // f not known to be there there, A has nSM
251 });
252
253 test('nSM in super', () {
254 return _check('''
255 class A {
256 noSuchMethod(i) => null;
257 }
258 class B extends A {
259 get f => super.f;
260 }
261 main() { new A(); test(); }
262 test() { A x = new B(); x.f; }
263 ''',
264 singleNsmCallSend: 1, // super.f
265 testMethod: 'B.f');
266 });
267 });
268 }
269
270
271 /// Checks that the `test` function in [code] produces the given distribution of
272 /// sends.
273 _check(String code, {int staticSend: 0, int superSend: 0, int localSend: 0,
274 int constructorSend: 0, int typeVariableSend: 0, int nsmErrorSend: 0,
275 int singleNsmCallSend: 0, int instanceSend: 0, int interceptorSend: 0,
276 int multiNsmCallSend: 0, int virtualSend: 0, int multiInterceptorSend: 0,
277 int dynamicSend: 0, String testMethod: 'test'}) async {
278
279 // Set up the expectation.
280 var expected = new Measurements();
281 int monomorphic = staticSend + superSend + localSend + constructorSend +
282 typeVariableSend + nsmErrorSend + singleNsmCallSend + instanceSend +
283 interceptorSend;
284 int polymorphic = multiNsmCallSend + virtualSend + multiInterceptorSend +
285 dynamicSend;
286
287 expected.counters[Metric.monomorphicSend] = monomorphic;
288 expected.counters[Metric.staticSend] = staticSend;
289 expected.counters[Metric.superSend] = superSend;
290 expected.counters[Metric.localSend] = localSend;
291 expected.counters[Metric.constructorSend] = constructorSend;
292 expected.counters[Metric.typeVariableSend] = typeVariableSend;
293 expected.counters[Metric.nsmErrorSend] = nsmErrorSend;
294 expected.counters[Metric.singleNsmCallSend] = singleNsmCallSend;
295 expected.counters[Metric.instanceSend] = instanceSend;
296 expected.counters[Metric.interceptorSend] = interceptorSend;
297
298 expected.counters[Metric.polymorphicSend] = polymorphic;
299 expected.counters[Metric.multiNsmCallSend] = multiNsmCallSend;
300 expected.counters[Metric.virtualSend] = virtualSend;
301 expected.counters[Metric.multiInterceptorSend] = multiInterceptorSend;
302 expected.counters[Metric.dynamicSend] = dynamicSend;
303
304 expected.counters[Metric.send] = monomorphic + polymorphic;
305
306 // Run the compiler to get the results.
307 var globalResult = await _compileAndGetStats(code);
308 var libs = globalResult.loose.libraries;
309 var lib = libs.firstWhere((l) => l.uri == testFileUri,
310 orElse: () => fail("Cannot find the tested library."));
311 var functions = lib.units.expand((u) => u.functions);
312 var function = functions.firstWhere((f) => f.name == testMethod,
313 orElse: () => fail("Cannot find function named '$testMethod'"
314 " in ${functions.map((f) => f.name)}."));
315 var result = function.measurements;
316
317 _compareMetric(Metric key) {
318 var expectedValue = expected.counters[key];
319 var value = result.counters[key];
320 if (value == null) value = 0;
321 if (value == expectedValue) return;
322 expect(expectedValue, value,
323 reason: "count for `$key` didn't match:\n"
324 "expected measurements:\n${recursiveDiagnosticString(expected, key)}\n"
325 "actual measurements:\n${recursiveDiagnosticString(result, key)}");
326 }
327
328 _compareMetric(Metric.send);
329 expected.counters.keys.forEach(_compareMetric);
330 }
331
332 Uri testFileUri = new Uri(scheme: 'source');
333
334 /// Helper that runs the compiler and returns the [GlobalResult] computed for
335 /// it.
336 Future<GlobalResult> _compileAndGetStats(String code) async {
337 MockCompiler compiler = new MockCompiler.internal(computeAnalysisStats: true);
338 compiler.stopAfterTypeInference = true;
339 compiler.registerSource(testFileUri, code);
340 compiler.diagnosticHandler = createHandler(compiler, code);
341 await compiler.runCompiler(testFileUri);
342 expect(compiler.compilationFailed, false,
343 reason: 'Unexpected compilation error(s): ${compiler.errors}');
344 return compiler.statsBuilderTask.resultForTesting;
345 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698