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/VirtualHandleTest.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.AssertJUnit;
26
import java.lang.invoke.MethodHandle;
27
import java.lang.invoke.MethodHandles;
28
import java.lang.invoke.MethodType;
29
import java.lang.reflect.*;
30
31
import org.objectweb.asm.*;
32
import static org.objectweb.asm.Opcodes.*;
33
34
/**
35
* A class to check if a specific method is correctly compiled by JIT
36
*/
37
public class VirtualHandleTest {
38
39
@Test(groups = { "level.extended" })
40
public void testIfVirtualHandleTestIsJitted() throws Throwable {
41
try {
42
TestClass_VH clazz = new TestClass_VH();
43
MethodHandle mh = MethodHandles.lookup().findVirtual(TestClass_VH.class, "test", MethodType.methodType(void.class));
44
AssertJUnit.assertTrue(mh.getClass().toString().equals("class java.lang.invoke.VirtualHandle"));
45
try {
46
while (true) {
47
mh.invokeExact((TestClass_VH)clazz);
48
}
49
} catch (Error t) {
50
t.printStackTrace();
51
}
52
} catch (JittingDetector j) {
53
AssertJUnit.assertTrue(true);
54
}
55
}
56
57
/**
58
* Class A declares a public method f. Class B extends A and overrides f with a protected implementation.
59
* Class C extends B. A virtual invocation of f on C finds the protected method B.f.
60
* According to the reference implementation, this B.f is a valid virtual resolution.
61
*/
62
@Test(groups = { "level.extended" })
63
public void test_bindTo_narrowedMethodImplementation_protected() throws Throwable {
64
Helper h = new Helper(ACC_PROTECTED);
65
MethodHandle mh = MethodHandles.lookup().findVirtual(h.classA, "f", MethodType.methodType(void.class));
66
mh = mh.bindTo(h.classC.newInstance());
67
mh.invokeExact();
68
}
69
70
/**
71
* Class A declares a public method f. Class B extends A and overrides f with a package private implementation.
72
* Class C extends B. A virtual invocation of f on C finds the package private method B.f.
73
* According to the reference implementation, this B.f is a valid virtual resolution.
74
*/
75
@Test(groups = { "level.extended" })
76
public void test_bindTo_narrowedMethodImplementation_package() throws Throwable {
77
Helper h = new Helper(0);
78
MethodHandle mh = MethodHandles.lookup().findVirtual(h.classA, "f", MethodType.methodType(void.class));
79
mh = mh.bindTo(h.classC.newInstance());
80
mh.invokeExact();
81
}
82
83
/**
84
* Class A declares a public method f. Class B extends A and overrides f with a private implementation.
85
* Class C extends B. A virtual invocation of f on C finds the private method B.f.
86
* According to the reference implementation, this B.f is a valid virtual resolution.
87
*/
88
@Test(groups = { "level.extended" })
89
public void test_bindTo_narrowedMethodImplementation_private() throws Throwable {
90
Helper h = new Helper(ACC_PRIVATE);
91
MethodHandle mh = MethodHandles.lookup().findVirtual(h.classA, "f", MethodType.methodType(void.class));
92
mh = mh.bindTo(h.classC.newInstance());
93
mh.invokeExact();
94
}
95
96
static class Helper {
97
private static final String CLASS_A = "A";
98
private static final String CLASS_B = "B";
99
private static final String CLASS_C = "C";
100
101
Class<?> classA;
102
Class<?> classB;
103
Class<?> classC;
104
105
Helper(final int flags) throws ClassNotFoundException {
106
ClassLoader cl = new ClassLoader() {
107
public Class<?> findClass(String name) throws ClassNotFoundException {
108
if (CLASS_A.equals(name)) {
109
byte[] classFile = getClassA();
110
return defineClass(CLASS_A, classFile, 0, classFile.length);
111
} else if (CLASS_B.equals(name)) {
112
byte[] classFile = getClassB(flags);
113
return defineClass(CLASS_B, classFile, 0, classFile.length);
114
} else if (CLASS_C.equals(name)) {
115
byte[] classFile = getClassC();
116
return defineClass(CLASS_C, classFile, 0, classFile.length);
117
}
118
throw new ClassNotFoundException(name);
119
}
120
121
/*
122
* class A {
123
* public void f() {}
124
* }
125
*/
126
private byte[] getClassA() {
127
ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_FRAMES | ClassWriter.COMPUTE_MAXS);
128
MethodVisitor mv;
129
130
cw.visit(49, ACC_PUBLIC | ACC_SUPER, CLASS_A, null, "java/lang/Object", null);
131
{
132
mv = cw.visitMethod(ACC_PUBLIC, "<init>", "()V", null, null);
133
mv.visitCode();
134
mv.visitVarInsn(ALOAD, 0);
135
mv.visitMethodInsn(INVOKESPECIAL, "java/lang/Object", "<init>", "()V", false);
136
mv.visitInsn(RETURN);
137
mv.visitMaxs(0, 0);
138
mv.visitEnd();
139
}
140
{
141
mv = cw.visitMethod(ACC_PUBLIC, "f", "()V", null, null);
142
mv.visitCode();
143
mv.visitInsn(RETURN);
144
mv.visitMaxs(0, 0);
145
mv.visitEnd();
146
}
147
return cw.toByteArray();
148
}
149
150
/*
151
* class B extends A {
152
* [flags] void f() {}
153
* }
154
*/
155
private byte[] getClassB(int flags) {
156
ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_FRAMES | ClassWriter.COMPUTE_MAXS);
157
MethodVisitor mv;
158
159
cw.visit(49, ACC_PUBLIC | ACC_SUPER, CLASS_B, null, CLASS_A, null);
160
{
161
mv = cw.visitMethod(ACC_PUBLIC, "<init>", "()V", null, null);
162
mv.visitCode();
163
mv.visitVarInsn(ALOAD, 0);
164
mv.visitMethodInsn(INVOKESPECIAL, CLASS_A, "<init>", "()V", false);
165
mv.visitInsn(RETURN);
166
mv.visitMaxs(0, 0);
167
mv.visitEnd();
168
}
169
{
170
mv = cw.visitMethod(flags, "f", "()V", null, null);
171
mv.visitCode();
172
mv.visitInsn(RETURN);
173
mv.visitMaxs(0, 0);
174
mv.visitEnd();
175
}
176
return cw.toByteArray();
177
}
178
179
/*
180
* class C extends B { }
181
*/
182
private byte[] getClassC() {
183
ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_FRAMES | ClassWriter.COMPUTE_MAXS);
184
MethodVisitor mv;
185
186
cw.visit(49, ACC_PUBLIC | ACC_SUPER, CLASS_C, null, CLASS_B, null);
187
{
188
mv = cw.visitMethod(ACC_PUBLIC, "<init>", "()V", null, null);
189
mv.visitCode();
190
mv.visitVarInsn(ALOAD, 0);
191
mv.visitMethodInsn(INVOKESPECIAL, CLASS_B, "<init>", "()V", false);
192
mv.visitInsn(RETURN);
193
mv.visitMaxs(0, 0);
194
mv.visitEnd();
195
}
196
return cw.toByteArray();
197
}
198
};
199
200
classA = cl.loadClass(CLASS_A);
201
classB = cl.loadClass(CLASS_B);
202
classC = cl.loadClass(CLASS_C);
203
}
204
}
205
}
206
207
class TestClass_VH {
208
209
static long PC = 0;
210
211
static final Field throwable_walkback;
212
213
static {
214
Field f;
215
try {
216
f = Throwable.class.getDeclaredField("walkback");
217
f.setAccessible(true);
218
throwable_walkback = f;
219
} catch (NoSuchFieldException | SecurityException e) {
220
throw new RuntimeException();
221
}
222
}
223
224
public void test() throws Throwable {
225
Throwable t = new Throwable();
226
Object walkback = throwable_walkback.get(t);
227
if (walkback instanceof int[]) {
228
int[] iWalkback = (int[])walkback;
229
if (PC == 0) {
230
PC = iWalkback[0];
231
} else if (PC != iWalkback[0]) {
232
throw new JittingDetector("detected jitting");
233
}
234
} else {
235
long[] iWalkback = (long[])walkback;
236
if (PC == 0) {
237
PC = iWalkback[0];
238
} else if (PC != iWalkback[0]) {
239
throw new JittingDetector("detected jitting");
240
}
241
}
242
}
243
}
244
245