blob: 286f0d996eef494c2e2bc217b6f2e0de5763018d [file] [log] [blame]
Nicolas Geoffraya42363f2015-12-17 14:57:09 +00001/*
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
17interface Itf {
18 public Class sameInvokeInterface();
19}
20
21public class Main implements Itf {
22 public static void assertEquals(Object expected, Object actual) {
23 if (expected != actual) {
24 throw new Error("Expected " + expected + ", got " + actual);
25 }
26 }
27
Nicolas Geoffray1be7cbd2016-04-29 13:56:01 +010028 public static void assertEquals(int expected, int actual) {
29 if (expected != actual) {
30 throw new Error("Expected " + expected + ", got " + actual);
31 }
32 }
33
Nicolas Geoffraya42363f2015-12-17 14:57:09 +000034 public static void main(String[] args) throws Exception {
35 System.loadLibrary(args[0]);
36 Main[] mains = new Main[3];
37 Itf[] itfs = new Itf[3];
38 itfs[0] = mains[0] = new Main();
39 itfs[1] = mains[1] = new Subclass();
40 itfs[2] = mains[2] = new OtherSubclass();
41
42 // Make testInvokeVirtual and testInvokeInterface hot to get them jitted.
43 // We pass Main and Subclass to get polymorphic inlining based on calling
44 // the same method.
45 for (int i = 0; i < 10000; ++i) {
46 testInvokeVirtual(mains[0]);
47 testInvokeVirtual(mains[1]);
48 testInvokeInterface(itfs[0]);
49 testInvokeInterface(itfs[1]);
Nicolas Geoffray1be7cbd2016-04-29 13:56:01 +010050 $noinline$testInlineToSameTarget(mains[0]);
51 $noinline$testInlineToSameTarget(mains[1]);
Nicolas Geoffraya42363f2015-12-17 14:57:09 +000052 }
53
54 ensureJittedAndPolymorphicInline();
55
56 // At this point, the JIT should have compiled both methods, and inline
57 // sameInvokeVirtual and sameInvokeInterface.
58 assertEquals(Main.class, testInvokeVirtual(mains[0]));
59 assertEquals(Main.class, testInvokeVirtual(mains[1]));
60
61 assertEquals(Itf.class, testInvokeInterface(itfs[0]));
62 assertEquals(Itf.class, testInvokeInterface(itfs[1]));
63
64 // This will trigger a deoptimization of the compiled code.
65 assertEquals(OtherSubclass.class, testInvokeVirtual(mains[2]));
66 assertEquals(OtherSubclass.class, testInvokeInterface(itfs[2]));
Nicolas Geoffray1be7cbd2016-04-29 13:56:01 +010067
68 // Run this once to make sure we execute the JITted code.
69 $noinline$testInlineToSameTarget(mains[0]);
70 assertEquals(20001, counter);
Nicolas Geoffraya42363f2015-12-17 14:57:09 +000071 }
72
73 public Class sameInvokeVirtual() {
74 field.getClass(); // null check to ensure we get an inlined frame in the CodeInfo
75 return Main.class;
76 }
77
78 public Class sameInvokeInterface() {
79 field.getClass(); // null check to ensure we get an inlined frame in the CodeInfo
80 return Itf.class;
81 }
82
83 public static Class testInvokeInterface(Itf i) {
84 return i.sameInvokeInterface();
85 }
86
87 public static Class testInvokeVirtual(Main m) {
88 return m.sameInvokeVirtual();
89 }
90
Nicolas Geoffray1be7cbd2016-04-29 13:56:01 +010091 public static void $noinline$testInlineToSameTarget(Main m) {
92 if (doThrow) throw new Error("");
93 m.increment();
94 }
95
Nicolas Geoffraya42363f2015-12-17 14:57:09 +000096 public Object field = new Object();
97
98 public static native void ensureJittedAndPolymorphicInline();
Nicolas Geoffray1be7cbd2016-04-29 13:56:01 +010099
100 public void increment() {
101 counter++;
102 }
103 public static int counter = 0;
104 public static boolean doThrow = false;
Nicolas Geoffraya42363f2015-12-17 14:57:09 +0000105}
106
107class Subclass extends Main {
108}
109
110class OtherSubclass extends Main {
111 public Class sameInvokeVirtual() {
112 return OtherSubclass.class;
113 }
114
115 public Class sameInvokeInterface() {
116 return OtherSubclass.class;
117 }
118}