blob: 793b85f5e538b4ed1d4a913f589cd87bff801fc6 [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 {
Andreas Gampe166aaee2016-07-18 08:27:23 -070018 public Class<?> sameInvokeInterface();
19 public Class<?> sameInvokeInterface2();
20 public Class<?> sameInvokeInterface3();
Nicolas Geoffraya42363f2015-12-17 14:57:09 +000021}
22
23public 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
Nicolas Geoffray1be7cbd2016-04-29 13:56:01 +010030 public static void assertEquals(int expected, int actual) {
31 if (expected != actual) {
32 throw new Error("Expected " + expected + ", got " + actual);
33 }
34 }
35
Nicolas Geoffraya42363f2015-12-17 14:57:09 +000036 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
Nicolas Geoffray2fa11372016-06-16 14:09:03 +010044 // Create the profiling info eagerly to make sure they are filled.
45 ensureProfilingInfo566();
46
Nicolas Geoffraya42363f2015-12-17 14:57:09 +000047 // 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]);
Nicolas Geoffrayff484b92016-07-13 14:13:48 +010055 testInvokeInterface2(itfs[0]);
56 testInvokeInterface2(itfs[1]);
Nicolas Geoffray1be7cbd2016-04-29 13:56:01 +010057 $noinline$testInlineToSameTarget(mains[0]);
58 $noinline$testInlineToSameTarget(mains[1]);
Nicolas Geoffraya42363f2015-12-17 14:57:09 +000059 }
60
Nicolas Geoffray2fa11372016-06-16 14:09:03 +010061 ensureJittedAndPolymorphicInline566();
Nicolas Geoffraya42363f2015-12-17 14:57:09 +000062
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
Nicolas Geoffrayff484b92016-07-13 14:13:48 +010071 assertEquals(Itf.class, testInvokeInterface2(itfs[0]));
72 assertEquals(Itf.class, testInvokeInterface2(itfs[1]));
73
Nicolas Geoffraya42363f2015-12-17 14:57:09 +000074 // This will trigger a deoptimization of the compiled code.
75 assertEquals(OtherSubclass.class, testInvokeVirtual(mains[2]));
76 assertEquals(OtherSubclass.class, testInvokeInterface(itfs[2]));
Nicolas Geoffrayff484b92016-07-13 14:13:48 +010077 assertEquals(null, testInvokeInterface2(itfs[2]));
Nicolas Geoffray1be7cbd2016-04-29 13:56:01 +010078
79 // Run this once to make sure we execute the JITted code.
80 $noinline$testInlineToSameTarget(mains[0]);
81 assertEquals(20001, counter);
Nicolas Geoffraya42363f2015-12-17 14:57:09 +000082 }
83
Andreas Gampe166aaee2016-07-18 08:27:23 -070084 public Class<?> sameInvokeVirtual() {
Nicolas Geoffray2fa11372016-06-16 14:09:03 +010085 field.getClass(); // null check to ensure we get an inlined frame in the CodeInfo.
Nicolas Geoffraya42363f2015-12-17 14:57:09 +000086 return Main.class;
87 }
88
Andreas Gampe166aaee2016-07-18 08:27:23 -070089 public Class<?> sameInvokeInterface() {
Nicolas Geoffray2fa11372016-06-16 14:09:03 +010090 field.getClass(); // null check to ensure we get an inlined frame in the CodeInfo.
Nicolas Geoffraya42363f2015-12-17 14:57:09 +000091 return Itf.class;
92 }
93
Andreas Gampe166aaee2016-07-18 08:27:23 -070094 public Class<?> sameInvokeInterface2() {
Nicolas Geoffrayff484b92016-07-13 14:13:48 +010095 field.getClass(); // null check to ensure we get an inlined frame in the CodeInfo.
96 return Itf.class;
97 }
98
Andreas Gampe166aaee2016-07-18 08:27:23 -070099 public Class<?> sameInvokeInterface3() {
Nicolas Geoffrayff484b92016-07-13 14:13:48 +0100100 field.getClass(); // null check to ensure we get an inlined frame in the CodeInfo.
101 return Itf.class;
102 }
103
Andreas Gampe166aaee2016-07-18 08:27:23 -0700104 public static Class<?> testInvokeInterface(Itf i) {
Nicolas Geoffraya42363f2015-12-17 14:57:09 +0000105 return i.sameInvokeInterface();
106 }
107
Andreas Gampe166aaee2016-07-18 08:27:23 -0700108 public static Class<?> testInvokeInterface2(Itf i) {
Nicolas Geoffrayff484b92016-07-13 14:13:48 +0100109 // 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
Andreas Gampe166aaee2016-07-18 08:27:23 -0700116 public static Class<?> testInvokeVirtual(Main m) {
Nicolas Geoffraya42363f2015-12-17 14:57:09 +0000117 return m.sameInvokeVirtual();
118 }
119
Nicolas Geoffray1be7cbd2016-04-29 13:56:01 +0100120 public static void $noinline$testInlineToSameTarget(Main m) {
121 if (doThrow) throw new Error("");
122 m.increment();
123 }
124
Nicolas Geoffraya42363f2015-12-17 14:57:09 +0000125 public Object field = new Object();
126
Nicolas Geoffray2fa11372016-06-16 14:09:03 +0100127 public static native void ensureJittedAndPolymorphicInline566();
128 public static native void ensureProfilingInfo566();
Nicolas Geoffray1be7cbd2016-04-29 13:56:01 +0100129
130 public void increment() {
Nicolas Geoffray130b7cf2016-05-06 10:08:36 +0100131 field.getClass(); // null check to ensure we get an inlined frame in the CodeInfo
Nicolas Geoffray1be7cbd2016-04-29 13:56:01 +0100132 counter++;
133 }
134 public static int counter = 0;
135 public static boolean doThrow = false;
Nicolas Geoffraya42363f2015-12-17 14:57:09 +0000136}
137
138class Subclass extends Main {
139}
140
141class OtherSubclass extends Main {
Andreas Gampe166aaee2016-07-18 08:27:23 -0700142 public Class<?> sameInvokeVirtual() {
Nicolas Geoffraya42363f2015-12-17 14:57:09 +0000143 return OtherSubclass.class;
144 }
145
Andreas Gampe166aaee2016-07-18 08:27:23 -0700146 public Class<?> sameInvokeInterface() {
Nicolas Geoffraya42363f2015-12-17 14:57:09 +0000147 return OtherSubclass.class;
148 }
Nicolas Geoffrayff484b92016-07-13 14:13:48 +0100149
Andreas Gampe166aaee2016-07-18 08:27:23 -0700150 public Class<?> sameInvokeInterface2() {
Nicolas Geoffrayff484b92016-07-13 14:13:48 +0100151 return null;
152 }
Andreas Gampe166aaee2016-07-18 08:27:23 -0700153 public Class<?> sameInvokeInterface3() {
Nicolas Geoffrayff484b92016-07-13 14:13:48 +0100154 return null;
155 }
Nicolas Geoffraya42363f2015-12-17 14:57:09 +0000156}