8287064: Modernize ProxyGenerator.PrimitiveTypeInfo

Reviewed-by: rriggs, mchung
This commit is contained in:
liach 2022-05-31 18:29:07 +00:00 committed by Roger Riggs
parent d5b6c7bde1
commit 37a513003c

View file

@ -31,6 +31,7 @@ import jdk.internal.org.objectweb.asm.Label;
import jdk.internal.org.objectweb.asm.MethodVisitor; import jdk.internal.org.objectweb.asm.MethodVisitor;
import jdk.internal.org.objectweb.asm.Opcodes; import jdk.internal.org.objectweb.asm.Opcodes;
import jdk.internal.org.objectweb.asm.Type; import jdk.internal.org.objectweb.asm.Type;
import sun.invoke.util.Wrapper;
import sun.security.action.GetBooleanAction; import sun.security.action.GetBooleanAction;
import java.io.IOException; import java.io.IOException;
@ -39,7 +40,6 @@ import java.nio.file.Files;
import java.nio.file.Path; import java.nio.file.Path;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
import java.util.HashMap;
import java.util.LinkedHashMap; import java.util.LinkedHashMap;
import java.util.List; import java.util.List;
import java.util.ListIterator; import java.util.ListIterator;
@ -813,21 +813,7 @@ final class ProxyGenerator extends ClassWriter {
if (type.isPrimitive()) { if (type.isPrimitive()) {
PrimitiveTypeInfo prim = PrimitiveTypeInfo.get(type); PrimitiveTypeInfo prim = PrimitiveTypeInfo.get(type);
if (type == int.class || mv.visitVarInsn(prim.loadOpcode, slot);
type == boolean.class ||
type == byte.class ||
type == char.class ||
type == short.class) {
mv.visitVarInsn(ILOAD, slot);
} else if (type == long.class) {
mv.visitVarInsn(LLOAD, slot);
} else if (type == float.class) {
mv.visitVarInsn(FLOAD, slot);
} else if (type == double.class) {
mv.visitVarInsn(DLOAD, slot);
} else {
throw new AssertionError();
}
mv.visitMethodInsn(INVOKESTATIC, prim.wrapperClassName, "valueOf", mv.visitMethodInsn(INVOKESTATIC, prim.wrapperClassName, "valueOf",
prim.wrapperValueOfDesc, false); prim.wrapperValueOfDesc, false);
} else { } else {
@ -849,21 +835,7 @@ final class ProxyGenerator extends ClassWriter {
prim.wrapperClassName, prim.wrapperClassName,
prim.unwrapMethodName, prim.unwrapMethodDesc, false); prim.unwrapMethodName, prim.unwrapMethodDesc, false);
if (type == int.class || mv.visitInsn(prim.returnOpcode);
type == boolean.class ||
type == byte.class ||
type == char.class ||
type == short.class) {
mv.visitInsn(IRETURN);
} else if (type == long.class) {
mv.visitInsn(LRETURN);
} else if (type == float.class) {
mv.visitInsn(FRETURN);
} else if (type == double.class) {
mv.visitInsn(DRETURN);
} else {
throw new AssertionError();
}
} else { } else {
mv.visitTypeInsn(CHECKCAST, dotToSlash(type.getName())); mv.visitTypeInsn(CHECKCAST, dotToSlash(type.getName()));
mv.visitInsn(ARETURN); mv.visitInsn(ARETURN);
@ -952,65 +924,73 @@ final class ProxyGenerator extends ClassWriter {
} }
/** /**
* A PrimitiveTypeInfo object contains assorted information about * A PrimitiveTypeInfo object contains bytecode-related information about
* a primitive type in its public fields. The struct for a particular * a primitive type in its instance fields. The struct for a particular
* primitive type can be obtained using the static "get" method. * primitive type can be obtained using the static "get" method.
*/ */
private static class PrimitiveTypeInfo { private enum PrimitiveTypeInfo {
BYTE(byte.class, ILOAD, IRETURN),
private static Map<Class<?>, PrimitiveTypeInfo> table = new HashMap<>(); CHAR(char.class, ILOAD, IRETURN),
DOUBLE(double.class, DLOAD, DRETURN),
static { FLOAT(float.class, FLOAD, FRETURN),
add(byte.class, Byte.class); INT(int.class, ILOAD, IRETURN),
add(char.class, Character.class); LONG(long.class, LLOAD, LRETURN),
add(double.class, Double.class); SHORT(short.class, ILOAD, IRETURN),
add(float.class, Float.class); BOOLEAN(boolean.class, ILOAD, IRETURN);
add(int.class, Integer.class);
add(long.class, Long.class);
add(short.class, Short.class);
add(boolean.class, Boolean.class);
}
/** /**
* name of corresponding wrapper class * internal name of corresponding wrapper class
*/ */
private String wrapperClassName; private final String wrapperClassName;
/** /**
* method descriptor for wrapper class "valueOf" factory method * method descriptor for wrapper class "valueOf" factory method
*/ */
private String wrapperValueOfDesc; private final String wrapperValueOfDesc;
/** /**
* name of wrapper class method for retrieving primitive value * name of wrapper class method for retrieving primitive value
*/ */
private String unwrapMethodName; private final String unwrapMethodName;
/** /**
* descriptor of same method * descriptor of same method
*/ */
private String unwrapMethodDesc; private final String unwrapMethodDesc;
/**
* Load opcode used by this primitive
*/
private final int loadOpcode;
/**
* Return opcode used by this primitive
*/
private final int returnOpcode;
private PrimitiveTypeInfo(Class<?> primitiveClass, Class<?> wrapperClass) { PrimitiveTypeInfo(Class<?> primitiveClass, int loadOpcode, int returnOpcode) {
assert primitiveClass.isPrimitive(); assert primitiveClass.isPrimitive();
assert returnOpcode - IRETURN == loadOpcode - ILOAD;
/** Wrapper wrapper = Wrapper.forPrimitiveType(primitiveClass);
* "base type" used in various descriptors (see JVMS section 4.3.2) // single-char BaseType descriptor (see JVMS section 4.3.2)
*/ String baseTypeString = wrapper.basicTypeString();
String baseTypeString = var wrapperType = wrapper.wrapperType();
Array.newInstance(primitiveClass, 0) wrapperClassName = dotToSlash(wrapperType.getName());
.getClass().getName().substring(1);
wrapperClassName = dotToSlash(wrapperClass.getName());
wrapperValueOfDesc = wrapperValueOfDesc =
"(" + baseTypeString + ")L" + wrapperClassName + ";"; "(" + baseTypeString + ")" + wrapperType.descriptorString();
unwrapMethodName = primitiveClass.getName() + "Value"; unwrapMethodName = primitiveClass.getName() + "Value";
unwrapMethodDesc = "()" + baseTypeString; unwrapMethodDesc = "()" + baseTypeString;
} this.loadOpcode = loadOpcode;
this.returnOpcode = returnOpcode;
private static void add(Class<?> primitiveClass, Class<?> wrapperClass) {
table.put(primitiveClass,
new PrimitiveTypeInfo(primitiveClass, wrapperClass));
} }
public static PrimitiveTypeInfo get(Class<?> cl) { public static PrimitiveTypeInfo get(Class<?> cl) {
return table.get(cl); // Uses if chain for speed: 8284880
if (cl == int.class) return INT;
if (cl == long.class) return LONG;
if (cl == boolean.class) return BOOLEAN;
if (cl == short.class) return SHORT;
if (cl == byte.class) return BYTE;
if (cl == char.class) return CHAR;
if (cl == float.class) return FLOAT;
if (cl == double.class) return DOUBLE;
throw new AssertionError(cl);
} }
} }
} }