--- a/jdk/src/java.base/share/classes/java/lang/invoke/BoundMethodHandle.java Tue Apr 11 21:59:26 2017 -0700
+++ b/jdk/src/java.base/share/classes/java/lang/invoke/BoundMethodHandle.java Wed Apr 12 05:14:51 2017 +0000
@@ -450,32 +450,29 @@
*/
static class Factory {
- static final String JLO_SIG = "Ljava/lang/Object;";
- static final String JLS_SIG = "Ljava/lang/String;";
- static final String JLC_SIG = "Ljava/lang/Class;";
- static final String MH = "java/lang/invoke/MethodHandle";
- static final String MH_SIG = "L"+MH+";";
- static final String BMH = "java/lang/invoke/BoundMethodHandle";
- static final String BMH_SIG = "L"+BMH+";";
- static final String SPECIES_DATA = "java/lang/invoke/BoundMethodHandle$SpeciesData";
- static final String SPECIES_DATA_SIG = "L"+SPECIES_DATA+";";
- static final String STABLE_SIG = "Ljdk/internal/vm/annotation/Stable;";
+ private static final String JLO_SIG = "Ljava/lang/Object;";
+ private static final String MH = "java/lang/invoke/MethodHandle";
+ private static final String MH_SIG = "L"+MH+";";
+ private static final String BMH = "java/lang/invoke/BoundMethodHandle";
+ private static final String BMH_NAME = "java.lang.invoke.BoundMethodHandle";
+ private static final String BMH_SIG = "L"+BMH+";";
+ private static final String SPECIES_DATA = "java/lang/invoke/BoundMethodHandle$SpeciesData";
+ private static final String SPECIES_DATA_SIG = "L"+SPECIES_DATA+";";
+ private static final String STABLE_SIG = "Ljdk/internal/vm/annotation/Stable;";
- static final String SPECIES_PREFIX_NAME = "Species_";
- static final String SPECIES_PREFIX_PATH = BMH + "$" + SPECIES_PREFIX_NAME;
- static final String SPECIES_CLASS_PREFIX = SPECIES_PREFIX_PATH.replace('/', '.');
+ private static final String SPECIES_PREFIX_NAME = "Species_";
+ private static final String SPECIES_PREFIX_PATH = BMH + "$" + SPECIES_PREFIX_NAME;
+ private static final String SPECIES_CLASS_PREFIX = BMH_NAME + "$" + SPECIES_PREFIX_NAME;
- static final String BMHSPECIES_DATA_EWI_SIG = "(B)" + SPECIES_DATA_SIG;
- static final String BMHSPECIES_DATA_GFC_SIG = "(" + JLS_SIG + JLC_SIG + ")" + SPECIES_DATA_SIG;
- static final String MYSPECIES_DATA_SIG = "()" + SPECIES_DATA_SIG;
- static final String VOID_SIG = "()V";
- static final String INT_SIG = "()I";
+ private static final String BMHSPECIES_DATA_EWI_SIG = "(B)" + SPECIES_DATA_SIG;
+ private static final String MYSPECIES_DATA_SIG = "()" + SPECIES_DATA_SIG;
+ private static final String INT_SIG = "()I";
- static final String SIG_INCIPIT = "(Ljava/lang/invoke/MethodType;Ljava/lang/invoke/LambdaForm;";
+ private static final String SIG_INCIPIT = "(Ljava/lang/invoke/MethodType;Ljava/lang/invoke/LambdaForm;";
- static final String[] E_THROWABLE = new String[] { "java/lang/Throwable" };
+ private static final String[] E_THROWABLE = new String[] { "java/lang/Throwable" };
- static final ConcurrentMap<String, Class<? extends BoundMethodHandle>> CLASS_CACHE = new ConcurrentHashMap<>();
+ private static final ConcurrentMap<String, Class<? extends BoundMethodHandle>> CLASS_CACHE = new ConcurrentHashMap<>();
/**
* Get a concrete subclass of BMH for a given combination of bound types.
@@ -830,15 +827,27 @@
private static String makeSignature(String types, boolean ctor) {
StringBuilder buf = new StringBuilder(SIG_INCIPIT);
- for (char c : types.toCharArray()) {
- buf.append(typeSig(c));
+ int len = types.length();
+ for (int i = 0; i < len; i++) {
+ buf.append(typeSig(types.charAt(i)));
}
return buf.append(')').append(ctor ? "V" : BMH_SIG).toString();
}
+ private static MethodType makeConstructorType(String types) {
+ int length = types.length();
+ Class<?> ptypes[] = new Class<?>[length + 2];
+ ptypes[0] = MethodType.class;
+ ptypes[1] = LambdaForm.class;
+ for (int i = 0; i < length; i++) {
+ ptypes[i + 2] = BasicType.basicType(types.charAt(i)).basicTypeClass();
+ }
+ return MethodType.makeImpl(BoundMethodHandle.class, ptypes, true);
+ }
+
static MethodHandle makeCbmhCtor(Class<? extends BoundMethodHandle> cbmh, String types) {
try {
- return LOOKUP.findStatic(cbmh, "make", MethodType.fromDescriptor(makeSignature(types, false), null));
+ return LOOKUP.findStatic(cbmh, "make", makeConstructorType(types));
} catch (NoSuchMethodException | IllegalAccessException | IllegalArgumentException | TypeNotPresentException e) {
throw newInternalError(e);
}
--- a/jdk/src/java.base/share/classes/java/lang/invoke/DirectMethodHandle.java Tue Apr 11 21:59:26 2017 -0700
+++ b/jdk/src/java.base/share/classes/java/lang/invoke/DirectMethodHandle.java Wed Apr 12 05:14:51 2017 +0000
@@ -224,12 +224,12 @@
assert(names.length == nameCursor);
if (doesAlloc) {
// names = { argx,y,z,... new C, init method }
- names[NEW_OBJ] = new Name(NF_allocateInstance, names[DMH_THIS]);
- names[GET_MEMBER] = new Name(NF_constructorMethod, names[DMH_THIS]);
+ names[NEW_OBJ] = new Name(getFunction(NF_allocateInstance), names[DMH_THIS]);
+ names[GET_MEMBER] = new Name(getFunction(NF_constructorMethod), names[DMH_THIS]);
} else if (needsInit) {
- names[GET_MEMBER] = new Name(NF_internalMemberNameEnsureInit, names[DMH_THIS]);
+ names[GET_MEMBER] = new Name(getFunction(NF_internalMemberNameEnsureInit), names[DMH_THIS]);
} else {
- names[GET_MEMBER] = new Name(NF_internalMemberName, names[DMH_THIS]);
+ names[GET_MEMBER] = new Name(getFunction(NF_internalMemberName), names[DMH_THIS]);
}
assert(findDirectMethodHandle(names[GET_MEMBER]) == names[DMH_THIS]);
Object[] outArgs = Arrays.copyOfRange(names, ARG_BASE, GET_MEMBER+1, Object[].class);
@@ -249,10 +249,10 @@
return lform;
}
- static Object findDirectMethodHandle(Name name) {
- if (name.function == NF_internalMemberName ||
- name.function == NF_internalMemberNameEnsureInit ||
- name.function == NF_constructorMethod) {
+ /* assert */ static Object findDirectMethodHandle(Name name) {
+ if (name.function.equals(getFunction(NF_internalMemberName)) ||
+ name.function.equals(getFunction(NF_internalMemberNameEnsureInit)) ||
+ name.function.equals(getFunction(NF_constructorMethod))) {
assert(name.arguments.length == 1);
return name.arguments[0];
}
@@ -674,18 +674,18 @@
final int RESULT = nameCursor-1; // either the call or the cast
Name[] names = arguments(nameCursor - ARG_LIMIT, mtype.invokerType());
if (needsInit)
- names[INIT_BAR] = new Name(NF_ensureInitialized, names[DMH_THIS]);
+ names[INIT_BAR] = new Name(getFunction(NF_ensureInitialized), names[DMH_THIS]);
if (needsCast && !isGetter)
- names[PRE_CAST] = new Name(NF_checkCast, names[DMH_THIS], names[SET_VALUE]);
+ names[PRE_CAST] = new Name(getFunction(NF_checkCast), names[DMH_THIS], names[SET_VALUE]);
Object[] outArgs = new Object[1 + linkerType.parameterCount()];
assert(outArgs.length == (isGetter ? 3 : 4));
- outArgs[0] = names[U_HOLDER] = new Name(NF_UNSAFE);
+ outArgs[0] = names[U_HOLDER] = new Name(getFunction(NF_UNSAFE));
if (isStatic) {
- outArgs[1] = names[F_HOLDER] = new Name(NF_staticBase, names[DMH_THIS]);
- outArgs[2] = names[F_OFFSET] = new Name(NF_staticOffset, names[DMH_THIS]);
+ outArgs[1] = names[F_HOLDER] = new Name(getFunction(NF_staticBase), names[DMH_THIS]);
+ outArgs[2] = names[F_OFFSET] = new Name(getFunction(NF_staticOffset), names[DMH_THIS]);
} else {
- outArgs[1] = names[OBJ_CHECK] = new Name(NF_checkBase, names[OBJ_BASE]);
- outArgs[2] = names[F_OFFSET] = new Name(NF_fieldOffset, names[DMH_THIS]);
+ outArgs[1] = names[OBJ_CHECK] = new Name(getFunction(NF_checkBase), names[OBJ_BASE]);
+ outArgs[2] = names[F_OFFSET] = new Name(getFunction(NF_fieldOffset), names[DMH_THIS]);
}
if (!isGetter) {
outArgs[3] = (needsCast ? names[PRE_CAST] : names[SET_VALUE]);
@@ -693,7 +693,7 @@
for (Object a : outArgs) assert(a != null);
names[LINKER_CALL] = new Name(linker, outArgs);
if (needsCast && isGetter)
- names[POST_CAST] = new Name(NF_checkCast, names[DMH_THIS], names[LINKER_CALL]);
+ names[POST_CAST] = new Name(getFunction(NF_checkCast), names[DMH_THIS], names[LINKER_CALL]);
for (Name n : names) assert(n != null);
LambdaForm form;
@@ -726,48 +726,72 @@
/**
* Pre-initialized NamedFunctions for bootstrapping purposes.
- * Factored in an inner class to delay initialization until first usage.
*/
- static final NamedFunction
- NF_internalMemberName,
- NF_internalMemberNameEnsureInit,
- NF_ensureInitialized,
- NF_fieldOffset,
- NF_checkBase,
- NF_staticBase,
- NF_staticOffset,
- NF_checkCast,
- NF_allocateInstance,
- NF_constructorMethod,
- NF_UNSAFE;
- static {
+ static final byte NF_internalMemberName = 0,
+ NF_internalMemberNameEnsureInit = 1,
+ NF_ensureInitialized = 2,
+ NF_fieldOffset = 3,
+ NF_checkBase = 4,
+ NF_staticBase = 5,
+ NF_staticOffset = 6,
+ NF_checkCast = 7,
+ NF_allocateInstance = 8,
+ NF_constructorMethod = 9,
+ NF_UNSAFE = 10,
+ NF_LIMIT = 11;
+
+ private static final @Stable NamedFunction[] NFS = new NamedFunction[NF_LIMIT];
+
+ private static NamedFunction getFunction(byte func) {
+ NamedFunction nf = NFS[func];
+ if (nf != null) {
+ return nf;
+ }
+ // Each nf must be statically invocable or we get tied up in our bootstraps.
+ nf = NFS[func] = createFunction(func);
+ assert(InvokerBytecodeGenerator.isStaticallyInvocable(nf));
+ return nf;
+ }
+
+ private static NamedFunction createFunction(byte func) {
try {
- NamedFunction nfs[] = {
- NF_internalMemberName = new NamedFunction(DirectMethodHandle.class
- .getDeclaredMethod("internalMemberName", Object.class)),
- NF_internalMemberNameEnsureInit = new NamedFunction(DirectMethodHandle.class
- .getDeclaredMethod("internalMemberNameEnsureInit", Object.class)),
- NF_ensureInitialized = new NamedFunction(DirectMethodHandle.class
- .getDeclaredMethod("ensureInitialized", Object.class)),
- NF_fieldOffset = new NamedFunction(DirectMethodHandle.class
- .getDeclaredMethod("fieldOffset", Object.class)),
- NF_checkBase = new NamedFunction(DirectMethodHandle.class
- .getDeclaredMethod("checkBase", Object.class)),
- NF_staticBase = new NamedFunction(DirectMethodHandle.class
- .getDeclaredMethod("staticBase", Object.class)),
- NF_staticOffset = new NamedFunction(DirectMethodHandle.class
- .getDeclaredMethod("staticOffset", Object.class)),
- NF_checkCast = new NamedFunction(DirectMethodHandle.class
- .getDeclaredMethod("checkCast", Object.class, Object.class)),
- NF_allocateInstance = new NamedFunction(DirectMethodHandle.class
- .getDeclaredMethod("allocateInstance", Object.class)),
- NF_constructorMethod = new NamedFunction(DirectMethodHandle.class
- .getDeclaredMethod("constructorMethod", Object.class)),
- NF_UNSAFE = new NamedFunction(new MemberName(MethodHandleStatics.class
- .getDeclaredField("UNSAFE")))
- };
- // Each nf must be statically invocable or we get tied up in our bootstraps.
- assert(InvokerBytecodeGenerator.isStaticallyInvocable(nfs));
+ switch (func) {
+ case NF_internalMemberName:
+ return new NamedFunction(DirectMethodHandle.class
+ .getDeclaredMethod("internalMemberName", Object.class));
+ case NF_internalMemberNameEnsureInit:
+ return new NamedFunction(DirectMethodHandle.class
+ .getDeclaredMethod("internalMemberNameEnsureInit", Object.class));
+ case NF_ensureInitialized:
+ return new NamedFunction(DirectMethodHandle.class
+ .getDeclaredMethod("ensureInitialized", Object.class));
+ case NF_fieldOffset:
+ return new NamedFunction(DirectMethodHandle.class
+ .getDeclaredMethod("fieldOffset", Object.class));
+ case NF_checkBase:
+ return new NamedFunction(DirectMethodHandle.class
+ .getDeclaredMethod("checkBase", Object.class));
+ case NF_staticBase:
+ return new NamedFunction(DirectMethodHandle.class
+ .getDeclaredMethod("staticBase", Object.class));
+ case NF_staticOffset:
+ return new NamedFunction(DirectMethodHandle.class
+ .getDeclaredMethod("staticOffset", Object.class));
+ case NF_checkCast:
+ return new NamedFunction(DirectMethodHandle.class
+ .getDeclaredMethod("checkCast", Object.class, Object.class));
+ case NF_allocateInstance:
+ return new NamedFunction(DirectMethodHandle.class
+ .getDeclaredMethod("allocateInstance", Object.class));
+ case NF_constructorMethod:
+ return new NamedFunction(DirectMethodHandle.class
+ .getDeclaredMethod("constructorMethod", Object.class));
+ case NF_UNSAFE:
+ return new NamedFunction(new MemberName(MethodHandleStatics.class
+ .getDeclaredField("UNSAFE")));
+ default:
+ throw newInternalError("Unknown function: " + func);
+ }
} catch (ReflectiveOperationException ex) {
throw newInternalError(ex);
}
--- a/jdk/src/java.base/share/classes/java/lang/invoke/InvokerBytecodeGenerator.java Tue Apr 11 21:59:26 2017 -0700
+++ b/jdk/src/java.base/share/classes/java/lang/invoke/InvokerBytecodeGenerator.java Wed Apr 12 05:14:51 2017 +0000
@@ -73,6 +73,7 @@
private static final String LL_SIG = "(L" + OBJ + ";)L" + OBJ + ";";
private static final String LLV_SIG = "(L" + OBJ + ";L" + OBJ + ";)V";
private static final String CLASS_PREFIX = LF + "$";
+ private static final String SOURCE_PREFIX = "LambdaForm$";
/** Name of its super class*/
static final String INVOKER_SUPER_NAME = OBJ;
@@ -80,9 +81,6 @@
/** Name of new class */
private final String className;
- /** Name of the source file (for stack trace printing). */
- private final String sourceFile;
-
private final LambdaForm lambdaForm;
private final String invokerName;
private final MethodType invokerType;
@@ -109,8 +107,7 @@
if (DUMP_CLASS_FILES) {
className = makeDumpableClassName(className);
}
- this.className = CLASS_PREFIX + className;
- this.sourceFile = "LambdaForm$" + className;
+ this.className = className;
this.lambdaForm = lambdaForm;
this.invokerName = invokerName;
this.invokerType = invokerType;
@@ -173,6 +170,13 @@
}
}
+ private void maybeDump(final byte[] classFile) {
+ if (DUMP_CLASS_FILES) {
+ maybeDump(CLASS_PREFIX + className, classFile);
+ }
+ }
+
+ // Also used from BoundMethodHandle
static void maybeDump(final String className, final byte[] classFile) {
if (DUMP_CLASS_FILES) {
java.security.AccessController.doPrivileged(
@@ -306,8 +310,9 @@
private ClassWriter classFilePrologue() {
final int NOT_ACC_PUBLIC = 0; // not ACC_PUBLIC
cw = new ClassWriter(ClassWriter.COMPUTE_MAXS + ClassWriter.COMPUTE_FRAMES);
- cw.visit(Opcodes.V1_8, NOT_ACC_PUBLIC + Opcodes.ACC_FINAL + Opcodes.ACC_SUPER, className, null, INVOKER_SUPER_NAME, null);
- cw.visitSource(sourceFile, null);
+ cw.visit(Opcodes.V1_8, NOT_ACC_PUBLIC + Opcodes.ACC_FINAL + Opcodes.ACC_SUPER,
+ CLASS_PREFIX + className, null, INVOKER_SUPER_NAME, null);
+ cw.visitSource(SOURCE_PREFIX + className, null);
return cw;
}
@@ -617,12 +622,11 @@
return resolvedMember;
}
- private static MemberName lookupPregenerated(LambdaForm form) {
+ private static MemberName lookupPregenerated(LambdaForm form, MethodType invokerType) {
if (form.customized != null) {
// No pre-generated version for customized LF
return null;
}
- MethodType invokerType = form.methodType();
String name = form.kind.methodName;
switch (form.kind) {
case BOUND_REINVOKER: {
@@ -670,7 +674,7 @@
* Generate customized bytecode for a given LambdaForm.
*/
static MemberName generateCustomizedCode(LambdaForm form, MethodType invokerType) {
- MemberName pregenerated = lookupPregenerated(form);
+ MemberName pregenerated = lookupPregenerated(form, invokerType);
if (pregenerated != null) return pregenerated; // pre-generated bytecode
InvokerBytecodeGenerator g = new InvokerBytecodeGenerator("MH", form, invokerType);
@@ -720,7 +724,7 @@
bogusMethod(lambdaForm);
final byte[] classFile = toByteArray();
- maybeDump(className, classFile);
+ maybeDump(classFile);
return classFile;
}
@@ -908,7 +912,7 @@
//MethodHandle.class already covered
};
- static boolean isStaticallyInvocable(NamedFunction[] functions) {
+ static boolean isStaticallyInvocable(NamedFunction ... functions) {
for (NamedFunction nf : functions) {
if (!isStaticallyInvocable(nf.member())) {
return false;
@@ -1761,7 +1765,7 @@
bogusMethod(invokerType);
final byte[] classFile = cw.toByteArray();
- maybeDump(className, classFile);
+ maybeDump(classFile);
return classFile;
}
@@ -1829,7 +1833,7 @@
bogusMethod(dstType);
final byte[] classFile = cw.toByteArray();
- maybeDump(className, classFile);
+ maybeDump(classFile);
return classFile;
}
--- a/jdk/src/java.base/share/classes/java/lang/invoke/Invokers.java Tue Apr 11 21:59:26 2017 -0700
+++ b/jdk/src/java.base/share/classes/java/lang/invoke/Invokers.java Wed Apr 12 05:14:51 2017 +0000
@@ -313,15 +313,15 @@
Object[] outArgs = Arrays.copyOfRange(names, CALL_MH, OUTARG_LIMIT, Object[].class);
Object mtypeArg = (customized ? mtype : names[MTYPE_ARG]);
if (!isGeneric) {
- names[CHECK_TYPE] = new Name(NF_checkExactType, names[CALL_MH], mtypeArg);
+ names[CHECK_TYPE] = new Name(getFunction(NF_checkExactType), names[CALL_MH], mtypeArg);
// mh.invokeExact(a*):R => checkExactType(mh, TYPEOF(a*:R)); mh.invokeBasic(a*)
} else {
- names[CHECK_TYPE] = new Name(NF_checkGenericType, names[CALL_MH], mtypeArg);
+ names[CHECK_TYPE] = new Name(getFunction(NF_checkGenericType), names[CALL_MH], mtypeArg);
// mh.invokeGeneric(a*):R => checkGenericType(mh, TYPEOF(a*:R)).invokeBasic(a*)
outArgs[0] = names[CHECK_TYPE];
}
if (CHECK_CUSTOM != -1) {
- names[CHECK_CUSTOM] = new Name(NF_checkCustomized, outArgs[0]);
+ names[CHECK_CUSTOM] = new Name(getFunction(NF_checkCustomized), outArgs[0]);
}
names[LINKER_CALL] = new Name(outCallType, outArgs);
if (customized) {
@@ -368,7 +368,7 @@
}
names[VAD_ARG] = new Name(ARG_LIMIT, BasicType.basicType(Object.class));
- names[CHECK_TYPE] = new Name(NF_checkVarHandleGenericType, names[THIS_VH], names[VAD_ARG]);
+ names[CHECK_TYPE] = new Name(getFunction(NF_checkVarHandleGenericType), names[THIS_VH], names[VAD_ARG]);
Object[] outArgs = new Object[ARG_LIMIT + 1];
outArgs[0] = names[CHECK_TYPE];
@@ -377,7 +377,7 @@
}
if (CHECK_CUSTOM != -1) {
- names[CHECK_CUSTOM] = new Name(NF_checkCustomized, outArgs[0]);
+ names[CHECK_CUSTOM] = new Name(getFunction(NF_checkCustomized), outArgs[0]);
}
MethodType outCallType = mtype.insertParameterTypes(0, VarHandle.class)
@@ -420,9 +420,9 @@
names[VAD_ARG] = new Name(getter, names[THIS_MH]);
if (isExact) {
- names[CHECK_TYPE] = new Name(NF_checkVarHandleExactType, names[CALL_VH], names[VAD_ARG]);
+ names[CHECK_TYPE] = new Name(getFunction(NF_checkVarHandleExactType), names[CALL_VH], names[VAD_ARG]);
} else {
- names[CHECK_TYPE] = new Name(NF_checkVarHandleGenericType, names[CALL_VH], names[VAD_ARG]);
+ names[CHECK_TYPE] = new Name(getFunction(NF_checkVarHandleGenericType), names[CALL_VH], names[VAD_ARG]);
}
Object[] outArgs = new Object[ARG_LIMIT];
outArgs[0] = names[CHECK_TYPE];
@@ -543,7 +543,7 @@
assert(names.length == nameCursor);
assert(names[APPENDIX_ARG] != null);
if (!skipCallSite)
- names[CALL_MH] = new Name(NF_getCallSiteTarget, names[CSITE_ARG]);
+ names[CALL_MH] = new Name(getFunction(NF_getCallSiteTarget), names[CSITE_ARG]);
// (site.)invokedynamic(a*):R => mh = site.getTarget(); mh.invokeBasic(a*)
final int PREPEND_MH = 0, PREPEND_COUNT = 1;
Object[] outArgs = Arrays.copyOfRange(names, ARG_BASE, OUTARG_LIMIT + PREPEND_COUNT, Object[].class);
@@ -586,31 +586,51 @@
}
// Local constant functions:
- private static final NamedFunction
- NF_checkExactType,
- NF_checkGenericType,
- NF_getCallSiteTarget,
- NF_checkCustomized,
- NF_checkVarHandleGenericType,
- NF_checkVarHandleExactType;
- static {
+ private static final byte NF_checkExactType = 0,
+ NF_checkGenericType = 1,
+ NF_getCallSiteTarget = 2,
+ NF_checkCustomized = 3,
+ NF_checkVarHandleGenericType = 4,
+ NF_checkVarHandleExactType = 5,
+ NF_LIMIT = 6;
+
+ private static final @Stable NamedFunction[] NFS = new NamedFunction[NF_LIMIT];
+
+ private static NamedFunction getFunction(byte func) {
+ NamedFunction nf = NFS[func];
+ if (nf != null) {
+ return nf;
+ }
+ NFS[func] = nf = createFunction(func);
+ // Each nf must be statically invocable or we get tied up in our bootstraps.
+ assert(InvokerBytecodeGenerator.isStaticallyInvocable(nf));
+ return nf;
+ }
+
+ private static NamedFunction createFunction(byte func) {
try {
- NamedFunction nfs[] = {
- NF_checkExactType = new NamedFunction(Invokers.class
- .getDeclaredMethod("checkExactType", MethodHandle.class, MethodType.class)),
- NF_checkGenericType = new NamedFunction(Invokers.class
- .getDeclaredMethod("checkGenericType", MethodHandle.class, MethodType.class)),
- NF_getCallSiteTarget = new NamedFunction(Invokers.class
- .getDeclaredMethod("getCallSiteTarget", CallSite.class)),
- NF_checkCustomized = new NamedFunction(Invokers.class
- .getDeclaredMethod("checkCustomized", MethodHandle.class)),
- NF_checkVarHandleGenericType = new NamedFunction(Invokers.class
- .getDeclaredMethod("checkVarHandleGenericType", VarHandle.class, VarHandle.AccessDescriptor.class)),
- NF_checkVarHandleExactType = new NamedFunction(Invokers.class
- .getDeclaredMethod("checkVarHandleExactType", VarHandle.class, VarHandle.AccessDescriptor.class)),
- };
- // Each nf must be statically invocable or we get tied up in our bootstraps.
- assert(InvokerBytecodeGenerator.isStaticallyInvocable(nfs));
+ switch (func) {
+ case NF_checkExactType:
+ return new NamedFunction(Invokers.class
+ .getDeclaredMethod("checkExactType", MethodHandle.class, MethodType.class));
+ case NF_checkGenericType:
+ return new NamedFunction(Invokers.class
+ .getDeclaredMethod("checkGenericType", MethodHandle.class, MethodType.class));
+ case NF_getCallSiteTarget:
+ return new NamedFunction(Invokers.class
+ .getDeclaredMethod("getCallSiteTarget", CallSite.class));
+ case NF_checkCustomized:
+ return new NamedFunction(Invokers.class
+ .getDeclaredMethod("checkCustomized", MethodHandle.class));
+ case NF_checkVarHandleGenericType:
+ return new NamedFunction(Invokers.class
+ .getDeclaredMethod("checkVarHandleGenericType", VarHandle.class, VarHandle.AccessDescriptor.class));
+ case NF_checkVarHandleExactType:
+ return new NamedFunction(Invokers.class
+ .getDeclaredMethod("checkVarHandleExactType", VarHandle.class, VarHandle.AccessDescriptor.class));
+ default:
+ throw newInternalError("Unknown function: " + func);
+ }
} catch (ReflectiveOperationException ex) {
throw newInternalError(ex);
}
--- a/jdk/src/java.base/share/classes/java/lang/invoke/LambdaForm.java Tue Apr 11 21:59:26 2017 -0700
+++ b/jdk/src/java.base/share/classes/java/lang/invoke/LambdaForm.java Wed Apr 12 05:14:51 2017 +0000
@@ -270,21 +270,21 @@
GENERIC("invoke"),
ZERO("zero"),
IDENTITY("identity"),
- BOUND_REINVOKER("BMH.reinvoke"),
- REINVOKER("MH.reinvoke"),
- DELEGATE("MH.delegate"),
- EXACT_LINKER("MH.invokeExact_MT"),
- EXACT_INVOKER("MH.exactInvoker"),
- GENERIC_LINKER("MH.invoke_MT"),
- GENERIC_INVOKER("MH.invoker"),
+ BOUND_REINVOKER("BMH.reinvoke", "reinvoke"),
+ REINVOKER("MH.reinvoke", "reinvoke"),
+ DELEGATE("MH.delegate", "delegate"),
+ EXACT_LINKER("MH.invokeExact_MT", "invokeExact_MT"),
+ EXACT_INVOKER("MH.exactInvoker", "exactInvoker"),
+ GENERIC_LINKER("MH.invoke_MT", "invoke_MT"),
+ GENERIC_INVOKER("MH.invoker", "invoker"),
LINK_TO_TARGET_METHOD("linkToTargetMethod"),
LINK_TO_CALL_SITE("linkToCallSite"),
- DIRECT_INVOKE_VIRTUAL("DMH.invokeVirtual"),
- DIRECT_INVOKE_SPECIAL("DMH.invokeSpecial"),
- DIRECT_INVOKE_STATIC("DMH.invokeStatic"),
- DIRECT_NEW_INVOKE_SPECIAL("DMH.newInvokeSpecial"),
- DIRECT_INVOKE_INTERFACE("DMH.invokeInterface"),
- DIRECT_INVOKE_STATIC_INIT("DMH.invokeStaticInit"),
+ DIRECT_INVOKE_VIRTUAL("DMH.invokeVirtual", "invokeVirtual"),
+ DIRECT_INVOKE_SPECIAL("DMH.invokeSpecial", "invokeSpecial"),
+ DIRECT_INVOKE_STATIC("DMH.invokeStatic", "invokeStatic"),
+ DIRECT_NEW_INVOKE_SPECIAL("DMH.newInvokeSpecial", "newInvokeSpecial"),
+ DIRECT_INVOKE_INTERFACE("DMH.invokeInterface", "invokeInterface"),
+ DIRECT_INVOKE_STATIC_INIT("DMH.invokeStaticInit", "invokeStaticInit"),
GET_OBJECT("getObject"),
PUT_OBJECT("putObject"),
GET_OBJECT_VOLATILE("getObjectVolatile"),
@@ -330,20 +330,19 @@
GUARD("guard"),
GUARD_WITH_CATCH("guardWithCatch"),
VARHANDLE_EXACT_INVOKER("VH.exactInvoker"),
- VARHANDLE_INVOKER("VH.invoker"),
- VARHANDLE_LINKER("VH.invoke_MT");
+ VARHANDLE_INVOKER("VH.invoker", "invoker"),
+ VARHANDLE_LINKER("VH.invoke_MT", "invoke_MT");
final String defaultLambdaName;
final String methodName;
private Kind(String defaultLambdaName) {
+ this(defaultLambdaName, defaultLambdaName);
+ }
+
+ private Kind(String defaultLambdaName, String methodName) {
this.defaultLambdaName = defaultLambdaName;
- int p = defaultLambdaName.indexOf('.');
- if (p > -1) {
- this.methodName = defaultLambdaName.substring(p + 1);
- } else {
- this.methodName = defaultLambdaName;
- }
+ this.methodName = methodName;
}
}
@@ -642,7 +641,7 @@
for (int i = 0; i < arity; ++i) {
ptypes[i] = parameterType(i).btClass;
}
- return MethodType.methodType(returnType().btClass, ptypes);
+ return MethodType.makeImpl(returnType().btClass, ptypes, true);
}
/** Return ABC_Z, where the ABC are parameter type characters, and Z is the return type character. */
@@ -678,7 +677,7 @@
for (int i = 0; i < ptypes.length; i++)
ptypes[i] = basicType(sig.charAt(i)).btClass;
Class<?> rtype = signatureReturn(sig).btClass;
- return MethodType.methodType(rtype, ptypes);
+ return MethodType.makeImpl(rtype, ptypes, true);
}
/**
@@ -848,6 +847,10 @@
if (vmentry != null && isCompiled) {
return; // already compiled somehow
}
+
+ // Obtain the invoker MethodType outside of the following try block.
+ // This ensures that an IllegalArgumentException is directly thrown if the
+ // type would have 256 or more parameters
MethodType invokerType = methodType();
assert(vmentry == null || vmentry.getMethodType().basicType().equals(invokerType));
try {
@@ -902,10 +905,6 @@
}
return true;
}
- private static boolean returnTypesMatch(String sig, Object[] av, Object res) {
- MethodHandle mh = (MethodHandle) av[0];
- return valueMatches(signatureReturn(sig), mh.type().returnType(), res);
- }
private static boolean checkInt(Class<?> type, Object x) {
assert(x instanceof Integer);
if (type == int.class) return true;
@@ -1180,7 +1179,6 @@
// If we have a cached invoker, call it right away.
// NOTE: The invoker always returns a reference value.
if (TRACE_INTERPRETER) return invokeWithArgumentsTracing(arguments);
- assert(checkArgumentTypes(arguments, methodType()));
return invoker().invokeBasic(resolvedHandle(), arguments);
}
@@ -1198,7 +1196,6 @@
traceInterpreter("| resolve", this);
resolvedHandle();
}
- assert(checkArgumentTypes(arguments, methodType()));
rval = invoker().invokeBasic(resolvedHandle(), arguments);
} catch (Throwable ex) {
traceInterpreter("] throw =>", ex);
@@ -1214,23 +1211,6 @@
return invoker = computeInvoker(methodType().form());
}
- private static boolean checkArgumentTypes(Object[] arguments, MethodType methodType) {
- if (true) return true; // FIXME
- MethodType dstType = methodType.form().erasedType();
- MethodType srcType = dstType.basicType().wrap();
- Class<?>[] ptypes = new Class<?>[arguments.length];
- for (int i = 0; i < arguments.length; i++) {
- Object arg = arguments[i];
- Class<?> ptype = arg == null ? Object.class : arg.getClass();
- // If the dest. type is a primitive we keep the
- // argument type.
- ptypes[i] = dstType.parameterType(i).isPrimitive() ? ptype : Object.class;
- }
- MethodType argType = MethodType.methodType(srcType.returnType(), ptypes).wrap();
- assert(argType.isConvertibleTo(srcType)) : "wrong argument types: cannot convert " + argType + " to " + srcType;
- return true;
- }
-
MethodType methodType() {
if (resolvedHandle != null)
return resolvedHandle.type();
@@ -1726,7 +1706,7 @@
boolean isVoid = (type == V_TYPE);
Class<?> btClass = type.btClass;
MethodType zeType = MethodType.methodType(btClass);
- MethodType idType = (isVoid) ? zeType : zeType.appendParameterTypes(btClass);
+ MethodType idType = (isVoid) ? zeType : MethodType.methodType(btClass, btClass);
// Look up symbolic names. It might not be necessary to have these,
// but if we need to emit direct references to bytecodes, it helps.
--- a/jdk/src/java.base/share/classes/java/lang/invoke/LambdaFormEditor.java Tue Apr 11 21:59:26 2017 -0700
+++ b/jdk/src/java.base/share/classes/java/lang/invoke/LambdaFormEditor.java Wed Apr 12 05:14:51 2017 +0000
@@ -532,7 +532,8 @@
assert(pos > 0); // cannot spread the MH arg itself
Name spreadParam = new Name(L_TYPE);
- Name checkSpread = new Name(MethodHandleImpl.NF_checkSpreadArgument, spreadParam, arrayLength);
+ Name checkSpread = new Name(MethodHandleImpl.getFunction(MethodHandleImpl.NF_checkSpreadArgument),
+ spreadParam, arrayLength);
// insert the new expressions
int exprPos = lambdaForm.arity();
@@ -932,14 +933,14 @@
// replace the null entry in the MHImpl.loop invocation with localTypes
Name invokeLoop = lambdaForm.names[pos + 1];
- assert(invokeLoop.function == NF_loop);
+ assert(invokeLoop.function.equals(MethodHandleImpl.getFunction(NF_loop)));
Object[] args = Arrays.copyOf(invokeLoop.arguments, invokeLoop.arguments.length);
assert(args[0] == null);
args[0] = localTypes;
LambdaFormBuffer buf = buffer();
buf.startEdit();
- buf.changeName(pos + 1, new Name(NF_loop, args));
+ buf.changeName(pos + 1, new Name(MethodHandleImpl.getFunction(NF_loop), args));
form = buf.endEdit();
return putInCache(key, form);
--- a/jdk/src/java.base/share/classes/java/lang/invoke/MemberName.java Tue Apr 11 21:59:26 2017 -0700
+++ b/jdk/src/java.base/share/classes/java/lang/invoke/MemberName.java Wed Apr 12 05:14:51 2017 +0000
@@ -149,7 +149,7 @@
Object[] typeInfo = (Object[]) type;
Class<?>[] ptypes = (Class<?>[]) typeInfo[1];
Class<?> rtype = (Class<?>) typeInfo[0];
- MethodType res = MethodType.methodType(rtype, ptypes);
+ MethodType res = MethodType.makeImpl(rtype, ptypes, true);
type = res;
}
// Make sure type is a MethodType for racing threads.
--- a/jdk/src/java.base/share/classes/java/lang/invoke/MethodHandleImpl.java Tue Apr 11 21:59:26 2017 -0700
+++ b/jdk/src/java.base/share/classes/java/lang/invoke/MethodHandleImpl.java Wed Apr 12 05:14:51 2017 +0000
@@ -589,7 +589,7 @@
// Spread the array.
MethodHandle aload = MethodHandles.arrayElementGetter(spreadArgType);
Name array = names[argIndex];
- names[nameCursor++] = new Name(NF_checkSpreadArgument, array, spreadArgCount);
+ names[nameCursor++] = new Name(getFunction(NF_checkSpreadArgument), array, spreadArgCount);
for (int j = 0; j < spreadArgCount; i++, j++) {
indexes[i] = nameCursor;
names[nameCursor++] = new Name(aload, array, j);
@@ -934,7 +934,7 @@
// profile branch
if (PROFILE != -1) {
- names[PROFILE] = new Name(NF_profileBoolean, names[CALL_TEST], names[GET_COUNTERS]);
+ names[PROFILE] = new Name(getFunction(NF_profileBoolean), names[CALL_TEST], names[GET_COUNTERS]);
}
// call selectAlternative
names[SELECT_ALT] = new Name(getConstantHandle(MH_selectAlternative), names[TEST], names[GET_TARGET], names[GET_FALLBACK]);
@@ -1012,7 +1012,7 @@
// t_{i+1}:L=MethodHandleImpl.guardWithCatch(target:L,exType:L,catcher:L,t_{i}:L);
Object[] gwcArgs = new Object[] {names[GET_TARGET], names[GET_CLASS], names[GET_CATCHER], names[BOXED_ARGS]};
- names[TRY_CATCH] = new Name(NF_guardWithCatch, gwcArgs);
+ names[TRY_CATCH] = new Name(getFunction(NF_guardWithCatch), gwcArgs);
// t_{i+2}:I=MethodHandle.invokeBasic(unbox:L,t_{i+1}:L);
MethodHandle invokeBasicUnbox = MethodHandles.basicInvoker(MethodType.methodType(basicType.rtype(), Object.class));
@@ -1085,7 +1085,7 @@
mh = MethodHandles.dropArguments(mh, 1, Arrays.copyOfRange(type.parameterArray(), 1, arity));
return mh;
}
- return makePairwiseConvert(NF_throwException.resolvedHandle(), type, false, true);
+ return makePairwiseConvert(getFunction(NF_throwException).resolvedHandle(), type, false, true);
}
static <T extends Throwable> Empty throwException(T t) throws T { throw t; }
@@ -1673,33 +1673,57 @@
}
// Local constant functions:
- /*non-public*/ static final NamedFunction
- NF_checkSpreadArgument,
- NF_guardWithCatch,
- NF_throwException,
- NF_tryFinally,
- NF_loop,
- NF_profileBoolean;
+
+ /* non-public */
+ static final byte NF_checkSpreadArgument = 0,
+ NF_guardWithCatch = 1,
+ NF_throwException = 2,
+ NF_tryFinally = 3,
+ NF_loop = 4,
+ NF_profileBoolean = 5,
+ NF_LIMIT = 6;
- static {
+ private static final @Stable NamedFunction[] NFS = new NamedFunction[NF_LIMIT];
+
+ static NamedFunction getFunction(byte func) {
+ NamedFunction nf = NFS[func];
+ if (nf != null) {
+ return nf;
+ }
+ return NFS[func] = createFunction(func);
+ }
+
+ private static NamedFunction createFunction(byte func) {
try {
- NF_checkSpreadArgument = new NamedFunction(MethodHandleImpl.class
- .getDeclaredMethod("checkSpreadArgument", Object.class, int.class));
- NF_guardWithCatch = new NamedFunction(MethodHandleImpl.class
- .getDeclaredMethod("guardWithCatch", MethodHandle.class, Class.class,
- MethodHandle.class, Object[].class));
- NF_tryFinally = new NamedFunction(MethodHandleImpl.class
- .getDeclaredMethod("tryFinally", MethodHandle.class, MethodHandle.class, Object[].class));
- NF_loop = new NamedFunction(MethodHandleImpl.class
- .getDeclaredMethod("loop", BasicType[].class, LoopClauses.class, Object[].class));
- NF_throwException = new NamedFunction(MethodHandleImpl.class
- .getDeclaredMethod("throwException", Throwable.class));
- NF_profileBoolean = new NamedFunction(MethodHandleImpl.class
- .getDeclaredMethod("profileBoolean", boolean.class, int[].class));
+ switch (func) {
+ case NF_checkSpreadArgument:
+ return new NamedFunction(MethodHandleImpl.class
+ .getDeclaredMethod("checkSpreadArgument", Object.class, int.class));
+ case NF_guardWithCatch:
+ return new NamedFunction(MethodHandleImpl.class
+ .getDeclaredMethod("guardWithCatch", MethodHandle.class, Class.class,
+ MethodHandle.class, Object[].class));
+ case NF_tryFinally:
+ return new NamedFunction(MethodHandleImpl.class
+ .getDeclaredMethod("tryFinally", MethodHandle.class, MethodHandle.class, Object[].class));
+ case NF_loop:
+ return new NamedFunction(MethodHandleImpl.class
+ .getDeclaredMethod("loop", BasicType[].class, LoopClauses.class, Object[].class));
+ case NF_throwException:
+ return new NamedFunction(MethodHandleImpl.class
+ .getDeclaredMethod("throwException", Throwable.class));
+ case NF_profileBoolean:
+ return new NamedFunction(MethodHandleImpl.class
+ .getDeclaredMethod("profileBoolean", boolean.class, int[].class));
+ default:
+ throw new InternalError("Undefined function: " + func);
+ }
} catch (ReflectiveOperationException ex) {
throw newInternalError(ex);
}
+ }
+ static {
SharedSecrets.setJavaLangInvokeAccess(new JavaLangInvokeAccess() {
@Override
public Object newMemberName() {
@@ -1878,7 +1902,7 @@
Object[] lArgs =
new Object[]{null, // placeholder for BasicType[] localTypes - will be added by LambdaFormEditor
names[GET_CLAUSE_DATA], names[BOXED_ARGS]};
- names[LOOP] = new Name(NF_loop, lArgs);
+ names[LOOP] = new Name(getFunction(NF_loop), lArgs);
// t_{i+2}:I=MethodHandle.invokeBasic(unbox:L,t_{i+1}:L);
MethodHandle invokeBasicUnbox = MethodHandles.basicInvoker(MethodType.methodType(basicType.rtype(), Object.class));
@@ -2113,7 +2137,7 @@
// t_{i+1}:L=MethodHandleImpl.tryFinally(target:L,exType:L,catcher:L,t_{i}:L);
Object[] tfArgs = new Object[] {names[GET_TARGET], names[GET_CLEANUP], names[BOXED_ARGS]};
- names[TRY_FINALLY] = new Name(NF_tryFinally, tfArgs);
+ names[TRY_FINALLY] = new Name(getFunction(NF_tryFinally), tfArgs);
// t_{i+2}:I=MethodHandle.invokeBasic(unbox:L,t_{i+1}:L);
MethodHandle invokeBasicUnbox = MethodHandles.basicInvoker(MethodType.methodType(basicType.rtype(), Object.class));
--- a/jdk/src/java.base/share/classes/java/lang/invoke/MethodType.java Tue Apr 11 21:59:26 2017 -0700
+++ b/jdk/src/java.base/share/classes/java/lang/invoke/MethodType.java Wed Apr 12 05:14:51 2017 +0000
@@ -95,7 +95,7 @@
private static final long serialVersionUID = 292L; // {rtype, {ptype...}}
// The rtype and ptypes fields define the structural identity of the method type:
- private final Class<?> rtype;
+ private final @Stable Class<?> rtype;
private final @Stable Class<?>[] ptypes;
// The remaining fields are caches of various sorts:
@@ -117,7 +117,8 @@
/**
* Construct a temporary unchecked instance of MethodType for use only as a key to the intern table.
- * Does not check the given parameters for validity, and must be discarded after it is used as a searching key.
+ * Does not check the given parameters for validity, and must discarded (if untrusted) or checked
+ * (if trusted) after it has been used as a searching key.
* The parameters are reversed for this constructor, so that it is not accidentally used.
*/
private MethodType(Class<?>[] ptypes, Class<?> rtype) {
@@ -181,6 +182,7 @@
checkSlotCount(ptypes.length + slots);
return slots;
}
+
static {
// MAX_JVM_ARITY must be power of 2 minus 1 for following code trick to work:
assert((MAX_JVM_ARITY & (MAX_JVM_ARITY+1)) == 0);
@@ -303,18 +305,26 @@
*/
/*trusted*/ static
MethodType makeImpl(Class<?> rtype, Class<?>[] ptypes, boolean trusted) {
- MethodType mt = internTable.get(new MethodType(ptypes, rtype));
- if (mt != null)
- return mt;
if (ptypes.length == 0) {
ptypes = NO_PTYPES; trusted = true;
}
- mt = new MethodType(rtype, ptypes, trusted);
+ MethodType primordialMT = new MethodType(ptypes, rtype);
+ MethodType mt = internTable.get(primordialMT);
+ if (mt != null)
+ return mt;
+
// promote the object to the Real Thing, and reprobe
+ if (trusted) {
+ MethodType.checkRtype(rtype);
+ MethodType.checkPtypes(ptypes);
+ mt = primordialMT;
+ } else {
+ mt = new MethodType(rtype, ptypes, false);
+ }
mt.form = MethodTypeForm.findForm(mt);
return internTable.add(mt);
}
- private static final MethodType[] objectOnlyTypes = new MethodType[20];
+ private static final @Stable MethodType[] objectOnlyTypes = new MethodType[20];
/**
* Finds or creates a method type whose components are {@code Object} with an optional trailing {@code Object[]} array.
@@ -398,9 +408,14 @@
checkSlotCount(parameterSlotCount() + ptypesToInsert.length + ins);
int ilen = ptypesToInsert.length;
if (ilen == 0) return this;
- Class<?>[] nptypes = Arrays.copyOfRange(ptypes, 0, len+ilen);
- System.arraycopy(nptypes, num, nptypes, num+ilen, len-num);
+ Class<?>[] nptypes = new Class<?>[len + ilen];
+ if (num > 0) {
+ System.arraycopy(ptypes, 0, nptypes, 0, num);
+ }
System.arraycopy(ptypesToInsert, 0, nptypes, num, ilen);
+ if (num < len) {
+ System.arraycopy(ptypes, num, nptypes, num+ilen, len-num);
+ }
return makeImpl(rtype, nptypes, true);
}
@@ -636,11 +651,14 @@
return form.basicType();
}
+ private static final @Stable Class<?>[] METHOD_HANDLE_ARRAY
+ = new Class<?>[] { MethodHandle.class };
+
/**
* @return a version of the original type with MethodHandle prepended as the first argument
*/
/*non-public*/ MethodType invokerType() {
- return insertParameterTypes(0, MethodHandle.class);
+ return insertParameterTypes(0, METHOD_HANDLE_ARRAY);
}
/**
--- a/jdk/src/java.base/share/classes/sun/invoke/util/VerifyAccess.java Tue Apr 11 21:59:26 2017 -0700
+++ b/jdk/src/java.base/share/classes/sun/invoke/util/VerifyAccess.java Wed Apr 12 05:14:51 2017 +0000
@@ -297,10 +297,13 @@
* @param refc the class attempting to make the reference
*/
public static boolean isTypeVisible(java.lang.invoke.MethodType type, Class<?> refc) {
- for (int n = -1, max = type.parameterCount(); n < max; n++) {
- Class<?> ptype = (n < 0 ? type.returnType() : type.parameterType(n));
- if (!isTypeVisible(ptype, refc))
+ if (!isTypeVisible(type.returnType(), refc)) {
+ return false;
+ }
+ for (int n = 0, max = type.parameterCount(); n < max; n++) {
+ if (!isTypeVisible(type.parameterType(n), refc)) {
return false;
+ }
}
return true;
}
--- a/jdk/src/java.base/share/classes/sun/invoke/util/Wrapper.java Tue Apr 11 21:59:26 2017 -0700
+++ b/jdk/src/java.base/share/classes/sun/invoke/util/Wrapper.java Wed Apr 12 05:14:51 2017 +0000
@@ -26,20 +26,20 @@
package sun.invoke.util;
public enum Wrapper {
- // wrapperType primitiveType char emptyArray format
- BOOLEAN( Boolean.class, boolean.class, 'Z', new boolean[0], Format.unsigned( 1)),
+ // wrapperType simple primitiveType simple char emptyArray format
+ BOOLEAN( Boolean.class, "Boolean", boolean.class, "boolean", 'Z', new boolean[0], Format.unsigned( 1)),
// These must be in the order defined for widening primitive conversions in JLS 5.1.2
// Avoid boxing integral types here to defer initialization of internal caches
- BYTE ( Byte.class, byte.class, 'B', new byte[0], Format.signed( 8)),
- SHORT ( Short.class, short.class, 'S', new short[0], Format.signed( 16)),
- CHAR (Character.class, char.class, 'C', new char[0], Format.unsigned(16)),
- INT ( Integer.class, int.class, 'I', new int[0], Format.signed( 32)),
- LONG ( Long.class, long.class, 'J', new long[0], Format.signed( 64)),
- FLOAT ( Float.class, float.class, 'F', new float[0], Format.floating(32)),
- DOUBLE ( Double.class, double.class, 'D', new double[0], Format.floating(64)),
- OBJECT ( Object.class, Object.class, 'L', new Object[0], Format.other( 1)),
+ BYTE ( Byte.class, "Byte", byte.class, "byte", 'B', new byte[0], Format.signed( 8)),
+ SHORT ( Short.class, "Short", short.class, "short", 'S', new short[0], Format.signed( 16)),
+ CHAR (Character.class, "Character", char.class, "char", 'C', new char[0], Format.unsigned(16)),
+ INT ( Integer.class, "Integer", int.class, "int", 'I', new int[0], Format.signed( 32)),
+ LONG ( Long.class, "Long", long.class, "long", 'J', new long[0], Format.signed( 64)),
+ FLOAT ( Float.class, "Float", float.class, "float", 'F', new float[0], Format.floating(32)),
+ DOUBLE ( Double.class, "Double", double.class, "double", 'D', new double[0], Format.floating(64)),
+ OBJECT ( Object.class, "Object", Object.class, "Object", 'L', new Object[0], Format.other( 1)),
// VOID must be the last type, since it is "assignable" from any other type:
- VOID ( Void.class, void.class, 'V', null, Format.other( 0)),
+ VOID ( Void.class, "Void", void.class, "void", 'V', null, Format.other( 0)),
;
public static final int COUNT = 10;
@@ -52,14 +52,14 @@
private final String wrapperSimpleName;
private final String primitiveSimpleName;
- private Wrapper(Class<?> wtype, Class<?> ptype, char tchar, Object emptyArray, int format) {
+ private Wrapper(Class<?> wtype, String wtypeName, Class<?> ptype, String ptypeName, char tchar, Object emptyArray, int format) {
this.wrapperType = wtype;
this.primitiveType = ptype;
this.basicTypeChar = tchar;
this.emptyArray = emptyArray;
this.format = format;
- this.wrapperSimpleName = wtype.getSimpleName();
- this.primitiveSimpleName = ptype.getSimpleName();
+ this.wrapperSimpleName = wtypeName;
+ this.primitiveSimpleName = ptypeName;
}
/** For debugging, give the details of this wrapper. */
@@ -518,12 +518,6 @@
* If the target type is a primitive, change it to a wrapper.
*/
static <T> Class<T> forceType(Class<?> type, Class<T> exampleType) {
- boolean z = (type == exampleType ||
- type.isPrimitive() && forPrimitiveType(type) == findWrapperType(exampleType) ||
- exampleType.isPrimitive() && forPrimitiveType(exampleType) == findWrapperType(type) ||
- type == Object.class && !exampleType.isPrimitive());
- if (!z)
- System.out.println(type+" <= "+exampleType);
assert(type == exampleType ||
type.isPrimitive() && forPrimitiveType(type) == findWrapperType(exampleType) ||
exampleType.isPrimitive() && forPrimitiveType(exampleType) == findWrapperType(type) ||