Home | History | Annotate | Download | only in src
      1 /*
      2  * Copyright (C) 2016 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 interface Itf {
     18   public Class<?> sameInvokeInterface();
     19   public Class<?> sameInvokeInterface2();
     20   public Class<?> sameInvokeInterface3();
     21 }
     22 
     23 public class Main implements Itf {
     24   public static void assertEquals(Object expected, Object actual) {
     25     if (expected != actual) {
     26       throw new Error("Expected " + expected  + ", got " + actual);
     27     }
     28   }
     29 
     30   public static void assertEquals(int expected, int actual) {
     31     if (expected != actual) {
     32       throw new Error("Expected " + expected  + ", got " + actual);
     33     }
     34   }
     35 
     36   public static void main(String[] args) throws Exception {
     37     System.loadLibrary(args[0]);
     38     Main[] mains = new Main[3];
     39     Itf[] itfs = new Itf[3];
     40     itfs[0] = mains[0] = new Main();
     41     itfs[1] = mains[1] = new Subclass();
     42     itfs[2] = mains[2] = new OtherSubclass();
     43 
     44     // Create the profiling info eagerly to make sure they are filled.
     45     ensureProfilingInfo566();
     46 
     47     // Make testInvokeVirtual and testInvokeInterface hot to get them jitted.
     48     // We pass Main and Subclass to get polymorphic inlining based on calling
     49     // the same method.
     50     for (int i = 0; i < 10000; ++i) {
     51       testInvokeVirtual(mains[0]);
     52       testInvokeVirtual(mains[1]);
     53       testInvokeInterface(itfs[0]);
     54       testInvokeInterface(itfs[1]);
     55       testInvokeInterface2(itfs[0]);
     56       testInvokeInterface2(itfs[1]);
     57       $noinline$testInlineToSameTarget(mains[0]);
     58       $noinline$testInlineToSameTarget(mains[1]);
     59     }
     60 
     61     ensureJittedAndPolymorphicInline566();
     62 
     63     // At this point, the JIT should have compiled both methods, and inline
     64     // sameInvokeVirtual and sameInvokeInterface.
     65     assertEquals(Main.class, testInvokeVirtual(mains[0]));
     66     assertEquals(Main.class, testInvokeVirtual(mains[1]));
     67 
     68     assertEquals(Itf.class, testInvokeInterface(itfs[0]));
     69     assertEquals(Itf.class, testInvokeInterface(itfs[1]));
     70 
     71     assertEquals(Itf.class, testInvokeInterface2(itfs[0]));
     72     assertEquals(Itf.class, testInvokeInterface2(itfs[1]));
     73 
     74     // This will trigger a deoptimization of the compiled code.
     75     assertEquals(OtherSubclass.class, testInvokeVirtual(mains[2]));
     76     assertEquals(OtherSubclass.class, testInvokeInterface(itfs[2]));
     77     assertEquals(null, testInvokeInterface2(itfs[2]));
     78 
     79     // Run this once to make sure we execute the JITted code.
     80     $noinline$testInlineToSameTarget(mains[0]);
     81     assertEquals(20001, counter);
     82   }
     83 
     84   public Class<?> sameInvokeVirtual() {
     85     field.getClass(); // null check to ensure we get an inlined frame in the CodeInfo.
     86     return Main.class;
     87   }
     88 
     89   public Class<?> sameInvokeInterface() {
     90     field.getClass(); // null check to ensure we get an inlined frame in the CodeInfo.
     91     return Itf.class;
     92   }
     93 
     94   public Class<?> sameInvokeInterface2() {
     95     field.getClass(); // null check to ensure we get an inlined frame in the CodeInfo.
     96     return Itf.class;
     97   }
     98 
     99   public Class<?> sameInvokeInterface3() {
    100     field.getClass(); // null check to ensure we get an inlined frame in the CodeInfo.
    101     return Itf.class;
    102   }
    103 
    104   public static Class<?> testInvokeInterface(Itf i) {
    105     return i.sameInvokeInterface();
    106   }
    107 
    108   public static Class<?> testInvokeInterface2(Itf i) {
    109     // Make three interface calls that will do a ClassTableGet to ensure bogus code
    110     // generation of ClassTableGet will crash.
    111     i.sameInvokeInterface();
    112     i.sameInvokeInterface2();
    113     return i.sameInvokeInterface3();
    114   }
    115 
    116   public static Class<?> testInvokeVirtual(Main m) {
    117     return m.sameInvokeVirtual();
    118   }
    119 
    120   public static void $noinline$testInlineToSameTarget(Main m) {
    121     if (doThrow) throw new Error("");
    122     m.increment();
    123   }
    124 
    125   public Object field = new Object();
    126 
    127   public static native void ensureJittedAndPolymorphicInline566();
    128   public static native void ensureProfilingInfo566();
    129 
    130   public void increment() {
    131     field.getClass(); // null check to ensure we get an inlined frame in the CodeInfo
    132     counter++;
    133   }
    134   public static int counter = 0;
    135   public static boolean doThrow = false;
    136 }
    137 
    138 class Subclass extends Main {
    139 }
    140 
    141 class OtherSubclass extends Main {
    142   public Class<?> sameInvokeVirtual() {
    143     return OtherSubclass.class;
    144   }
    145 
    146   public Class<?> sameInvokeInterface() {
    147     return OtherSubclass.class;
    148   }
    149 
    150   public Class<?> sameInvokeInterface2() {
    151     return null;
    152   }
    153   public Class<?> sameInvokeInterface3() {
    154     return null;
    155   }
    156 }
    157