8310848: Convert ClassDesc and MethodTypeDesc to be stored in static final fields

Reviewed-by: asotona
This commit is contained in:
Chen Liang 2023-06-29 12:32:52 +00:00 committed by Adam Sotona
parent e5744b8120
commit 07734f6dde
6 changed files with 112 additions and 92 deletions

View File

@ -25,6 +25,7 @@
import java.lang.constant.ClassDesc;
import java.lang.constant.ConstantDesc;
import java.lang.constant.ConstantDescs;
import java.lang.reflect.AccessFlag;
import java.util.ArrayDeque;
import java.util.Map;
@ -98,10 +99,13 @@ class PackageSnippets {
// @end
@interface Test{}
private static final ClassDesc CD_Foo = ClassDesc.of("Foo");
private static final ClassDesc CD_Bar = ClassDesc.of("Bar");
void singleClassRemap(ClassModel... allMyClasses) {
// @start region="singleClassRemap"
var classRemapper = ClassRemapper.of(
Map.of(ClassDesc.of("Foo"), ClassDesc.of("Bar")));
Map.of(CD_Foo, CD_Bar));
var cc = Classfile.of();
for (var classModel : allMyClasses) {
byte[] newBytes = classRemapper.remapClass(cc, classModel);
@ -207,7 +211,7 @@ class PackageSnippets {
!(cle instanceof FieldModel fm
&& !targetFieldNames.contains(fm.fieldName().stringValue()))
&& !(cle instanceof MethodModel mm
&& !"<init>".equals(mm.methodName().stringValue())
&& !ConstantDescs.INIT_NAME.equals(mm.methodName().stringValue())
&& !targetMethods.contains(mm.methodName().stringValue() + mm.methodType().stringValue())))
//and instrumentor class references remapped to target class
.andThen(instrumentorClassRemapper)))));

View File

@ -26,12 +26,11 @@ import java.lang.constant.ClassDesc;
import java.lang.constant.ConstantDescs;
import java.lang.constant.MethodTypeDesc;
import java.lang.invoke.MethodHandles;
import java.util.ArrayDeque;
import java.util.HashSet;
import java.util.Set;
import java.lang.reflect.AccessFlag;
import java.util.ArrayDeque;
import java.util.LinkedList;
import java.util.Map;
import java.util.function.Predicate;
import java.util.stream.Collectors;
@ -125,26 +124,33 @@ class PackageSnippets {
// @end
}
private static final ClassDesc CD_Hello = ClassDesc.of("Hello");
private static final ClassDesc CD_Foo = ClassDesc.of("Foo");
private static final ClassDesc CD_Bar = ClassDesc.of("Bar");
private static final ClassDesc CD_System = ClassDesc.of("java.lang.System");
private static final ClassDesc CD_PrintStream = ClassDesc.of("java.io.PrintStream");
private static final MethodTypeDesc MTD_void_StringArray = MethodTypeDesc.of(ConstantDescs.CD_void, ConstantDescs.CD_String.arrayType());
private static final MethodTypeDesc MTD_void_String = MethodTypeDesc.of(ConstantDescs.CD_void, ConstantDescs.CD_String);
void writeHelloWorld() {
// @start region="helloWorld"
byte[] bytes = Classfile.of().build(ClassDesc.of("Hello"), cb -> {
byte[] bytes = Classfile.of().build(CD_Hello, cb -> {
cb.withFlags(AccessFlag.PUBLIC);
cb.withMethod("<init>", MethodTypeDesc.of(ConstantDescs.CD_void), Classfile.ACC_PUBLIC,
cb.withMethod(ConstantDescs.INIT_NAME, ConstantDescs.MTD_void, Classfile.ACC_PUBLIC,
mb -> mb.withCode(
b -> b.aload(0)
.invokespecial(ConstantDescs.CD_Object, "<init>",
MethodTypeDesc.of(ConstantDescs.CD_void))
.invokespecial(ConstantDescs.CD_Object, ConstantDescs.INIT_NAME,
ConstantDescs.MTD_void)
.returnInstruction(TypeKind.VoidType)
)
)
.withMethod("main", MethodTypeDesc.of(ConstantDescs.CD_void, ConstantDescs.CD_String.arrayType()),
.withMethod("main", MTD_void_StringArray,
Classfile.ACC_PUBLIC,
mb -> mb.withFlags(AccessFlag.STATIC, AccessFlag.PUBLIC)
.withCode(
b -> b.getstatic(ClassDesc.of("java.lang.System"), "out", ClassDesc.of("java.io.PrintStream"))
b -> b.getstatic(CD_System, "out", CD_PrintStream)
.constantInstruction(Opcode.LDC, "Hello World")
.invokevirtual(ClassDesc.of("java.io.PrintStream"), "println",
MethodTypeDesc.of(ConstantDescs.CD_void, ConstantDescs.CD_String))
.invokevirtual(CD_PrintStream, "println", MTD_void_String)
.returnInstruction(TypeKind.VoidType)
));
});
@ -182,7 +188,7 @@ class PackageSnippets {
if (e instanceof InvokeInstruction i
&& i.owner().asInternalName().equals("Foo")
&& i.opcode() == Opcode.INVOKESTATIC)
b.invokeInstruction(i.opcode(), ClassDesc.of("Bar"), i.name().stringValue(), i.typeSymbol(), i.isInterface());
b.invokeInstruction(i.opcode(), CD_Bar, i.name().stringValue(), i.typeSymbol(), i.isInterface());
else b.with(e);
};
// @end
@ -192,10 +198,9 @@ class PackageSnippets {
// @start region="instrumentCallsTransform"
CodeTransform instrumentCalls = (b, e) -> {
if (e instanceof InvokeInstruction i) {
b.getstatic(ClassDesc.of("java.lang.System"), "out", ClassDesc.of("java.io.PrintStream"))
b.getstatic(CD_System, "out", CD_PrintStream)
.constantInstruction(Opcode.LDC, i.name().stringValue())
.invokevirtual(ClassDesc.of("java.io.PrintStream"), "println",
MethodTypeDesc.of(ConstantDescs.CD_void, ConstantDescs.CD_String));
.invokevirtual(CD_PrintStream, "println", MTD_void_String);
}
b.with(e);
};
@ -217,7 +222,7 @@ class PackageSnippets {
for (CodeElement e : xm) {
if (e instanceof InvokeInstruction i && i.owner().asInternalName().equals("Foo")
&& i.opcode() == Opcode.INVOKESTATIC)
codeBuilder.invokeInstruction(i.opcode(), ClassDesc.of("Bar"),
codeBuilder.invokeInstruction(i.opcode(), CD_Bar,
i.name().stringValue(), i.typeSymbol(), i.isInterface());
else codeBuilder.with(e);
}});
@ -303,7 +308,7 @@ class PackageSnippets {
!(cle instanceof FieldModel fm
&& !targetFieldNames.contains(fm.fieldName().stringValue()))
&& !(cle instanceof MethodModel mm
&& !"<init>".equals(mm.methodName().stringValue())
&& !ConstantDescs.INIT_NAME.equals(mm.methodName().stringValue())
&& !targetMethods.contains(mm.methodName().stringValue() + mm.methodType().stringValue())))
//and instrumentor class references remapped to target class
.andThen(instrumentorClassRemapper)))));

View File

@ -118,6 +118,8 @@ public final class SystemModulesPlugin extends AbstractPlugin {
ClassDesc.ofInternalName("jdk/internal/module/SystemModules");
private static final ClassDesc CD_SYSTEM_MODULES_MAP =
ClassDesc.ofInternalName(SYSTEM_MODULES_MAP_CLASSNAME);
private static final MethodTypeDesc MTD_StringArray = MethodTypeDesc.of(CD_String.arrayType());
private static final MethodTypeDesc MTD_SystemModules = MethodTypeDesc.of(CD_SYSTEM_MODULES);
private boolean enabled;
public SystemModulesPlugin() {
@ -516,6 +518,18 @@ public final class SystemModulesPlugin extends AbstractPlugin {
ClassDesc.ofInternalName("jdk/internal/module/ModuleHashes");
private static final ClassDesc CD_MODULE_RESOLUTION =
ClassDesc.ofInternalName("jdk/internal/module/ModuleResolution");
private static final ClassDesc CD_Map_Entry = ClassDesc.ofInternalName("java/util/Map$Entry");
private static final MethodTypeDesc MTD_boolean = MethodTypeDesc.of(CD_boolean);
private static final MethodTypeDesc MTD_ModuleDescriptorArray = MethodTypeDesc.of(CD_MODULE_DESCRIPTOR.arrayType());
private static final MethodTypeDesc MTD_ModuleTargetArray = MethodTypeDesc.of(CD_MODULE_TARGET.arrayType());
private static final MethodTypeDesc MTD_void_String = MethodTypeDesc.of(CD_void, CD_String);
private static final MethodTypeDesc MTD_void_int = MethodTypeDesc.of(CD_void, CD_int);
private static final MethodTypeDesc MTD_ModuleHashesArray = MethodTypeDesc.of(CD_MODULE_HASHES.arrayType());
private static final MethodTypeDesc MTD_ModuleResolutionArray = MethodTypeDesc.of(CD_MODULE_RESOLUTION.arrayType());
private static final MethodTypeDesc MTD_Map = MethodTypeDesc.of(CD_Map);
private static final MethodTypeDesc MTD_MapEntry_Object_Object = MethodTypeDesc.of(CD_Map_Entry, CD_Object, CD_Object);
private static final MethodTypeDesc MTD_Map_MapEntryArray = MethodTypeDesc.of(CD_Map, CD_Map_Entry.arrayType());
private static final MethodTypeDesc MTD_Set_ObjectArray = MethodTypeDesc.of(CD_Set, CD_Object.arrayType());
private static final int MAX_LOCAL_VARS = 256;
@ -616,13 +630,13 @@ public final class SystemModulesPlugin extends AbstractPlugin {
*/
private void genConstructor(ClassBuilder clb) {
clb.withMethodBody(
"<init>",
MethodTypeDesc.of(CD_void),
INIT_NAME,
MTD_void,
ACC_PUBLIC,
cob -> cob.aload(0)
.invokespecial(CD_Object,
"<init>",
MethodTypeDesc.of(CD_void))
INIT_NAME,
MTD_void)
.return_());
}
@ -638,7 +652,7 @@ public final class SystemModulesPlugin extends AbstractPlugin {
clb.withMethodBody(
"hasSplitPackages",
MethodTypeDesc.of(CD_boolean),
MTD_boolean,
ACC_PUBLIC,
cob -> cob.constantInstruction(hasSplitPackages ? 1 : 0)
.ireturn());
@ -656,7 +670,7 @@ public final class SystemModulesPlugin extends AbstractPlugin {
clb.withMethodBody(
"hasIncubatorModules",
MethodTypeDesc.of(CD_boolean),
MTD_boolean,
ACC_PUBLIC,
cob -> cob.constantInstruction(hasIncubatorModules ? 1 : 0)
.ireturn());
@ -668,7 +682,7 @@ public final class SystemModulesPlugin extends AbstractPlugin {
private void genModuleDescriptorsMethod(ClassBuilder clb) {
clb.withMethodBody(
"moduleDescriptors",
MethodTypeDesc.of(CD_MODULE_DESCRIPTOR.arrayType()),
MTD_ModuleDescriptorArray,
ACC_PUBLIC,
cob -> {
cob.constantInstruction(moduleInfos.size())
@ -693,7 +707,7 @@ public final class SystemModulesPlugin extends AbstractPlugin {
private void genModuleTargetsMethod(ClassBuilder clb) {
clb.withMethodBody(
"moduleTargets",
MethodTypeDesc.of(CD_MODULE_TARGET.arrayType()),
MTD_ModuleTargetArray,
ACC_PUBLIC,
cob -> {
cob.constantInstruction(moduleInfos.size())
@ -726,8 +740,8 @@ public final class SystemModulesPlugin extends AbstractPlugin {
.dup()
.constantInstruction(minfo.target().targetPlatform())
.invokespecial(CD_MODULE_TARGET,
"<init>",
MethodTypeDesc.of(CD_void, CD_String));
INIT_NAME,
MTD_void_String);
cob.aastore();
}
@ -744,7 +758,7 @@ public final class SystemModulesPlugin extends AbstractPlugin {
private void genModuleHashesMethod(ClassBuilder clb) {
clb.withMethodBody(
"moduleHashes",
MethodTypeDesc.of(CD_MODULE_HASHES.arrayType()),
MTD_ModuleHashesArray,
ACC_PUBLIC,
cob -> {
cob.constantInstruction(moduleInfos.size())
@ -771,7 +785,7 @@ public final class SystemModulesPlugin extends AbstractPlugin {
private void genModuleResolutionsMethod(ClassBuilder clb) {
clb.withMethodBody(
"moduleResolutions",
MethodTypeDesc.of(CD_MODULE_RESOLUTION.arrayType()),
MTD_ModuleResolutionArray,
ACC_PUBLIC,
cob -> {
cob.constantInstruction(moduleInfos.size())
@ -787,8 +801,8 @@ public final class SystemModulesPlugin extends AbstractPlugin {
.dup()
.constantInstruction(minfo.moduleResolution().value())
.invokespecial(CD_MODULE_RESOLUTION,
"<init>",
MethodTypeDesc.of(CD_void, CD_int))
INIT_NAME,
MTD_void_int)
.aastore();
}
}
@ -822,7 +836,7 @@ public final class SystemModulesPlugin extends AbstractPlugin {
boolean dedup) {
clb.withMethodBody(
methodName,
MethodTypeDesc.of(CD_Map),
MTD_Map,
ACC_PUBLIC,
cob -> {
@ -852,7 +866,7 @@ public final class SystemModulesPlugin extends AbstractPlugin {
// new Map$Entry[size]
cob.constantInstruction(map.size())
.anewarray(ClassDesc.ofInternalName("java/util/Map$Entry"));
.anewarray(CD_Map_Entry);
int index = 0;
for (var e : new TreeMap<>(map).entrySet()) {
@ -871,11 +885,9 @@ public final class SystemModulesPlugin extends AbstractPlugin {
cob.aload(varIndex);
}
MethodTypeDesc desc = MethodTypeDesc.ofDescriptor(
"(Ljava/lang/Object;Ljava/lang/Object;)Ljava/util/Map$Entry;");
cob.invokestatic(CD_Map,
"entry",
desc,
MTD_MapEntry_Object_Object,
true)
.aastore();
index++;
@ -884,8 +896,7 @@ public final class SystemModulesPlugin extends AbstractPlugin {
// invoke Map.ofEntries(Map$Entry[])
cob.invokestatic(CD_Map,
"ofEntries",
MethodTypeDesc.ofDescriptor(
"([Ljava/util/Map$Entry;)Ljava/util/Map;"),
MTD_Map_MapEntryArray,
true)
.areturn();
});
@ -912,8 +923,7 @@ public final class SystemModulesPlugin extends AbstractPlugin {
}
cob.invokestatic(CD_Set,
"of",
MethodTypeDesc.ofDescriptor(
"([Ljava/lang/Object;)Ljava/util/Set;"),
MTD_Set_ObjectArray,
true);
} else {
for (String element : sorted(set)) {
@ -968,6 +978,9 @@ public final class SystemModulesPlugin extends AbstractPlugin {
static final MethodTypeDesc MTD_SET = MethodTypeDesc.of(CD_MODULE_BUILDER, CD_Set);
static final MethodTypeDesc MTD_STRING = MethodTypeDesc.of(CD_MODULE_BUILDER, CD_String);
static final MethodTypeDesc MTD_BOOLEAN = MethodTypeDesc.of(CD_MODULE_BUILDER, CD_boolean);
static final MethodTypeDesc MTD_void_String = MethodTypeDesc.of(CD_void, CD_String);
static final MethodTypeDesc MTD_ModuleDescriptor_int = MethodTypeDesc.of(CD_MODULE_DESCRIPTOR, CD_int);
static final MethodTypeDesc MTD_List_ObjectArray = MethodTypeDesc.of(CD_List, CD_Object.arrayType());
final CodeBuilder cob;
final ModuleDescriptor md;
@ -1020,8 +1033,8 @@ public final class SystemModulesPlugin extends AbstractPlugin {
.dup()
.constantInstruction(md.name())
.invokespecial(CD_MODULE_BUILDER,
"<init>",
MethodTypeDesc.of(CD_void, CD_String))
INIT_NAME,
MTD_void_String)
.astore(BUILDER_VAR);
if (md.isOpen()) {
@ -1057,7 +1070,7 @@ public final class SystemModulesPlugin extends AbstractPlugin {
.constantInstruction(md.hashCode())
.invokevirtual(CD_MODULE_BUILDER,
"build",
MethodTypeDesc.of(CD_MODULE_DESCRIPTOR, CD_int))
MTD_ModuleDescriptor_int)
.aastore();
}
@ -1283,8 +1296,7 @@ public final class SystemModulesPlugin extends AbstractPlugin {
}
cob.invokestatic(CD_List,
"of",
MethodTypeDesc.ofDescriptor(
"([Ljava/lang/Object;)Ljava/util/List;"),
MTD_List_ObjectArray,
true)
.invokestatic(CD_MODULE_BUILDER,
"newProvides",
@ -1343,6 +1355,8 @@ public final class SystemModulesPlugin extends AbstractPlugin {
ClassDesc.ofInternalName("jdk/internal/module/ModuleHashes$Builder");
static final MethodTypeDesc STRING_BYTE_ARRAY_SIG =
MethodTypeDesc.of(MODULE_HASHES_BUILDER, CD_String, CD_byte.arrayType());
static final MethodTypeDesc MTD_void_String_int = MethodTypeDesc.of(CD_void, CD_String, CD_int);
static final MethodTypeDesc MTD_ModuleHashes = MethodTypeDesc.of(CD_MODULE_HASHES);
final ModuleHashes recordedHashes;
final CodeBuilder cob;
@ -1385,8 +1399,8 @@ public final class SystemModulesPlugin extends AbstractPlugin {
.constantInstruction(recordedHashes.algorithm())
.constantInstruction(((4 * recordedHashes.names().size()) / 3) + 1)
.invokespecial(MODULE_HASHES_BUILDER,
"<init>",
MethodTypeDesc.of(CD_void, CD_String, CD_int))
INIT_NAME,
MTD_void_String_int)
.astore(BUILDER_VAR)
.aload(BUILDER_VAR);
}
@ -1402,7 +1416,7 @@ public final class SystemModulesPlugin extends AbstractPlugin {
.aload(BUILDER_VAR)
.invokevirtual(MODULE_HASHES_BUILDER,
"build",
MethodTypeDesc.of(CD_MODULE_HASHES))
MTD_ModuleHashes)
.aastore();
}
@ -1551,6 +1565,9 @@ public final class SystemModulesPlugin extends AbstractPlugin {
* it will use a new local variable retrieved from the nextLocalVar
*/
static class SetBuilder<T extends Comparable<T>> {
private static final MethodTypeDesc MTD_Set_ObjectArray = MethodTypeDesc.of(
CD_Set, CD_Object.arrayType());
private final Set<T> elements;
private final int defaultVarIndex;
private final IntSupplier nextLocalVar;
@ -1632,8 +1649,7 @@ public final class SystemModulesPlugin extends AbstractPlugin {
}
cob.invokestatic(CD_Set,
"of",
MethodTypeDesc.ofDescriptor(
"([Ljava/lang/Object;)Ljava/util/Set;"),
MTD_Set_ObjectArray,
true);
}
cob.astore(index);
@ -1683,43 +1699,43 @@ public final class SystemModulesPlugin extends AbstractPlugin {
// <init>
.withMethodBody(
"<init>",
MethodTypeDesc.of(CD_void),
INIT_NAME,
MTD_void,
0,
cob -> cob.aload(0)
.invokespecial(CD_Object,
"<init>",
MethodTypeDesc.of(CD_void))
INIT_NAME,
MTD_void)
.return_())
// allSystemModules()
.withMethodBody(
"allSystemModules",
MethodTypeDesc.of(CD_SYSTEM_MODULES),
MTD_SystemModules,
ACC_STATIC,
cob -> cob.new_(allSystemModules)
.dup()
.invokespecial(allSystemModules,
"<init>",
MethodTypeDesc.of(CD_void))
INIT_NAME,
MTD_void)
.areturn())
// defaultSystemModules()
.withMethodBody(
"defaultSystemModules",
MethodTypeDesc.of(CD_SYSTEM_MODULES),
MTD_SystemModules,
ACC_STATIC,
cob -> cob.new_(defaultSystemModules)
.dup()
.invokespecial(defaultSystemModules,
"<init>",
MethodTypeDesc.of(CD_void))
INIT_NAME,
MTD_void)
.areturn())
// moduleNames()
.withMethodBody(
"moduleNames",
MethodTypeDesc.of(CD_String.arrayType()),
MTD_StringArray,
ACC_STATIC,
cob -> {
cob.constantInstruction(map.size());
@ -1740,7 +1756,7 @@ public final class SystemModulesPlugin extends AbstractPlugin {
// classNames()
.withMethodBody(
"classNames",
MethodTypeDesc.of(CD_String.arrayType()),
MTD_StringArray,
ACC_STATIC,
cob -> {
cob.constantInstruction(map.size())

View File

@ -26,7 +26,6 @@ package jdk.jshell.execution;
import java.lang.constant.ClassDesc;
import java.lang.constant.ConstantDescs;
import java.lang.constant.MethodTypeDesc;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
@ -77,14 +76,13 @@ public class LocalExecutionControl extends DirectExecutionControl {
private static final String CANCEL_CLASS = "REPL.$Cancel$";
private static final ClassDesc CD_Cancel = ClassDesc.of(CANCEL_CLASS);
private static final ClassDesc CD_ThreadDeath = ClassDesc.of("java.lang.ThreadDeath");
private static final MethodTypeDesc MTD_void = MethodTypeDesc.of(ConstantDescs.CD_void);
private static byte[] instrument(byte[] classFile) {
var cc = Classfile.of();
return cc.transform(cc.parse(classFile),
ClassTransform.transformingMethodBodies((cob, coe) -> {
if (coe instanceof BranchInstruction)
cob.invokestatic(CD_Cancel, "stopCheck", MTD_void);
cob.invokestatic(CD_Cancel, "stopCheck", ConstantDescs.MTD_void);
cob.with(coe);
}));
}
@ -93,11 +91,11 @@ public class LocalExecutionControl extends DirectExecutionControl {
return new ClassBytecodes(CANCEL_CLASS, Classfile.of().build(CD_Cancel, clb ->
clb.withFlags(Classfile.ACC_PUBLIC)
.withField("allStop", ConstantDescs.CD_boolean, Classfile.ACC_PUBLIC | Classfile.ACC_STATIC | Classfile.ACC_VOLATILE)
.withMethodBody("stopCheck", MTD_void, Classfile.ACC_PUBLIC | Classfile.ACC_STATIC, cob ->
.withMethodBody("stopCheck", ConstantDescs.MTD_void, Classfile.ACC_PUBLIC | Classfile.ACC_STATIC, cob ->
cob.getstatic(CD_Cancel, "allStop", ConstantDescs.CD_boolean)
.ifThenElse(tb -> tb.new_(CD_ThreadDeath)
.dup()
.invokespecial(CD_ThreadDeath, "<init>", MTD_void)
.invokespecial(CD_ThreadDeath, ConstantDescs.INIT_NAME, ConstantDescs.MTD_void)
.athrow(),
eb -> eb.return_()))));
}

View File

@ -27,14 +27,18 @@ package org.openjdk.bench.jdk.classfile;
import java.lang.constant.ClassDesc;
import java.lang.constant.MethodTypeDesc;
import static java.lang.constant.ConstantDescs.CD_String;
import static java.lang.constant.ConstantDescs.CD_void;
/**
* TestConstants
*/
public class TestConstants {
public static final ClassDesc CD_MyClass = ClassDesc.of("MyClass");
public static final ClassDesc CD_System = ClassDesc.of("java.lang.System");
public static final ClassDesc CD_PrintStream = ClassDesc.of("java.io.PrintStream");
public static final ClassDesc CD_ArrayList = ClassDesc.of("java.util.ArrayList");
public static final MethodTypeDesc MTD_INT_VOID = MethodTypeDesc.ofDescriptor("(I)V");
public static final MethodTypeDesc MTD_VOID = MethodTypeDesc.ofDescriptor("()V");
public static final MethodTypeDesc MTD_void_int = MethodTypeDesc.ofDescriptor("(I)V");
public static final MethodTypeDesc MTD_void_StringArray = MethodTypeDesc.of(CD_void, CD_String.arrayType());
}

View File

@ -31,22 +31,15 @@ import jdk.internal.classfile.TypeKind;
import jdk.internal.classfile.attribute.SourceFileAttribute;
import jdk.internal.org.objectweb.asm.*;
import org.openjdk.jmh.annotations.*;
import java.io.FileOutputStream;
import java.lang.constant.ClassDesc;
import static java.lang.constant.ConstantDescs.*;
import java.lang.constant.MethodTypeDesc;
import java.nio.file.Files;
import java.nio.file.Paths;
import static org.openjdk.bench.jdk.classfile.TestConstants.CD_PrintStream;
import static org.openjdk.bench.jdk.classfile.TestConstants.CD_System;
import static org.openjdk.bench.jdk.classfile.TestConstants.MTD_INT_VOID;
import static org.openjdk.bench.jdk.classfile.TestConstants.MTD_VOID;
import static jdk.internal.classfile.Opcode.*;
import static jdk.internal.classfile.TypeKind.*;
import static jdk.internal.classfile.TypeKind.IntType;
import static jdk.internal.org.objectweb.asm.Opcodes.V12;
import static org.openjdk.bench.jdk.classfile.TestConstants.*;
/**
* Write
@ -85,17 +78,17 @@ public class Write {
@BenchmarkMode(Mode.Throughput)
public byte[] asmStream() {
ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_FRAMES);
cw.visit(V12, Opcodes.ACC_PUBLIC, "MyClass", null, "java/lang/Object", null);
cw.visit(Opcodes.V12, Opcodes.ACC_PUBLIC, "MyClass", null, "java/lang/Object", null);
cw.visitSource("MyClass.java", null);
{
MethodVisitor mv = cw.visitMethod(0, "<init>", "()V", null, null);
MethodVisitor mv = cw.visitMethod(0, INIT_NAME, "()V", null, null);
mv.visitCode();
Label startLabel = new Label();
Label endLabel = new Label();
mv.visitLabel(startLabel);
mv.visitVarInsn(Opcodes.ALOAD, 0);
mv.visitMethodInsn(Opcodes.INVOKESPECIAL, "java/lang/Object", "<init>", "()V", false);
mv.visitMethodInsn(Opcodes.INVOKESPECIAL, "java/lang/Object", INIT_NAME, "()V", false);
mv.visitInsn(Opcodes.RETURN);
mv.visitLabel(endLabel);
mv.visitLocalVariable("this", "LMyClass;", null, startLabel, endLabel, 1);
@ -149,18 +142,18 @@ public class Write {
@BenchmarkMode(Mode.Throughput)
public byte[] jdkTree() {
byte[] bytes = Classfile.of().build(ClassDesc.of("MyClass"), cb -> {
byte[] bytes = Classfile.of().build(CD_MyClass, cb -> {
cb.withFlags(AccessFlag.PUBLIC);
cb.withVersion(52, 0);
cb.with(SourceFileAttribute.of(cb.constantPool().utf8Entry(("MyClass.java"))))
.withMethod("<init>", MethodTypeDesc.of(CD_void), 0, mb -> mb
.withMethod(INIT_NAME, MTD_void, 0, mb -> mb
.withCode(codeb -> codeb.loadInstruction(TypeKind.ReferenceType, 0)
.invokeInstruction(INVOKESPECIAL, CD_Object, "<init>", MTD_VOID, false)
.invokeInstruction(INVOKESPECIAL, CD_Object, INIT_NAME, MTD_void, false)
.returnInstruction(VoidType)
)
);
for (int xi = 0; xi < 40; ++xi) {
cb.withMethod("main" + ((xi == 0) ? "" : "" + xi), MethodTypeDesc.of(CD_void, CD_String.arrayType()),
cb.withMethod("main" + ((xi == 0) ? "" : "" + xi), MTD_void_StringArray,
AccessFlags.ofMethod(AccessFlag.STATIC, AccessFlag.PUBLIC).flagsMask(),
mb -> mb.withCode(c0 -> {
jdk.internal.classfile.Label loopTop = c0.newLabel();
@ -184,7 +177,7 @@ public class Write {
.labelBinding(loopEnd)
.fieldInstruction(GETSTATIC, CD_System, "out", CD_PrintStream) // 13
.loadInstruction(IntType, vFac)
.invokeInstruction(INVOKEVIRTUAL, CD_PrintStream, "println", MTD_INT_VOID, false) // 15
.invokeInstruction(INVOKEVIRTUAL, CD_PrintStream, "println", MTD_void_int, false) // 15
.returnInstruction(VoidType);
}));
}
@ -197,18 +190,18 @@ public class Write {
@BenchmarkMode(Mode.Throughput)
public byte[] jdkTreePrimitive() {
byte[] bytes = Classfile.of().build(ClassDesc.of("MyClass"), cb -> {
byte[] bytes = Classfile.of().build(CD_MyClass, cb -> {
cb.withFlags(AccessFlag.PUBLIC);
cb.withVersion(52, 0);
cb.with(SourceFileAttribute.of(cb.constantPool().utf8Entry(("MyClass.java"))))
.withMethod("<init>", MethodTypeDesc.of(CD_void), 0,
.withMethod(INIT_NAME, MTD_void, 0,
mb -> mb.withCode(codeb -> codeb.loadInstruction(ReferenceType, 0)
.invokeInstruction(INVOKESPECIAL, CD_Object, "<init>", MTD_VOID, false)
.invokeInstruction(INVOKESPECIAL, CD_Object, INIT_NAME, MTD_void, false)
.returnInstruction(VoidType)
)
);
for (int xi = 0; xi < 40; ++xi) {
cb.withMethod("main" + ((xi == 0) ? "" : "" + xi), MethodTypeDesc.of(CD_void, CD_String.arrayType()),
cb.withMethod("main" + ((xi == 0) ? "" : "" + xi), MTD_void_StringArray,
AccessFlags.ofMethod(AccessFlag.STATIC, AccessFlag.PUBLIC).flagsMask(),
mb -> mb.withCode(c0 -> {
jdk.internal.classfile.Label loopTop = c0.newLabel();
@ -232,7 +225,7 @@ public class Write {
.labelBinding(loopEnd)
.fieldInstruction(GETSTATIC, CD_System, "out", CD_PrintStream) // 13
.loadInstruction(IntType, 1)
.invokeInstruction(INVOKEVIRTUAL, CD_PrintStream, "println", MTD_INT_VOID, false) // 15
.invokeInstruction(INVOKEVIRTUAL, CD_PrintStream, "println", MTD_void_int, false) // 15
.returnInstruction(VoidType);
}));
}