1 /*
2  * Copyright (C) 2014 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 public class Main {
18 
19   // The following tests make sure that we inline methods used inside try and catch
20   // blocks, provided they meet other inlining criteria. To do that, we rely on
21   // the compiler recognizing and enforcing the $inline$ and $noinline$ markers.
22 
23   // We expect a single block to always be inlined.
24 
$inline$SingleBlock(String str)25   private static int $inline$SingleBlock(String str) throws NumberFormatException {
26     return Integer.parseInt(str);
27   }
28 
29   // We expect a "simple" method with multiple blocks to always be inlined.
30 
$inline$MultipleBlocks(String str, boolean is_hex)31   private static int $inline$MultipleBlocks(String str, boolean is_hex)
32       throws NumberFormatException {
33     return is_hex ? Integer.parseInt(str, 16) : Integer.parseInt(str);
34   }
35 
36   // We expect methods with try/catch to not be inlined. Inlined try/catch
37   // blocks are not supported at the moment.
38 
$noinline$TryCatch(String str)39   private static int $noinline$TryCatch(String str) {
40     try {
41       return Integer.parseInt(str);
42     } catch (NumberFormatException ex) {
43       return -1;
44     }
45   }
46 
testSingleBlockFromTry()47   public static void testSingleBlockFromTry() {
48     int val = 0;
49 
50     try {
51       val = $inline$SingleBlock("42");
52     } catch (NumberFormatException ex) {
53       unreachable();
54     }
55     assertEquals(42, val);
56 
57     try {
58       $inline$SingleBlock("xyz");
59       unreachable();
60     } catch (NumberFormatException ex) {}
61   }
62 
testSingleBlockFromCatch()63   public static void testSingleBlockFromCatch() {
64     int val = 0;
65 
66     try {
67       throwException();
68     } catch (Exception ex) {
69       val = $inline$SingleBlock("42");
70     }
71     assertEquals(42, val);
72   }
73 
testMultipleBlocksFromTry()74   public static void testMultipleBlocksFromTry() {
75     int val = 0;
76 
77     try {
78       val = $inline$MultipleBlocks("42", false);
79     } catch (NumberFormatException ex) {
80       unreachable();
81     }
82     assertEquals(42, val);
83 
84     try {
85       val = $inline$MultipleBlocks("20", true);
86     } catch (NumberFormatException ex) {
87       unreachable();
88     }
89     assertEquals(32, val);
90 
91     try {
92       $inline$MultipleBlocks("xyz", false);
93       unreachable();
94     } catch (NumberFormatException ex) {}
95 
96     try {
97       $inline$MultipleBlocks("xyz", true);
98       unreachable();
99     } catch (NumberFormatException ex) {}
100   }
101 
testMultipleBlocksFromCatch()102   public static void testMultipleBlocksFromCatch() {
103     int val = 0;
104 
105     try {
106       throwException();
107     } catch (Exception ex) {
108       val = $inline$MultipleBlocks("42", false);
109     }
110     assertEquals(42, val);
111 
112     try {
113       throwException();
114     } catch (Exception ex) {
115       val = $inline$MultipleBlocks("20", true);
116     }
117     assertEquals(32, val);
118   }
119 
testTryCatchFromTry()120   public static void testTryCatchFromTry() {
121     int val = 0;
122 
123     try {
124       val = $noinline$TryCatch("42");
125     } catch (NumberFormatException ex) {
126       unreachable();
127     }
128     assertEquals(42, val);
129 
130     try {
131       val = $noinline$TryCatch("xyz");
132     } catch (NumberFormatException ex) {
133       unreachable();
134     }
135     assertEquals(-1, val);
136   }
137 
testTryCatchFromCatch()138   public static void testTryCatchFromCatch() {
139     int val = 0;
140 
141     try {
142       throwException();
143     } catch (Exception ex) {
144       val = $noinline$TryCatch("42");
145     }
146     assertEquals(42, val);
147 
148     try {
149       throwException();
150     } catch (Exception ex) {
151       val = $noinline$TryCatch("xyz");
152     }
153     assertEquals(-1, val);
154   }
155 
main(String[] args)156   public static void main(String[] args) {
157     testSingleBlockFromTry();
158     testSingleBlockFromCatch();
159     testMultipleBlocksFromTry();
160     testMultipleBlocksFromCatch();
161     testTryCatchFromTry();
162     testTryCatchFromCatch();
163   }
164 
assertEquals(int expected, int actual)165   private static void assertEquals(int expected, int actual) {
166     if (expected != actual) {
167       throw new AssertionError("Wrong result: " + expected + " != " + actual);
168     }
169   }
170 
unreachable()171   private static void unreachable() {
172     throw new Error("Unreachable");
173   }
174 
throwException()175   private static void throwException() throws Exception {
176     throw new Exception();
177   }
178 }
179