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

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, 2 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 | « tests/compiler/dart2js/dump_info_test.dart ('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
(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 // SharedOptions=-Dsend_stats=true
5
6 /// Tests that we compute send metrics correctly in many simple scenarios.
7 library dart2js.test.send_measurements_test;
8
9 import 'dart:async';
10 import 'package:test/test.dart';
11 import 'package:dart2js_info/info.dart';
12 import 'memory_compiler.dart';
13 import 'dart:io';
14
15 main() {
16 test('nothing is reachable, nothing to count', () {
17 return _check('''
18 main() {}
19 test() { int x = 3; }
20 ''');
21 });
22
23 test('local variable read', () {
24 return _check('''
25 main() => test();
26 test() { int x = 3; int y = x; }
27 ''',
28 localSend: 1); // from `int y = x`;
29 });
30
31 test('generative constructor call', () {
32 return _check('''
33 class A {
34 get f => 1;
35 }
36 main() => test();
37 test() { new A(); }
38 ''',
39 constructorSend: 1); // from new A()
40 });
41
42 group('instance call', () {
43 test('monomorphic only one implementor', () {
44 return _check('''
45 class A {
46 get f => 1;
47 }
48 main() => test();
49 test() { new A().f; }
50 ''',
51 constructorSend: 1, // new A()
52 instanceSend: 1); // f resolved to A.f
53 });
54
55 test('monomorphic only one type possible from types', () {
56 return _check('''
57 class A {
58 get f => 1;
59 }
60 class B extends A {
61 get f => 1;
62 }
63 main() => test();
64 test() { new B().f; }
65 ''',
66 constructorSend: 1,
67 instanceSend: 1); // f resolved to B.f
68 });
69
70 test('monomorphic only one type possible from liveness', () {
71 return _check('''
72 class A {
73 get f => 1;
74 }
75 class B extends A {
76 get f => 1;
77 }
78 main() => test();
79 test() { A x = new B(); x.f; }
80 ''',
81 constructorSend: 1, // new B()
82 localSend: 1, // x in x.f
83 instanceSend: 1); // x.f known to resolve to B.f
84 });
85
86 test('monomorphic one possible, more than one live', () {
87 return _check('''
88 class A {
89 get f => 1;
90 }
91 class B extends A {
92 get f => 1;
93 }
94 main() { new A(); test(); }
95 test() { B x = new B(); x.f; }
96 ''',
97 constructorSend: 1, // new B()
98 localSend: 1, // x in x.f
99 instanceSend: 1); // x.f resolves to B.f
100 });
101
102 test('polymorphic-virtual couple possible types from liveness', () {
103 // Note: this would be an instanceSend if we used the inferrer.
104 return _check('''
105 class A {
106 get f => 1;
107 }
108 class B extends A {
109 get f => 1;
110 }
111 main() { new A(); test(); }
112 test() { A x = new B(); x.f; }
113 ''',
114 constructorSend: 1, // new B()
115 localSend: 1, // x in x.f
116 virtualSend: 1); // x.f may be A.f or B.f (types alone is not enough)
117 });
118
119 test("polymorphic-dynamic: type annotations don't help", () {
120 return _check('''
121 class A {
122 get f => 1;
123 }
124 class B extends A {
125 get f => 1;
126 }
127 main() { new A(); test(); }
128 test() { var x = new B(); x.f; }
129 ''',
130 constructorSend: 1, // new B()
131 localSend: 1, // x in x.f
132 dynamicSend: 1); // x.f could be any `f` or no `f`
133 });
134 });
135
136 group('instance this call', () {
137 test('monomorphic only one implementor', () {
138 return _check('''
139 class A {
140 get f => 1;
141 test() => this.f;
142 }
143 main() => new A().test();
144 ''',
145 instanceSend: 1); // this.f resolved to A.f
146 });
147
148 test('monomorphic only one type possible from types & liveness', () {
149 return _check('''
150 class A {
151 get f => 1;
152 test() => this.f;
153 }
154 class B extends A {
155 get f => 1;
156 }
157 main() => new B().test();
158 ''',
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 virtualSend: 1); // this.f may be A.f or B.f
175 });
176 });
177
178 group('noSuchMethod', () {
179 test('error will be thrown', () {
180 return _check('''
181 class A {
182 }
183 main() { test(); }
184 test() { new A().f; }
185 ''',
186 constructorSend: 1, // new B()
187 nsmErrorSend: 1); // f not there, A has no nSM
188 });
189
190 test('nSM will be called - one option', () {
191 return _check('''
192 class A {
193 noSuchMethod(i) => null;
194 }
195 main() { test(); }
196 test() { new A().f; }
197 ''',
198 constructorSend: 1, // new B()
199 singleNsmCallSend: 1); // f not there, A has nSM
200 });
201
202 // TODO(sigmund): is it worth splitting multiNSMvirtual?
203 test('nSM will be called - multiple options', () {
204 return _check('''
205 class A {
206 noSuchMethod(i) => null;
207 }
208 class B extends A {
209 noSuchMethod(i) => null;
210 }
211 main() { new A(); test(); }
212 test() { A x = new B(); x.f; }
213 ''',
214 constructorSend: 1, // new B()
215 localSend: 1, // x in x.f
216 multiNsmCallSend: 1); // f not there, A has nSM
217 });
218
219 // TODO(sigmund): is it worth splitting multiNSMvirtual?
220 test('nSM will be called - multiple options', () {
221 return _check('''
222 class A {
223 noSuchMethod(i) => null;
224 }
225 class B extends A {
226 // don't count A's nsm as distinct
227 }
228 main() { new A(); test(); }
229 test() { A x = new B(); x.f; }
230 ''',
231 constructorSend: 1, // new B()
232 localSend: 1, // x in x.f
233 singleNsmCallSend: 1); // f not there, A has nSM
234 });
235
236 test('nSM will be called - multiple options', () {
237 return _check('''
238 class A {
239 noSuchMethod(i) => null;
240 }
241 class B extends A {
242 get f => null;
243 }
244 main() { new A(); test(); }
245 test() { A x = new B(); x.f; }
246 ''',
247 constructorSend: 1, // new B()
248 localSend: 1, // x in x.f
249 dynamicSend: 1); // f not known to be there there, A has nSM
250 });
251
252 test('nSM in super', () {
253 return _check('''
254 class A {
255 noSuchMethod(i) => null;
256 }
257 class B extends A {
258 get f => super.f;
259 }
260 main() { new A(); test(); }
261 test() { A x = new B(); x.f; }
262 ''',
263 singleNsmCallSend: 1, // super.f
264 testMethod: 'f');
265 });
266 });
267 }
268
269
270 /// Checks that the `test` function in [code] produces the given distribution of
271 /// sends.
272 _check(String code, {int staticSend: 0, int superSend: 0, int localSend: 0,
273 int constructorSend: 0, int typeVariableSend: 0, int nsmErrorSend: 0,
274 int singleNsmCallSend: 0, int instanceSend: 0, int interceptorSend: 0,
275 int multiNsmCallSend: 0, int virtualSend: 0, int multiInterceptorSend: 0,
276 int dynamicSend: 0, String testMethod: 'test'}) async {
277
278 // Set up the expectation.
279 var expected = new Measurements();
280 int monomorphic = staticSend + superSend + localSend + constructorSend +
281 typeVariableSend + nsmErrorSend + singleNsmCallSend + instanceSend +
282 interceptorSend;
283 int polymorphic = multiNsmCallSend + virtualSend + multiInterceptorSend +
284 dynamicSend;
285
286 expected.counters[Metric.monomorphicSend] = monomorphic;
287 expected.counters[Metric.staticSend] = staticSend;
288 expected.counters[Metric.superSend] = superSend;
289 expected.counters[Metric.localSend] = localSend;
290 expected.counters[Metric.constructorSend] = constructorSend;
291 expected.counters[Metric.typeVariableSend] = typeVariableSend;
292 expected.counters[Metric.nsmErrorSend] = nsmErrorSend;
293 expected.counters[Metric.singleNsmCallSend] = singleNsmCallSend;
294 expected.counters[Metric.instanceSend] = instanceSend;
295 expected.counters[Metric.interceptorSend] = interceptorSend;
296
297 expected.counters[Metric.polymorphicSend] = polymorphic;
298 expected.counters[Metric.multiNsmCallSend] = multiNsmCallSend;
299 expected.counters[Metric.virtualSend] = virtualSend;
300 expected.counters[Metric.multiInterceptorSend] = multiInterceptorSend;
301 expected.counters[Metric.dynamicSend] = dynamicSend;
302
303 expected.counters[Metric.send] = monomorphic + polymorphic;
304
305 // Run the compiler to get the results.
306 var all = await _compileAndGetStats(code);
307 var function = all.functions.firstWhere((f) => f.name == testMethod,
308 orElse: () => null);
309 var result = function?.measurements;
310 if (function == null) {
311 expect(expected.counters[Metric.send], 0);
312 return;
313 }
314
315 expect(result, isNotNull);
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 /// Helper that runs the compiler and returns the [GlobalResult] computed for
333 /// it.
334 Future<AllInfo> _compileAndGetStats(String program) async {
335 var result = await runCompiler(
336 memorySourceFiles: {'main.dart': program}, options: ['--dump-info']);
337 expect(result.compiler.compilationFailed, isFalse);
338 return result.compiler.dumpInfoTask.infoCollector.result;
339 }
OLDNEW
« no previous file with comments | « tests/compiler/dart2js/dump_info_test.dart ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698