Home | History | Annotate | Download | only in src
      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 
     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