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
17public 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
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
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
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
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
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
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
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
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
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
156  public static void main(String[] args) {
157    testSingleBlockFromTry();
158    testSingleBlockFromCatch();
159    testMultipleBlocksFromTry();
160    testMultipleBlocksFromCatch();
161    testTryCatchFromTry();
162    testTryCatchFromCatch();
163  }
164
165  private static void assertEquals(int expected, int actual) {
166    if (expected != actual) {
167      throw new AssertionError("Wrong result: " + expected + " != " + actual);
168    }
169  }
170
171  private static void unreachable() {
172    throw new Error("Unreachable");
173  }
174
175  private static void throwException() throws Exception {
176    throw new Exception();
177  }
178}
179