Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/mobile
Path: blob/master/test/hotspot/jtreg/vmTestbase/vm/mlvm/cp/share/GenFullCP.java
41162 views
1
/*
2
* Copyright (c) 2011, 2018, 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
package vm.mlvm.cp.share;
25
26
import jdk.internal.org.objectweb.asm.ByteVector;
27
import jdk.internal.org.objectweb.asm.ClassWriter;
28
import jdk.internal.org.objectweb.asm.ClassWriterExt;
29
import jdk.internal.org.objectweb.asm.MethodVisitor;
30
import jdk.internal.org.objectweb.asm.Opcodes;
31
import jdk.internal.org.objectweb.asm.Type;
32
33
import vm.mlvm.share.ClassfileGenerator;
34
import vm.mlvm.share.Env;
35
36
public abstract class GenFullCP extends ClassfileGenerator {
37
38
/**
39
* Generate field description for object type from class name:
40
* return "L" + className + ";";
41
* @param className Class name
42
* @return field descriptor representing the class type
43
*/
44
protected static String fd(String className) {
45
return "L" + className + ";";
46
}
47
48
// Universal constants
49
protected static final String JL_OBJECT = "java/lang/Object";
50
protected static final String JL_CLASS = "java/lang/Class";
51
protected static final String JL_CLASSLOADER = "java/lang/ClassLoader";
52
protected static final String JL_STRING = "java/lang/String";
53
protected static final String JL_RUNTIMEEXCEPTION = "java/lang/RuntimeException";
54
protected static final String JL_BOOTSTRAPMETHODERROR = "java/lang/BootstrapMethodError";
55
protected static final String JL_THROWABLE = "java/lang/Throwable";
56
protected static final String JLI_METHODTYPE = "java/lang/invoke/MethodType";
57
protected static final String JLI_METHODHANDLE = "java/lang/invoke/MethodHandle";
58
protected static final String JLI_METHODHANDLES = "java/lang/invoke/MethodHandles";
59
protected static final String JLI_METHODHANDLES_LOOKUP = "java/lang/invoke/MethodHandles$Lookup";
60
protected static final String JLI_CALLSITE = "java/lang/invoke/CallSite";
61
protected static final String JLI_CONSTANTCALLSITE = "java/lang/invoke/ConstantCallSite";
62
63
protected static final String VOID_NO_ARG_METHOD_SIGNATURE = "()V";
64
65
protected static final String NEW_INVOKE_SPECIAL_CLASS_NAME = "java/lang/invoke/NewInvokeSpecialCallSite";
66
protected static final String NEW_INVOKE_SPECIAL_BOOTSTRAP_METHOD_SIGNATURE = "(" + fd(JLI_METHODHANDLES_LOOKUP) + fd(JL_STRING) + fd(JLI_METHODTYPE) + ")V";
67
68
protected static final String INIT_METHOD_NAME = "<init>";
69
protected static final String STATIC_INIT_METHOD_NAME = "<clinit>";
70
71
// Generated class constants
72
protected static final int CLASSFILE_VERSION = 51;
73
74
protected static final int CP_CONST_COUNT = 65400;
75
protected static final int MAX_METHOD_SIZE = 65400;
76
protected static final int BYTES_PER_LDC = 5;
77
protected static final int LDC_PER_METHOD = MAX_METHOD_SIZE / BYTES_PER_LDC;
78
protected static final int METHOD_COUNT = CP_CONST_COUNT / LDC_PER_METHOD;
79
80
protected static final String PARENT_CLASS_NAME = JL_OBJECT;
81
82
protected static final String INIT_METHOD_SIGNATURE = VOID_NO_ARG_METHOD_SIGNATURE;
83
84
protected static final String MAIN_METHOD_NAME = "main";
85
protected static final String MAIN_METHOD_SIGNATURE = "(" + "[" + fd(JL_STRING) + ")V";
86
87
protected static final String TEST_METHOD_NAME = "test";
88
protected static final String TEST_METHOD_SIGNATURE = VOID_NO_ARG_METHOD_SIGNATURE;
89
90
protected static final String STATIC_FIELD_NAME = "testStatic";
91
protected static final String STATIC_FIELD_SIGNATURE = "Z";
92
93
protected static final String INSTANCE_FIELD_NAME = "testInstance";
94
protected static final String INSTANCE_FIELD_SIGNATURE = "Z";
95
96
protected static final String STATIC_BOOTSTRAP_FIELD_NAME = "testCSStatic";
97
protected static final String STATIC_BOOTSTRAP_FIELD_SIGNATURE = fd(JLI_CALLSITE);
98
99
protected static final String INSTANCE_BOOTSTRAP_FIELD_NAME = "testCSInstance";
100
protected static final String INSTANCE_BOOTSTRAP_FIELD_SIGNATURE = fd(JLI_CALLSITE);
101
102
protected static final String BOOTSTRAP_METHOD_NAME = "bootstrap";
103
protected static final String BOOTSTRAP_METHOD_SIGNATURE = "(" + fd(JLI_METHODHANDLES_LOOKUP) + fd(JL_STRING) + fd(JLI_METHODTYPE) + ")" + fd(JLI_CALLSITE);
104
105
protected static final String INSTANCE_BOOTSTRAP_METHOD_NAME = "bootstrapInstance";
106
protected static final String INSTANCE_BOOTSTRAP_METHOD_SIGNATURE = BOOTSTRAP_METHOD_SIGNATURE;
107
108
protected static final String TARGET_METHOD_NAME = "target";
109
protected static final String TARGET_METHOD_SIGNATURE = VOID_NO_ARG_METHOD_SIGNATURE;
110
111
protected static final String INSTANCE_TARGET_METHOD_NAME = "targetInstance";
112
protected static final String INSTANCE_TARGET_METHOD_SIGNATURE = VOID_NO_ARG_METHOD_SIGNATURE;
113
114
protected interface DummyInterface {
115
public void targetInstance();
116
}
117
118
// Helper methods
119
120
protected static String getDummyInterfaceClassName() {
121
return DummyInterface.class.getName().replace('.', '/');
122
}
123
124
protected static void createLogMsgCode(MethodVisitor mv, String msg) {
125
mv.visitLdcInsn(msg);
126
mv.visitMethodInsn(Opcodes.INVOKESTATIC, "vm/mlvm/share/Env", "traceVerbose", "(Ljava/lang/String;)V");
127
}
128
129
protected static void createThrowRuntimeExceptionCode(MethodVisitor mv, String msg) {
130
createThrowRuntimeExceptionCodeHelper(mv, msg, false);
131
}
132
133
// Expects a throwable (the cause) to be on top of the stack when called.
134
protected static void createThrowRuntimeExceptionCodeWithCause(MethodVisitor mv, String msg) {
135
createThrowRuntimeExceptionCodeHelper(mv, msg, true);
136
}
137
138
// If set_cause is true it expects a Throwable (the cause) to be on top of the stack when called.
139
protected static void createThrowRuntimeExceptionCodeHelper(MethodVisitor mv, String msg, boolean set_cause) {
140
mv.visitTypeInsn(Opcodes.NEW, JL_RUNTIMEEXCEPTION);
141
mv.visitInsn(Opcodes.DUP);
142
mv.visitLdcInsn(msg);
143
mv.visitMethodInsn(Opcodes.INVOKESPECIAL, JL_RUNTIMEEXCEPTION,
144
INIT_METHOD_NAME, "(" + fd(JL_STRING) + ")V");
145
if (set_cause) {
146
mv.visitInsn(Opcodes.SWAP);
147
mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, JL_RUNTIMEEXCEPTION,
148
"initCause", "(" + fd(JL_THROWABLE) + ")"+ fd(JL_THROWABLE));
149
}
150
mv.visitInsn(Opcodes.ATHROW);
151
}
152
153
protected static void createThrowRuntimeExceptionMethod(ClassWriter cw, boolean isStatic, String methodName, String methodSignature) {
154
MethodVisitor mv = cw.visitMethod(
155
Opcodes.ACC_PUBLIC | (isStatic ? Opcodes.ACC_STATIC : 0),
156
methodName, methodSignature,
157
null,
158
new String[0]);
159
160
createThrowRuntimeExceptionCode(mv, "Method " + methodName + methodSignature + " should not be called!");
161
162
mv.visitMaxs(-1, -1);
163
mv.visitEnd();
164
}
165
166
protected static void finishMethodCode(MethodVisitor mv) {
167
finishMethodCode(mv, Opcodes.RETURN);
168
}
169
170
protected static void finishMethodCode(MethodVisitor mv, int returnOpcode) {
171
mv.visitInsn(returnOpcode);
172
mv.visitMaxs(-1, -1);
173
mv.visitEnd();
174
}
175
176
protected void createClassInitMethod(ClassWriter cw) {
177
}
178
179
protected void createInitMethod(ClassWriter cw) {
180
MethodVisitor mv = cw.visitMethod(
181
Opcodes.ACC_PUBLIC,
182
INIT_METHOD_NAME, INIT_METHOD_SIGNATURE,
183
null,
184
new String[0]);
185
186
mv.visitIntInsn(Opcodes.ALOAD, 0);
187
mv.visitMethodInsn(Opcodes.INVOKESPECIAL,
188
PARENT_CLASS_NAME,
189
INIT_METHOD_NAME, INIT_METHOD_SIGNATURE);
190
191
createLogMsgCode(mv, fullClassName + " constructor called");
192
193
finishMethodCode(mv);
194
}
195
196
protected void createTargetMethod(ClassWriter cw) {
197
MethodVisitor mv = cw.visitMethod(
198
Opcodes.ACC_PUBLIC | Opcodes.ACC_STATIC,
199
TARGET_METHOD_NAME, TARGET_METHOD_SIGNATURE,
200
null,
201
new String[0]);
202
203
createLogMsgCode(mv, fullClassName + "." + TARGET_METHOD_NAME + TARGET_METHOD_SIGNATURE + " called");
204
205
finishMethodCode(mv);
206
}
207
208
protected void createBootstrapMethod(ClassWriter cw) {
209
createBootstrapMethod(cw, true, BOOTSTRAP_METHOD_NAME, BOOTSTRAP_METHOD_SIGNATURE);
210
}
211
212
protected void createBootstrapMethod(ClassWriter cw, boolean isStatic, String methodName, String methodSignature) {
213
MethodVisitor mv = cw.visitMethod(
214
(isStatic ? Opcodes.ACC_STATIC : 0) | Opcodes.ACC_PUBLIC,
215
methodName, methodSignature,
216
null, new String[0]);
217
218
createLogMsgCode(mv, fullClassName + "." + BOOTSTRAP_METHOD_NAME + BOOTSTRAP_METHOD_SIGNATURE + " called");
219
220
int argShift = isStatic ? 0 : 1;
221
222
mv.visitTypeInsn(Opcodes.NEW, JLI_CONSTANTCALLSITE);
223
mv.visitInsn(Opcodes.DUP);
224
mv.visitVarInsn(Opcodes.ALOAD, 0 + argShift);
225
mv.visitLdcInsn(Type.getObjectType(fullClassName));
226
mv.visitVarInsn(Opcodes.ALOAD, 1 + argShift);
227
mv.visitVarInsn(Opcodes.ALOAD, 2 + argShift);
228
mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL,
229
JLI_METHODHANDLES_LOOKUP, "findStatic",
230
"(" + fd(JL_CLASS) + fd(JL_STRING) + fd(JLI_METHODTYPE) + ")" + fd(JLI_METHODHANDLE));
231
mv.visitMethodInsn(Opcodes.INVOKESPECIAL, JLI_CONSTANTCALLSITE,
232
INIT_METHOD_NAME, "(" + fd(JLI_METHODHANDLE) + ")V");
233
234
finishMethodCode(mv, Opcodes.ARETURN);
235
}
236
237
@Override
238
public Klass[] generateBytecodes() {
239
240
// COMPUTE_FRAMES were disabled due to JDK-8079697
241
ClassWriterExt cw = new ClassWriterExt(/*ClassWriter.COMPUTE_FRAMES |*/ ClassWriter.COMPUTE_MAXS);
242
243
String[] interfaces = new String[1];
244
interfaces[0] = getDummyInterfaceClassName();
245
cw.visit(CLASSFILE_VERSION, Opcodes.ACC_PUBLIC, fullClassName, null, PARENT_CLASS_NAME, interfaces);
246
247
generateCommonData(cw);
248
249
MethodVisitor mainMV = cw.visitMethod(
250
Opcodes.ACC_PUBLIC | Opcodes.ACC_STATIC,
251
MAIN_METHOD_NAME, MAIN_METHOD_SIGNATURE,
252
null, new String[0]);
253
254
mainMV.visitTypeInsn(Opcodes.NEW, fullClassName);
255
mainMV.visitInsn(Opcodes.DUP);
256
mainMV.visitMethodInsn(Opcodes.INVOKESPECIAL, fullClassName, INIT_METHOD_NAME, INIT_METHOD_SIGNATURE);
257
258
int constCount = 0;
259
int methodNum = 0;
260
261
// TODO: check real CP size and also limit number of iterations in this cycle
262
while (constCount < CP_CONST_COUNT) {
263
final String methodName = TEST_METHOD_NAME + String.format("%02d", methodNum);
264
265
MethodVisitor mw = cw.visitMethod(
266
Opcodes.ACC_PUBLIC,
267
methodName, TEST_METHOD_SIGNATURE,
268
null, new String[0]);
269
270
generateTestMethodProlog(mw);
271
272
// TODO: check real CP size and also limit number of iterations in this cycle
273
while (constCount < CP_CONST_COUNT && cw.getBytecodeLength(mw) < MAX_METHOD_SIZE) {
274
generateCPEntryData(cw, mw);
275
++constCount;
276
}
277
278
generateTestMethodEpilog(mw);
279
280
mw.visitMaxs(-1, -1);
281
mw.visitEnd();
282
283
Env.traceNormal("Method " + fullClassName + "." + methodName + "(): "
284
+ constCount + " constants in CP, "
285
+ cw.getBytecodeLength(mw) + " bytes of code");
286
287
mainMV.visitInsn(Opcodes.DUP);
288
mainMV.visitMethodInsn(Opcodes.INVOKEVIRTUAL, fullClassName, methodName, TEST_METHOD_SIGNATURE);
289
290
++methodNum;
291
}
292
293
mainMV.visitInsn(Opcodes.POP);
294
finishMethodCode(mainMV);
295
296
cw.visitEnd();
297
return new Klass[] { new Klass(this.pkgName, this.shortClassName, MAIN_METHOD_NAME, MAIN_METHOD_SIGNATURE, cw.toByteArray()) };
298
}
299
300
protected void generateCommonData(ClassWriterExt cw) {
301
createClassInitMethod(cw);
302
createInitMethod(cw);
303
createTargetMethod(cw);
304
createBootstrapMethod(cw);
305
}
306
307
protected void generateTestMethodProlog(MethodVisitor mw) {
308
}
309
310
protected abstract void generateCPEntryData(ClassWriter cw, MethodVisitor mw);
311
312
protected void generateTestMethodEpilog(MethodVisitor mw) {
313
mw.visitInsn(Opcodes.RETURN);
314
}
315
316
}
317
318