OLD | NEW |
1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file | 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 | 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. | 3 // BSD-style license that can be found in the LICENSE file. |
4 | 4 |
5 // This unit test of dart2js checks that a SSA bailout target | 5 // This unit test of dart2js checks that a SSA bailout target |
6 // instruction gets removed from the graph when it's not used. | 6 // instruction gets removed from the graph when it's not used. |
7 | 7 |
8 import "package:expect/expect.dart"; | 8 import "package:expect/expect.dart"; |
| 9 import "../../async_helper.dart"; |
9 import 'compiler_helper.dart'; | 10 import 'compiler_helper.dart'; |
10 | 11 |
11 String TEST = r''' | 12 String TEST = r''' |
12 main() { | 13 main() { |
13 foo(1); | 14 foo(1); |
14 foo([]); | 15 foo([]); |
15 } | 16 } |
16 | 17 |
17 class A { | 18 class A { |
18 operator -() => this; | 19 operator -() => this; |
19 } | 20 } |
20 | 21 |
21 foo(a) { | 22 foo(a) { |
22 new A(); // Force having another operator- | 23 new A(); // Force having another operator- |
23 // Make the method recursive to always enable bailouts | 24 // Make the method recursive to always enable bailouts |
24 // and force a list instantiation. | 25 // and force a list instantiation. |
25 foo([]); | 26 foo([]); |
26 // Force bailout on [a]. | 27 // Force bailout on [a]. |
27 for (int i = 0; i < 100; i++) a[0] = 42; | 28 for (int i = 0; i < 100; i++) a[0] = 42; |
28 // Force bailout on [:a.length:]. | 29 // Force bailout on [:a.length:]. |
29 for (int i = 0; i < 200; i++) a[0] = -a.length; | 30 for (int i = 0; i < 200; i++) a[0] = -a.length; |
30 } | 31 } |
31 '''; | 32 '''; |
32 | 33 |
33 main() { | 34 main() { |
34 String generated = compile(TEST, entry: 'foo'); | 35 String generated = compile(TEST, entry: 'foo'); |
35 | |
36 // Check that we only have one bailout call. The second bailout call | 36 // Check that we only have one bailout call. The second bailout call |
37 // is dead code because we know [:a.length:] is an int. | 37 // is dead code because we know [:a.length:] is an int. |
38 checkNumberOfMatches(new RegExp('bailout').allMatches(generated).iterator, 1); | 38 checkNumberOfMatches(new RegExp('bailout').allMatches(generated).iterator, 1); |
39 | 39 |
40 // Check that the foo method does not have any call to | 40 // Check that the foo method does not have any call to |
41 // 'getInterceptor'. The environment for the second bailout contains | 41 // 'getInterceptor'. The environment for the second bailout contains |
42 // the interceptor of [:a.length:], but since the bailout is | 42 // the interceptor of [:a.length:], but since the bailout is |
43 // removed, the interceptor is removed too. | 43 // removed, the interceptor is removed too. |
44 if (generated.contains(r'getInterceptor(a).$is')) { | 44 if (generated.contains(r'getInterceptor(a).$is')) { |
45 // If we have an interceptor for a type check, it should be the only one. | 45 // If we have an interceptor for a type check, it should be the only one. |
46 checkNumberOfMatches( | 46 checkNumberOfMatches( |
47 new RegExp('getInterceptor').allMatches(generated).iterator, 1); | 47 new RegExp('getInterceptor').allMatches(generated).iterator, 1); |
48 } else { | 48 } else { |
49 Expect.isTrue(!generated.contains('getInterceptor')); | 49 Expect.isTrue(!generated.contains('getInterceptor')); |
50 } | 50 } |
51 | 51 |
52 generated = compileAll(TEST); | 52 asyncTest(() => compileAll(TEST).then((generated) { |
53 | 53 // Check that the foo bailout method is generated. |
54 // Check that the foo bailout method is generated. | 54 checkNumberOfMatches( |
55 checkNumberOfMatches( | 55 new RegExp('foo\\\$bailout').allMatches(generated).iterator, 2); |
56 new RegExp('foo\\\$bailout').allMatches(generated).iterator, 2); | |
57 | 56 |
58 // Check that it's the only bailout method. | 57 // Check that it's the only bailout method. |
59 checkNumberOfMatches(new RegExp('bailout').allMatches(generated).iterator, 2); | 58 checkNumberOfMatches(new RegExp('bailout').allMatches(generated).iterator, 2
); |
60 | 59 |
61 // Check that the bailout method has a case 2 for the state, which | 60 // Check that the bailout method has a case 2 for the state, which |
62 // is the second bailout in foo. | 61 // is the second bailout in foo. |
63 Expect.isTrue(generated.contains('case 2:')); | 62 Expect.isTrue(generated.contains('case 2:')); |
64 | 63 |
65 // Finally, make sure that the reason foo does not contain | 64 // Finally, make sure that the reason foo does not contain |
66 // 'getInterceptor' is not because the compiler renamed it. | 65 // 'getInterceptor' is not because the compiler renamed it. |
67 Expect.isTrue(generated.contains('getInterceptor')); | 66 Expect.isTrue(generated.contains('getInterceptor')); |
| 67 })); |
68 } | 68 } |
OLD | NEW |