OLD | NEW |
| (Empty) |
1 // Copyright (c) 2013, 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 // Test allocation sinking optimization. | |
5 // VMOptions=--optimization-counter-threshold=10 --no-use-osr --no-background-co
mpilation | |
6 | |
7 import 'dart:typed_data'; | |
8 import 'package:expect/expect.dart'; | |
9 | |
10 class Point { | |
11 var x, y; | |
12 | |
13 Point(this.x, this.y); | |
14 | |
15 operator *(other) { | |
16 return x * other.x + y * other.y; | |
17 } | |
18 } | |
19 | |
20 class C { | |
21 var p; | |
22 C(this.p); | |
23 } | |
24 | |
25 class Pointx4 { | |
26 var x, y; | |
27 | |
28 Pointx4(this.x, this.y); | |
29 | |
30 operator *(other) { | |
31 return x * other.x + y * other.y; | |
32 } | |
33 } | |
34 | |
35 class Cx4 { | |
36 var p; | |
37 Cx4(this.p); | |
38 } | |
39 | |
40 class D { | |
41 var p; | |
42 D(this.p); | |
43 } | |
44 | |
45 // Class that is used to capture materialized Point object with * operator. | |
46 class F { | |
47 var p; | |
48 var val; | |
49 | |
50 F(this.p); | |
51 | |
52 operator *(other) { | |
53 Expect.isTrue(other is Point); | |
54 Expect.equals(42.0, other.x); | |
55 Expect.equals(0.5, other.y); | |
56 | |
57 if (val == null) { | |
58 val = other; | |
59 } else { | |
60 Expect.isTrue(identical(val, other)); | |
61 } | |
62 | |
63 return this.p * other; | |
64 } | |
65 } | |
66 | |
67 test1(c, x, y) { | |
68 var a = new Point(x - 0.5, y + 0.5); | |
69 var b = new Point(x + 0.5, y + 0.8); | |
70 var d = new Point(c.p * a, c.p * b); | |
71 return d * d; | |
72 } | |
73 | |
74 test1x4(c, x, y, z, w) { | |
75 var a = new Pointx4(x - z, y + w); | |
76 var b = new Pointx4(x + w, y + z); | |
77 var d = new Pointx4(c.p * a, c.p * b); | |
78 return d * d; | |
79 } | |
80 | |
81 effects() { | |
82 // This function should not be inlinable. | |
83 try {} catch (e) {} | |
84 } | |
85 | |
86 testForwardingThroughEffects(c, x, y) { | |
87 var a = new Point(x - 0.5, y + 0.5); | |
88 var b = new Point(x - 0.5, y - 0.8); | |
89 var d = new Point(c.p * a, c.p * b); | |
90 // Effects can't affect neither a, b, nor d because they do not escape. | |
91 effects(); | |
92 effects(); | |
93 return ((a == null) ? 0.0 : 0.1) + (d * d); | |
94 } | |
95 | |
96 testIdentity(x) { | |
97 var y = new Point(42.0, 0.5); | |
98 var z = y; | |
99 return x * y + x * z; | |
100 } | |
101 | |
102 class PointP<T> { | |
103 var x, y; | |
104 | |
105 PointP(this.x, this.y); | |
106 | |
107 operator *(other) { | |
108 return x * other.x + y * other.y; | |
109 } | |
110 } | |
111 | |
112 foo2() => new PointP<int>(1, 3) * new PointP<num>(5, 6); | |
113 | |
114 class A<T> { | |
115 var x, y; | |
116 } | |
117 | |
118 foo3(x) { | |
119 // Test materialization of type arguments. | |
120 var a = new A<int>(); | |
121 a.x = x; | |
122 a.y = x; | |
123 if (x is int) return a.x + a.y; | |
124 Expect.isFalse(a is A<double>); | |
125 Expect.isTrue(a is A<int>); | |
126 Expect.isTrue(a is A); | |
127 return a.x - a.y; | |
128 } | |
129 | |
130 class WithFinal { | |
131 final _x; | |
132 WithFinal(this._x); | |
133 } | |
134 | |
135 testInitialValueForFinalField(x) { | |
136 new WithFinal(x); | |
137 } | |
138 | |
139 testFinalField() { | |
140 for (var i = 0; i < 100; i++) { | |
141 testInitialValueForFinalField(1); | |
142 } | |
143 } | |
144 | |
145 class V { | |
146 var x = 0; | |
147 } | |
148 | |
149 test_vm_field() { | |
150 var obj; | |
151 inner() => obj.x = 42; | |
152 var a = new V(); | |
153 obj = a; | |
154 var t1 = a.x; | |
155 var t2 = inner(); | |
156 return a.x + t1 + t2; | |
157 } | |
158 | |
159 testVMField() { | |
160 Expect.equals(84, test_vm_field()); | |
161 for (var i = 0; i < 100; i++) test_vm_field(); | |
162 Expect.equals(84, test_vm_field()); | |
163 } | |
164 | |
165 class CompoundA { | |
166 var b; | |
167 CompoundA(this.b); | |
168 } | |
169 | |
170 class CompoundB { | |
171 var c; | |
172 CompoundB(this.c); | |
173 } | |
174 | |
175 class CompoundC { | |
176 var d; | |
177 var root; | |
178 CompoundC(this.d); | |
179 } | |
180 | |
181 class NoopSink { | |
182 const NoopSink(); | |
183 call(val) {} | |
184 } | |
185 | |
186 testCompound1() { | |
187 f(d, [sink = const NoopSink()]) { | |
188 var c = new CompoundC(d); | |
189 var a = new CompoundA(new CompoundB(c)); | |
190 sink(a); | |
191 return c.d; | |
192 } | |
193 | |
194 Expect.equals(0.1, f(0.1)); | |
195 for (var i = 0; i < 100; i++) f(0.1); | |
196 Expect.equals(0.1, f(0.1)); | |
197 Expect.equals( | |
198 0.1, | |
199 f(0.1, (val) { | |
200 Expect.isTrue(val is CompoundA); | |
201 Expect.isTrue(val.b is CompoundB); | |
202 Expect.isTrue(val.b.c is CompoundC); | |
203 Expect.isNull(val.b.c.root); | |
204 Expect.equals(0.1, val.b.c.d); | |
205 })); | |
206 } | |
207 | |
208 testCompound2() { | |
209 f(d, [sink = const NoopSink()]) { | |
210 var c = new CompoundC(d); | |
211 var a = new CompoundA(new CompoundB(c)); | |
212 c.root = a; | |
213 sink(a); | |
214 return c.d; | |
215 } | |
216 | |
217 Expect.equals(0.1, f(0.1)); | |
218 for (var i = 0; i < 100; i++) f(0.1); | |
219 Expect.equals(0.1, f(0.1)); | |
220 Expect.equals( | |
221 0.1, | |
222 f(0.1, (val) { | |
223 Expect.isTrue(val is CompoundA); | |
224 Expect.isTrue(val.b is CompoundB); | |
225 Expect.isTrue(val.b.c is CompoundC); | |
226 Expect.equals(val, val.b.c.root); | |
227 Expect.equals(0.1, val.b.c.d); | |
228 })); | |
229 } | |
230 | |
231 testCompound3() { | |
232 f(d, [sink = const NoopSink()]) { | |
233 var c = new CompoundC(d); | |
234 c.root = c; | |
235 sink(c); | |
236 return c.d; | |
237 } | |
238 | |
239 Expect.equals(0.1, f(0.1)); | |
240 for (var i = 0; i < 100; i++) f(0.1); | |
241 Expect.equals(0.1, f(0.1)); | |
242 Expect.equals( | |
243 0.1, | |
244 f(0.1, (val) { | |
245 Expect.isTrue(val is CompoundC); | |
246 Expect.equals(val, val.root); | |
247 Expect.equals(0.1, val.d); | |
248 })); | |
249 } | |
250 | |
251 testCompound4() { | |
252 f(d, [sink = const NoopSink()]) { | |
253 var c = new CompoundC(d); | |
254 c.root = c; | |
255 for (var i = 0; i < 10; i++) { | |
256 c.d += 1.0; | |
257 } | |
258 sink(c); | |
259 return c.d - 1.0 * 10; | |
260 } | |
261 | |
262 Expect.equals(1.0, f(1.0)); | |
263 for (var i = 0; i < 100; i++) f(1.0); | |
264 Expect.equals(1.0, f(1.0)); | |
265 Expect.equals( | |
266 1.0, | |
267 f(1.0, (val) { | |
268 Expect.isTrue(val is CompoundC); | |
269 Expect.equals(val, val.root); | |
270 Expect.equals(11.0, val.d); | |
271 })); | |
272 } | |
273 | |
274 main() { | |
275 var c = new C(new Point(0.1, 0.2)); | |
276 | |
277 // Compute initial values. | |
278 final x0 = test1(c, 11.11, 22.22); | |
279 var fc = new Cx4(new Pointx4( | |
280 new Float32x4(1.0, 1.0, 1.0, 1.0), new Float32x4(1.0, 1.0, 1.0, 1.0))); | |
281 final fx0 = test1x4( | |
282 fc, | |
283 new Float32x4(1.0, 1.0, 1.0, 1.0), | |
284 new Float32x4(1.0, 1.0, 1.0, 1.0), | |
285 new Float32x4(1.0, 1.0, 1.0, 1.0), | |
286 new Float32x4(1.0, 1.0, 1.0, 1.0)); | |
287 final y0 = testForwardingThroughEffects(c, 11.11, 22.22); | |
288 final z0 = testIdentity(c.p); | |
289 | |
290 // Force optimization. | |
291 for (var i = 0; i < 100; i++) { | |
292 test1(c, i.toDouble(), i.toDouble()); | |
293 test1x4( | |
294 fc, | |
295 new Float32x4(1.0, 1.0, 1.0, 1.0), | |
296 new Float32x4(1.0, 1.0, 1.0, 1.0), | |
297 new Float32x4(1.0, 1.0, 1.0, 1.0), | |
298 new Float32x4(1.0, 1.0, 1.0, 1.0)); | |
299 testForwardingThroughEffects(c, i.toDouble(), i.toDouble()); | |
300 testIdentity(c.p); | |
301 foo2(); | |
302 Expect.equals(10, foo3(5)); | |
303 } | |
304 Expect.equals(0.0, foo3(0.5)); | |
305 | |
306 // Test returned value after optimization. | |
307 final x1 = test1(c, 11.11, 22.22); | |
308 final y1 = testForwardingThroughEffects(c, 11.11, 22.22); | |
309 | |
310 // Test returned value after deopt. | |
311 final x2 = test1(new D(c.p), 11.11, 22.22); | |
312 final y2 = testForwardingThroughEffects(new D(c.p), 11.11, 22.22); | |
313 | |
314 Expect.equals(6465, (x0 * 100).floor()); | |
315 Expect.equals(6465, (x1 * 100).floor()); | |
316 Expect.equals(6465, (x2 * 100).floor()); | |
317 Expect.equals(x0, x1); | |
318 Expect.equals(x0, x2); | |
319 | |
320 Expect.equals(6008, (y0 * 100).floor()); | |
321 Expect.equals(6008, (y1 * 100).floor()); | |
322 Expect.equals(6008, (y2 * 100).floor()); | |
323 Expect.equals(y0, y1); | |
324 Expect.equals(y0, y2); | |
325 | |
326 // Test that identity of materialized objects is preserved correctly and | |
327 // no copies are materialized. | |
328 final z1 = testIdentity(c.p); | |
329 final z2 = testIdentity(new F(c.p)); | |
330 Expect.equals(z0, z1); | |
331 Expect.equals(z0, z2); | |
332 | |
333 testFinalField(); | |
334 testVMField(); | |
335 testCompound1(); | |
336 testCompound2(); | |
337 testCompound3(); | |
338 testCompound4(); | |
339 } | |
OLD | NEW |