Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/mobile
Path: blob/master/test/hotspot/jtreg/compiler/jsr292/CallSiteDepContextTest.java
41149 views
1
/*
2
* Copyright (c) 2015, 2021, Oracle and/or its affiliates. All rights reserved.
3
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4
*
5
* This code is free software; you can redistribute it and/or modify it
6
* under the terms of the GNU General Public License version 2 only, as
7
* published by the Free Software Foundation.
8
*
9
* This code is distributed in the hope that it will be useful, but WITHOUT
10
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12
* version 2 for more details (a copy is included in the LICENSE file that
13
* accompanied this code).
14
*
15
* You should have received a copy of the GNU General Public License version
16
* 2 along with this work; if not, write to the Free Software Foundation,
17
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18
*
19
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20
* or visit www.oracle.com if you need additional information or have any
21
* questions.
22
*/
23
24
/**
25
* @test
26
* @bug 8057967
27
* @requires vm.opt.final.ClassUnloading
28
* @modules java.base/jdk.internal.misc
29
* java.base/jdk.internal.org.objectweb.asm
30
* @library patches /
31
*
32
* @build java.base/java.lang.invoke.MethodHandleHelper
33
* @run main/bootclasspath/othervm -Xbatch -XX:+IgnoreUnrecognizedVMOptions -Xlog:class+unload
34
* -XX:+PrintCompilation -XX:+TraceDependencies -XX:+TraceReferenceGC
35
* -verbose:gc
36
* compiler.jsr292.CallSiteDepContextTest
37
*/
38
39
package compiler.jsr292;
40
41
import jdk.internal.org.objectweb.asm.ClassWriter;
42
import jdk.internal.org.objectweb.asm.Handle;
43
import jdk.internal.org.objectweb.asm.MethodVisitor;
44
45
import java.lang.invoke.CallSite;
46
import java.lang.invoke.MethodHandle;
47
import java.lang.invoke.MethodHandleHelper;
48
import java.lang.invoke.MethodHandles;
49
import java.lang.invoke.MethodHandles.Lookup;
50
import java.lang.invoke.MethodType;
51
import java.lang.invoke.MutableCallSite;
52
import java.lang.ref.PhantomReference;
53
import java.lang.ref.Reference;
54
import java.lang.ref.ReferenceQueue;
55
import java.lang.reflect.Field;
56
57
import static jdk.internal.org.objectweb.asm.Opcodes.ACC_PUBLIC;
58
import static jdk.internal.org.objectweb.asm.Opcodes.ACC_STATIC;
59
import static jdk.internal.org.objectweb.asm.Opcodes.ACC_SUPER;
60
import static jdk.internal.org.objectweb.asm.Opcodes.H_INVOKESTATIC;
61
import static jdk.internal.org.objectweb.asm.Opcodes.IRETURN;
62
63
public class CallSiteDepContextTest {
64
static final MethodHandles.Lookup LOOKUP = MethodHandleHelper.IMPL_LOOKUP;
65
static final String CLASS_NAME = "compiler/jsr292/Test";
66
static final String METHOD_NAME = "m";
67
static final MethodType TYPE = MethodType.methodType(int.class);
68
69
static MutableCallSite mcs;
70
static MethodHandle bsmMH;
71
72
static {
73
try {
74
bsmMH = LOOKUP.findStatic(
75
CallSiteDepContextTest.class, "bootstrap",
76
MethodType.methodType(CallSite.class, MethodHandles.Lookup.class, String.class, MethodType.class));
77
} catch(Throwable e) {
78
throw new InternalError(e);
79
}
80
}
81
82
public static CallSite bootstrap(MethodHandles.Lookup caller,
83
String invokedName,
84
MethodType invokedType) {
85
return mcs;
86
}
87
88
static class T {
89
static int f1() { return 1; }
90
static int f2() { return 2; }
91
}
92
93
static byte[] getClassFile(String suffix) {
94
ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_FRAMES | ClassWriter.COMPUTE_MAXS);
95
MethodVisitor mv;
96
cw.visit(52, ACC_PUBLIC | ACC_SUPER, CLASS_NAME + suffix, null, "java/lang/Object", null);
97
{
98
mv = cw.visitMethod(ACC_PUBLIC | ACC_STATIC, METHOD_NAME, TYPE.toMethodDescriptorString(), null, null);
99
mv.visitCode();
100
Handle bsm = new Handle(H_INVOKESTATIC,
101
CallSiteDepContextTest.class.getName().replace(".", "/"),
102
"bootstrap",
103
bsmMH.type().toMethodDescriptorString());
104
mv.visitInvokeDynamicInsn("methodName", TYPE.toMethodDescriptorString(), bsm);
105
mv.visitInsn(IRETURN);
106
mv.visitMaxs(0, 0);
107
mv.visitEnd();
108
}
109
cw.visitEnd();
110
return cw.toByteArray();
111
}
112
113
private static void execute(int expected, MethodHandle... mhs) throws Throwable {
114
for (int i = 0; i < 20_000; i++) {
115
for (MethodHandle mh : mhs) {
116
int r = (int) mh.invokeExact();
117
if (r != expected) {
118
throw new Error(r + " != " + expected);
119
}
120
}
121
}
122
}
123
124
public static void testHiddenDepField() {
125
try {
126
Field f = MethodHandleHelper.MHN_CALL_SITE_CONTEXT_CLASS.getDeclaredField("vmdependencies");
127
throw new AssertionError("Context.dependencies field should be hidden");
128
} catch(NoSuchFieldException e) { /* expected */ }
129
}
130
131
public static void testSharedCallSite() throws Throwable {
132
Lookup lookup = MethodHandles.lookup();
133
Class<?> cls1 = lookup.defineHiddenClass(getClassFile("CS_1"), true).lookupClass();
134
Class<?> cls2 = lookup.defineHiddenClass(getClassFile("CS_2"), true).lookupClass();
135
136
MethodHandle[] mhs = new MethodHandle[] {
137
LOOKUP.findStatic(cls1, METHOD_NAME, TYPE),
138
LOOKUP.findStatic(cls2, METHOD_NAME, TYPE)
139
};
140
141
mcs = new MutableCallSite(LOOKUP.findStatic(T.class, "f1", TYPE));
142
execute(1, mhs);
143
mcs.setTarget(LOOKUP.findStatic(T.class, "f2", TYPE));
144
execute(2, mhs);
145
}
146
147
public static void testNonBoundCallSite() throws Throwable {
148
mcs = new MutableCallSite(LOOKUP.findStatic(T.class, "f1", TYPE));
149
150
// mcs.context == null
151
MethodHandle mh = mcs.dynamicInvoker();
152
execute(1, mh);
153
154
// mcs.context == cls1
155
Lookup lookup = MethodHandles.lookup();
156
Class<?> cls1 = lookup.defineHiddenClass(getClassFile("NonBound_1"), true).lookupClass();
157
MethodHandle mh1 = LOOKUP.findStatic(cls1, METHOD_NAME, TYPE);
158
159
execute(1, mh1);
160
161
mcs.setTarget(LOOKUP.findStatic(T.class, "f2", TYPE));
162
163
execute(2, mh, mh1);
164
}
165
166
static ReferenceQueue rq = new ReferenceQueue();
167
static PhantomReference ref;
168
169
public static void testGC(boolean clear, boolean precompile) throws Throwable {
170
String id = "_" + clear + "_" + precompile;
171
172
mcs = new MutableCallSite(LOOKUP.findStatic(T.class, "f1", TYPE));
173
174
Lookup lookup = MethodHandles.lookup();
175
Class<?>[] cls = new Class[] {
176
lookup.defineHiddenClass(getClassFile("GC_1"), true).lookupClass(),
177
lookup.defineHiddenClass(getClassFile("GC_2"), true).lookupClass(),
178
};
179
180
MethodHandle[] mhs = new MethodHandle[] {
181
LOOKUP.findStatic(cls[0], METHOD_NAME, TYPE),
182
LOOKUP.findStatic(cls[1], METHOD_NAME, TYPE),
183
};
184
185
// mcs.context == cls[0]
186
int r = (int) mhs[0].invokeExact();
187
188
execute(1, mhs);
189
190
ref = new PhantomReference<>(cls[0], rq);
191
cls[0] = lookup.defineHiddenClass(getClassFile("GC_3"), true).lookupClass();
192
mhs[0] = LOOKUP.findStatic(cls[0], METHOD_NAME, TYPE);
193
194
do {
195
System.gc();
196
try {
197
Reference ref1 = rq.remove(100);
198
if (ref1 == ref) {
199
break;
200
}
201
} catch(InterruptedException e) { /* ignore */ }
202
} while (true);
203
204
if (clear) {
205
ref.clear();
206
System.gc(); // Ensure that the stale context is unloaded
207
}
208
if (precompile) {
209
execute(1, mhs);
210
}
211
mcs.setTarget(LOOKUP.findStatic(T.class, "f2", TYPE));
212
execute(2, mhs);
213
}
214
215
public static void main(String[] args) throws Throwable {
216
testHiddenDepField();
217
testSharedCallSite();
218
testNonBoundCallSite();
219
testGC(false, false);
220
testGC(false, true);
221
testGC( true, false);
222
testGC( true, true);
223
System.out.println("TEST PASSED");
224
}
225
}
226
227