OLD | NEW |
| (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 // VMOptions=--optimization_filter=doesNotExist | |
5 // ^Force code to be unoptimized so the invocation counts are accurate. | |
6 | |
7 library call_site_data_test; | |
8 | |
9 import 'package:observatory/service_io.dart'; | |
10 import 'package:unittest/unittest.dart'; | |
11 import 'test_helper.dart'; | |
12 | |
13 class A { foo() => 'A'; } | |
14 class B { foo() => 'B'; } | |
15 class C { foo() => 'C'; } | |
16 class D { foo() => 'D'; } | |
17 class E { foo() => 'E'; } | |
18 class F { foo() => 'F'; } | |
19 class G { foo() => 'G'; } | |
20 class H { foo() => 'H'; } | |
21 | |
22 monomorphic(fooable) { | |
23 fooable.foo(); | |
24 return null; | |
25 } | |
26 polymorphic(fooable) { | |
27 fooable.foo(); | |
28 return null; | |
29 } | |
30 megamorphic(fooable) { | |
31 fooable.foo(); | |
32 return null; | |
33 } | |
34 | |
35 class Static { | |
36 static staticMethod() => 2; | |
37 } | |
38 staticCall() { | |
39 Static.staticMethod(); | |
40 return null; | |
41 } | |
42 constructorCall() { | |
43 new Static(); | |
44 return null; | |
45 } | |
46 topLevelMethod() => "TOP"; | |
47 topLevelCall() { | |
48 topLevelMethod(); | |
49 return null; | |
50 } | |
51 | |
52 class Super { bar() => "Super"; } | |
53 class Sub extends Super { bar() => super.bar(); } | |
54 | |
55 script() { | |
56 for (int i = 0; i < 10; i++) monomorphic(new A()); | |
57 | |
58 for (int i = 0; i < 10; i++) polymorphic(new A()); | |
59 for (int i = 0; i < 20; i++) polymorphic(new B()); | |
60 for (int i = 0; i < 30; i++) polymorphic(new C()); | |
61 | |
62 for (int i = 0; i < 10; i++) megamorphic(new A()); | |
63 for (int i = 0; i < 20; i++) megamorphic(new B()); | |
64 for (int i = 0; i < 30; i++) megamorphic(new C()); | |
65 for (int i = 0; i < 40; i++) megamorphic(new D()); | |
66 for (int i = 0; i < 50; i++) megamorphic(new E()); | |
67 for (int i = 0; i < 60; i++) megamorphic(new F()); | |
68 for (int i = 0; i < 70; i++) megamorphic(new G()); | |
69 for (int i = 0; i < 80; i++) megamorphic(new H()); | |
70 | |
71 for (int i = 0; i < 10; i++) staticCall(); | |
72 | |
73 for (int i = 0; i < 10; i++) constructorCall(); | |
74 | |
75 for (int i = 0; i < 10; i++) topLevelCall(); | |
76 | |
77 for (int i = 0; i < 15; i++) new Sub().bar(); | |
78 } | |
79 | |
80 | |
81 Set<String> stringifyCacheEntries(Map callSite) { | |
82 return callSite['cacheEntries'].map((entry) { | |
83 return "${entry['receiverContainer']['name']}:${entry['count']}"; | |
84 }).toSet(); | |
85 } | |
86 | |
87 | |
88 testMonomorphic(Isolate isolate) async { | |
89 Library lib = await isolate.rootLibrary.load(); | |
90 ServiceFunction func = | |
91 lib.functions.singleWhere((f) => f.name == 'monomorphic'); | |
92 Map response = await isolate.invokeRpcNoUpgrade('_getCallSiteData', | |
93 { 'targetId': func.id }); | |
94 expect(response['type'], equals('CodeCoverage')); | |
95 Map callSite = response['coverage'].single['callSites'].single; | |
96 expect(callSite['name'], equals('foo')); | |
97 expect(stringifyCacheEntries(callSite), | |
98 equals(['A:10'].toSet())); | |
99 } | |
100 | |
101 testPolymorphic(Isolate isolate) async { | |
102 Library lib = await isolate.rootLibrary.load(); | |
103 ServiceFunction func = | |
104 lib.functions.singleWhere((f) => f.name == 'polymorphic'); | |
105 Map response = await isolate.invokeRpcNoUpgrade('_getCallSiteData', | |
106 { 'targetId': func.id }); | |
107 expect(response['type'], equals('CodeCoverage')); | |
108 Map callSite = response['coverage'].single['callSites'].single; | |
109 expect(callSite['name'], equals('foo')); | |
110 expect(stringifyCacheEntries(callSite), | |
111 equals(['A:10', 'B:20', 'C:30'].toSet())); | |
112 } | |
113 | |
114 testMegamorphic(Isolate isolate) async { | |
115 Library lib = await isolate.rootLibrary.load(); | |
116 ServiceFunction func = | |
117 lib.functions.singleWhere((f) => f.name == 'megamorphic'); | |
118 Map response = await isolate.invokeRpcNoUpgrade('_getCallSiteData', | |
119 { 'targetId': func.id }); | |
120 expect(response['type'], equals('CodeCoverage')); | |
121 Map callSite = response['coverage'].single['callSites'].single; | |
122 expect(callSite['name'], equals('foo')); | |
123 expect(stringifyCacheEntries(callSite), | |
124 equals(['A:10', 'B:20', 'C:30', 'D:40', | |
125 'E:50', 'F:60', 'G:70', 'H:80'].toSet())); | |
126 } | |
127 | |
128 testStaticCall(Isolate isolate) async { | |
129 Library lib = await isolate.rootLibrary.load(); | |
130 ServiceFunction func = | |
131 lib.functions.singleWhere((f) => f.name == 'staticCall'); | |
132 Map response = await isolate.invokeRpcNoUpgrade('_getCallSiteData', | |
133 { 'targetId': func.id }); | |
134 expect(response['type'], equals('CodeCoverage')); | |
135 Map callSite = response['coverage'].single['callSites'].single; | |
136 expect(callSite['name'], equals('staticMethod')); | |
137 expect(stringifyCacheEntries(callSite), | |
138 equals(['Static:10'].toSet())); | |
139 } | |
140 | |
141 testConstructorCall(Isolate isolate) async { | |
142 Library lib = await isolate.rootLibrary.load(); | |
143 ServiceFunction func = | |
144 lib.functions.singleWhere((f) => f.name == 'constructorCall'); | |
145 Map response = await isolate.invokeRpcNoUpgrade('_getCallSiteData', | |
146 { 'targetId': func.id }); | |
147 expect(response['type'], equals('CodeCoverage')); | |
148 Map callSite = response['coverage'].single['callSites'].single; | |
149 expect(callSite['name'], equals('Static.')); | |
150 expect(stringifyCacheEntries(callSite), | |
151 equals(['Static:10'].toSet())); | |
152 } | |
153 | |
154 testTopLevelCall(Isolate isolate) async { | |
155 Library lib = await isolate.rootLibrary.load(); | |
156 ServiceFunction func = | |
157 lib.functions.singleWhere((f) => f.name == 'topLevelCall'); | |
158 Map response = await isolate.invokeRpcNoUpgrade('_getCallSiteData', | |
159 { 'targetId': func.id }); | |
160 expect(response['type'], equals('CodeCoverage')); | |
161 Map callSite = response['coverage'].single['callSites'].single; | |
162 expect(callSite['name'], equals('topLevelMethod')); | |
163 expect(stringifyCacheEntries(callSite), | |
164 equals(['call_site_data_test:10'].toSet())); | |
165 } | |
166 | |
167 testSuperCall(Isolate isolate) async { | |
168 Library lib = await isolate.rootLibrary.load(); | |
169 Class cls = await lib.classes.singleWhere((f) => f.name == 'Sub').load(); | |
170 ServiceFunction func = cls.functions.singleWhere((f) => f.name == 'bar'); | |
171 Map response = await isolate.invokeRpcNoUpgrade('_getCallSiteData', | |
172 { 'targetId': func.id }); | |
173 expect(response['type'], equals('CodeCoverage')); | |
174 Map callSite = response['coverage'].single['callSites'].single; | |
175 expect(callSite['name'], equals('bar')); | |
176 expect(stringifyCacheEntries(callSite), | |
177 equals(['Super:15'].toSet())); | |
178 } | |
179 | |
180 var tests = [ | |
181 testMonomorphic, | |
182 testPolymorphic, | |
183 testMegamorphic, | |
184 testStaticCall, | |
185 testConstructorCall, | |
186 testTopLevelCall, | |
187 testSuperCall ]; | |
188 | |
189 main(args) => runIsolateTests(args, tests, testeeBefore: script); | |
OLD | NEW |