Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/openj9
Path: blob/master/test/functional/Jsr292/src/com/ibm/j9/jsr292/InterfaceHandleTest.java
6007 views
1
/*******************************************************************************
2
* Copyright (c) 2014, 2018 IBM Corp. and others
3
*
4
* This program and the accompanying materials are made available under
5
* the terms of the Eclipse Public License 2.0 which accompanies this
6
* distribution and is available at https://www.eclipse.org/legal/epl-2.0/
7
* or the Apache License, Version 2.0 which accompanies this distribution and
8
* is available at https://www.apache.org/licenses/LICENSE-2.0.
9
*
10
* This Source Code may also be made available under the following
11
* Secondary Licenses when the conditions for such availability set
12
* forth in the Eclipse Public License, v. 2.0 are satisfied: GNU
13
* General Public License, version 2 with the GNU Classpath
14
* Exception [1] and GNU General Public License, version 2 with the
15
* OpenJDK Assembly Exception [2].
16
*
17
* [1] https://www.gnu.org/software/classpath/license.html
18
* [2] http://openjdk.java.net/legal/assembly-exception.html
19
*
20
* SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 OR GPL-2.0 WITH Classpath-exception-2.0 OR LicenseRef-GPL-2.0 WITH Assembly-exception
21
*******************************************************************************/
22
package com.ibm.j9.jsr292;
23
24
import org.testng.annotations.Test;
25
import org.testng.Assert;
26
import org.testng.AssertJUnit;
27
import static org.objectweb.asm.Opcodes.*;
28
29
import java.lang.invoke.MethodHandle;
30
import java.lang.invoke.MethodHandles;
31
import java.lang.invoke.MethodType;
32
import java.lang.reflect.Field;
33
34
import org.objectweb.asm.ClassWriter;
35
import org.objectweb.asm.MethodVisitor;
36
37
import org.openj9.test.util.VersionCheck;
38
39
/**
40
* A class to check if a specific method is correctly compiled by JIT
41
*/
42
public class InterfaceHandleTest {
43
44
@Test(groups = { "level.extended" })
45
public void testIfInterfaceHandleIsJitted() throws Throwable {
46
try {
47
TestClass_IH clazz = new TestClass_IH();
48
MethodHandle mh = MethodHandles.lookup().findVirtual(TestInterface.class, "test", MethodType.methodType(void.class));
49
AssertJUnit.assertTrue(mh.getClass().toString().equals("class java.lang.invoke.InterfaceHandle"));
50
try {
51
while (true) {
52
mh.invokeExact((TestInterface)clazz);
53
}
54
} catch (Error t) {
55
t.printStackTrace();
56
}
57
} catch (JittingDetector j) {
58
AssertJUnit.assertTrue(true);
59
}
60
}
61
62
/**
63
* Class C inherits a public implementation of the method f from class B, which is declared in interface A.
64
* Because the implementation is public, B.f is a valid implementation of A.f.
65
*/
66
@Test(groups = { "level.extended" })
67
public void test_bindTo_interfaceMethodImplementation_public() throws Throwable {
68
Helper h = new Helper(ACC_PUBLIC);
69
MethodHandle mh = MethodHandles.lookup().findVirtual(h.classA, "f", MethodType.methodType(void.class));
70
mh = mh.bindTo(h.classC.newInstance());
71
mh.invokeExact();
72
}
73
74
/**
75
* Class C inherits a protected implementation of the method f from class B.
76
* The method is also declared in interface A, which C implements.
77
* Because the implementation is protected, B.f is an invalid implementation of A.f.
78
*/
79
@Test(groups = { "level.extended" })
80
public void test_bindTo_interfaceMethodImplementation_protected() throws Throwable {
81
Helper h = new Helper(ACC_PROTECTED);
82
MethodHandle mh = MethodHandles.lookup().findVirtual(h.classA, "f", MethodType.methodType(void.class));
83
mh = mh.bindTo(h.classC.newInstance());
84
try {
85
mh.invokeExact();
86
Assert.fail("Successfully invoked protected implementation of an interface method.");
87
} catch (IllegalAccessError e) { }
88
}
89
90
/**
91
* Class C inherits a package private implementation of the method f from class B.
92
* The method is also declared in interface A, which C implements.
93
* Because the implementation is package private, B.f is an invalid implementation of A.f.
94
*/
95
@Test(groups = { "level.extended" })
96
public void test_bindTo_interfaceMethodImplementation_package() throws Throwable {
97
Helper h = new Helper(0);
98
MethodHandle mh = MethodHandles.lookup().findVirtual(h.classA, "f", MethodType.methodType(void.class));
99
mh = mh.bindTo(h.classC.newInstance());
100
try {
101
mh.invokeExact();
102
Assert.fail("Successfully invoked package private implementation of an interface method.");
103
} catch (IllegalAccessError e) { }
104
}
105
106
/**
107
* Class C inherits a private implementation of the method f from class B.
108
* The method is also declared in interface A, which C implements.
109
* Because the implementation is private, B.f is an invalid implementation of A.f.
110
*/
111
@Test(groups = { "level.extended" })
112
public void test_bindTo_interfaceMethodImplementation_private() throws Throwable {
113
Helper h = new Helper(ACC_PRIVATE);
114
MethodHandle mh = MethodHandles.lookup().findVirtual(h.classA, "f", MethodType.methodType(void.class));
115
mh = mh.bindTo(h.classC.newInstance());
116
try {
117
mh.invokeExact();
118
Assert.fail("Successfully invoked private implementation of an interface method.");
119
} catch (IllegalAccessError e) {
120
if (VersionCheck.major() >= 11) {
121
Assert.fail("IllegalAccessError thrown instead of AbstractMethodError");
122
}
123
} catch (AbstractMethodError e) {
124
if (VersionCheck.major() < 11) {
125
Assert.fail("AbstractMethodError thrown instead of IllegalAccessError");
126
}
127
}
128
}
129
130
static class Helper {
131
private static final String CLASS_A = "A";
132
private static final String CLASS_B = "B";
133
private static final String CLASS_C = "C";
134
135
Class<?> classA;
136
Class<?> classB;
137
Class<?> classC;
138
139
Helper(final int flags) throws ClassNotFoundException {
140
ClassLoader cl = new ClassLoader() {
141
public Class<?> findClass(String name) throws ClassNotFoundException {
142
if (CLASS_A.equals(name)) {
143
byte[] classFile = getClassA();
144
return defineClass(CLASS_A, classFile, 0, classFile.length);
145
} else if (CLASS_B.equals(name)) {
146
byte[] classFile = getClassB(flags);
147
return defineClass(CLASS_B, classFile, 0, classFile.length);
148
} else if (CLASS_C.equals(name)) {
149
byte[] classFile = getClassC();
150
return defineClass(CLASS_C, classFile, 0, classFile.length);
151
}
152
throw new ClassNotFoundException(name);
153
}
154
155
/*
156
* interface A {
157
* void f();
158
* }
159
*/
160
private byte[] getClassA() {
161
ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_FRAMES | ClassWriter.COMPUTE_MAXS);
162
MethodVisitor mv;
163
164
cw.visit(49, ACC_PUBLIC | ACC_ABSTRACT | ACC_INTERFACE, CLASS_A, null, "java/lang/Object", null);
165
{
166
mv = cw.visitMethod(ACC_PUBLIC | ACC_ABSTRACT, "f", "()V", null, null);
167
mv.visitEnd();
168
}
169
return cw.toByteArray();
170
}
171
172
/*
173
* class B {
174
* [flags] void f() {}
175
* }
176
*/
177
private byte[] getClassB(int flags) {
178
ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_FRAMES | ClassWriter.COMPUTE_MAXS);
179
MethodVisitor mv;
180
181
cw.visit(49, ACC_PUBLIC | ACC_SUPER, CLASS_B, null, "java/lang/Object", null);
182
{
183
mv = cw.visitMethod(ACC_PUBLIC, "<init>", "()V", null, null);
184
mv.visitCode();
185
mv.visitVarInsn(ALOAD, 0);
186
mv.visitMethodInsn(INVOKESPECIAL, "java/lang/Object", "<init>", "()V", false);
187
mv.visitInsn(RETURN);
188
mv.visitMaxs(0, 0);
189
mv.visitEnd();
190
}
191
{
192
mv = cw.visitMethod(flags, "f", "()V", null, null);
193
mv.visitCode();
194
mv.visitInsn(RETURN);
195
mv.visitMaxs(0, 0);
196
mv.visitEnd();
197
}
198
return cw.toByteArray();
199
}
200
201
/*
202
* class C extends B implements A { }
203
*/
204
private byte[] getClassC() {
205
ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_FRAMES | ClassWriter.COMPUTE_MAXS);
206
MethodVisitor mv;
207
208
cw.visit(49, ACC_PUBLIC | ACC_SUPER, CLASS_C, null, CLASS_B, new String[] {CLASS_A});
209
{
210
mv = cw.visitMethod(ACC_PUBLIC, "<init>", "()V", null, null);
211
mv.visitCode();
212
mv.visitVarInsn(ALOAD, 0);
213
mv.visitMethodInsn(INVOKESPECIAL, CLASS_B, "<init>", "()V", false);
214
mv.visitInsn(RETURN);
215
mv.visitMaxs(0, 0);
216
mv.visitEnd();
217
}
218
return cw.toByteArray();
219
}
220
};
221
222
classA = cl.loadClass(CLASS_A);
223
classB = cl.loadClass(CLASS_B);
224
classC = cl.loadClass(CLASS_C);
225
}
226
}
227
}
228
229
class TestClass_IH implements TestInterface {
230
231
static long PC = 0;
232
233
static final Field throwable_walkback;
234
235
static {
236
Field f;
237
try {
238
f = Throwable.class.getDeclaredField("walkback");
239
f.setAccessible(true);
240
throwable_walkback = f;
241
} catch (NoSuchFieldException | SecurityException e) {
242
throw new RuntimeException();
243
}
244
}
245
246
@Test(groups = { "level.extended" })
247
public void test() throws Throwable {
248
Throwable t = new Throwable();
249
Object walkback = throwable_walkback.get(t);
250
if (walkback instanceof int[]) {
251
int[] iWalkback = (int[])walkback;
252
if (PC == 0) {
253
PC = iWalkback[0];
254
} else if (PC != iWalkback[0]) {
255
throw new JittingDetector("detected jitting");
256
}
257
} else {
258
long[] iWalkback = (long[])walkback;
259
if (PC == 0) {
260
PC = iWalkback[0];
261
} else if (PC != iWalkback[0]) {
262
throw new JittingDetector("detected jitting");
263
}
264
}
265
}
266
}
267
268