8178384: Reduce work in java.lang.invoke initializers
Reviewed-by: vlivanov, psandoz
This commit is contained in:
parent
b3ea0dd629
commit
9ab899d481
@ -450,32 +450,29 @@ import static jdk.internal.org.objectweb.asm.Opcodes.*;
|
|||||||
*/
|
*/
|
||||||
static class Factory {
|
static class Factory {
|
||||||
|
|
||||||
static final String JLO_SIG = "Ljava/lang/Object;";
|
private static final String JLO_SIG = "Ljava/lang/Object;";
|
||||||
static final String JLS_SIG = "Ljava/lang/String;";
|
private static final String MH = "java/lang/invoke/MethodHandle";
|
||||||
static final String JLC_SIG = "Ljava/lang/Class;";
|
private static final String MH_SIG = "L"+MH+";";
|
||||||
static final String MH = "java/lang/invoke/MethodHandle";
|
private static final String BMH = "java/lang/invoke/BoundMethodHandle";
|
||||||
static final String MH_SIG = "L"+MH+";";
|
private static final String BMH_NAME = "java.lang.invoke.BoundMethodHandle";
|
||||||
static final String BMH = "java/lang/invoke/BoundMethodHandle";
|
private static final String BMH_SIG = "L"+BMH+";";
|
||||||
static final String BMH_SIG = "L"+BMH+";";
|
private static final String SPECIES_DATA = "java/lang/invoke/BoundMethodHandle$SpeciesData";
|
||||||
static final String SPECIES_DATA = "java/lang/invoke/BoundMethodHandle$SpeciesData";
|
private static final String SPECIES_DATA_SIG = "L"+SPECIES_DATA+";";
|
||||||
static final String SPECIES_DATA_SIG = "L"+SPECIES_DATA+";";
|
private static final String STABLE_SIG = "Ljdk/internal/vm/annotation/Stable;";
|
||||||
static final String STABLE_SIG = "Ljdk/internal/vm/annotation/Stable;";
|
|
||||||
|
|
||||||
static final String SPECIES_PREFIX_NAME = "Species_";
|
private static final String SPECIES_PREFIX_NAME = "Species_";
|
||||||
static final String SPECIES_PREFIX_PATH = BMH + "$" + SPECIES_PREFIX_NAME;
|
private 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_CLASS_PREFIX = BMH_NAME + "$" + SPECIES_PREFIX_NAME;
|
||||||
|
|
||||||
static final String BMHSPECIES_DATA_EWI_SIG = "(B)" + SPECIES_DATA_SIG;
|
private 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;
|
private static final String MYSPECIES_DATA_SIG = "()" + SPECIES_DATA_SIG;
|
||||||
static final String MYSPECIES_DATA_SIG = "()" + SPECIES_DATA_SIG;
|
private static final String INT_SIG = "()I";
|
||||||
static final String VOID_SIG = "()V";
|
|
||||||
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.
|
* Get a concrete subclass of BMH for a given combination of bound types.
|
||||||
|
@ -224,12 +224,12 @@ class DirectMethodHandle extends MethodHandle {
|
|||||||
assert(names.length == nameCursor);
|
assert(names.length == nameCursor);
|
||||||
if (doesAlloc) {
|
if (doesAlloc) {
|
||||||
// names = { argx,y,z,... new C, init method }
|
// names = { argx,y,z,... new C, init method }
|
||||||
names[NEW_OBJ] = new Name(NF_allocateInstance, names[DMH_THIS]);
|
names[NEW_OBJ] = new Name(getFunction(NF_allocateInstance), names[DMH_THIS]);
|
||||||
names[GET_MEMBER] = new Name(NF_constructorMethod, names[DMH_THIS]);
|
names[GET_MEMBER] = new Name(getFunction(NF_constructorMethod), names[DMH_THIS]);
|
||||||
} else if (needsInit) {
|
} 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 {
|
} 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]);
|
assert(findDirectMethodHandle(names[GET_MEMBER]) == names[DMH_THIS]);
|
||||||
Object[] outArgs = Arrays.copyOfRange(names, ARG_BASE, GET_MEMBER+1, Object[].class);
|
Object[] outArgs = Arrays.copyOfRange(names, ARG_BASE, GET_MEMBER+1, Object[].class);
|
||||||
@ -249,10 +249,10 @@ class DirectMethodHandle extends MethodHandle {
|
|||||||
return lform;
|
return lform;
|
||||||
}
|
}
|
||||||
|
|
||||||
static Object findDirectMethodHandle(Name name) {
|
/* assert */ static Object findDirectMethodHandle(Name name) {
|
||||||
if (name.function == NF_internalMemberName ||
|
if (name.function.equals(getFunction(NF_internalMemberName)) ||
|
||||||
name.function == NF_internalMemberNameEnsureInit ||
|
name.function.equals(getFunction(NF_internalMemberNameEnsureInit)) ||
|
||||||
name.function == NF_constructorMethod) {
|
name.function.equals(getFunction(NF_constructorMethod))) {
|
||||||
assert(name.arguments.length == 1);
|
assert(name.arguments.length == 1);
|
||||||
return name.arguments[0];
|
return name.arguments[0];
|
||||||
}
|
}
|
||||||
@ -674,18 +674,18 @@ class DirectMethodHandle extends MethodHandle {
|
|||||||
final int RESULT = nameCursor-1; // either the call or the cast
|
final int RESULT = nameCursor-1; // either the call or the cast
|
||||||
Name[] names = arguments(nameCursor - ARG_LIMIT, mtype.invokerType());
|
Name[] names = arguments(nameCursor - ARG_LIMIT, mtype.invokerType());
|
||||||
if (needsInit)
|
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)
|
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()];
|
Object[] outArgs = new Object[1 + linkerType.parameterCount()];
|
||||||
assert(outArgs.length == (isGetter ? 3 : 4));
|
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) {
|
if (isStatic) {
|
||||||
outArgs[1] = names[F_HOLDER] = new Name(NF_staticBase, names[DMH_THIS]);
|
outArgs[1] = names[F_HOLDER] = new Name(getFunction(NF_staticBase), names[DMH_THIS]);
|
||||||
outArgs[2] = names[F_OFFSET] = new Name(NF_staticOffset, names[DMH_THIS]);
|
outArgs[2] = names[F_OFFSET] = new Name(getFunction(NF_staticOffset), names[DMH_THIS]);
|
||||||
} else {
|
} else {
|
||||||
outArgs[1] = names[OBJ_CHECK] = new Name(NF_checkBase, names[OBJ_BASE]);
|
outArgs[1] = names[OBJ_CHECK] = new Name(getFunction(NF_checkBase), names[OBJ_BASE]);
|
||||||
outArgs[2] = names[F_OFFSET] = new Name(NF_fieldOffset, names[DMH_THIS]);
|
outArgs[2] = names[F_OFFSET] = new Name(getFunction(NF_fieldOffset), names[DMH_THIS]);
|
||||||
}
|
}
|
||||||
if (!isGetter) {
|
if (!isGetter) {
|
||||||
outArgs[3] = (needsCast ? names[PRE_CAST] : names[SET_VALUE]);
|
outArgs[3] = (needsCast ? names[PRE_CAST] : names[SET_VALUE]);
|
||||||
@ -693,7 +693,7 @@ class DirectMethodHandle extends MethodHandle {
|
|||||||
for (Object a : outArgs) assert(a != null);
|
for (Object a : outArgs) assert(a != null);
|
||||||
names[LINKER_CALL] = new Name(linker, outArgs);
|
names[LINKER_CALL] = new Name(linker, outArgs);
|
||||||
if (needsCast && isGetter)
|
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);
|
for (Name n : names) assert(n != null);
|
||||||
|
|
||||||
LambdaForm form;
|
LambdaForm form;
|
||||||
@ -726,48 +726,72 @@ class DirectMethodHandle extends MethodHandle {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Pre-initialized NamedFunctions for bootstrapping purposes.
|
* Pre-initialized NamedFunctions for bootstrapping purposes.
|
||||||
* Factored in an inner class to delay initialization until first usage.
|
|
||||||
*/
|
*/
|
||||||
static final NamedFunction
|
static final byte NF_internalMemberName = 0,
|
||||||
NF_internalMemberName,
|
NF_internalMemberNameEnsureInit = 1,
|
||||||
NF_internalMemberNameEnsureInit,
|
NF_ensureInitialized = 2,
|
||||||
NF_ensureInitialized,
|
NF_fieldOffset = 3,
|
||||||
NF_fieldOffset,
|
NF_checkBase = 4,
|
||||||
NF_checkBase,
|
NF_staticBase = 5,
|
||||||
NF_staticBase,
|
NF_staticOffset = 6,
|
||||||
NF_staticOffset,
|
NF_checkCast = 7,
|
||||||
NF_checkCast,
|
NF_allocateInstance = 8,
|
||||||
NF_allocateInstance,
|
NF_constructorMethod = 9,
|
||||||
NF_constructorMethod,
|
NF_UNSAFE = 10,
|
||||||
NF_UNSAFE;
|
NF_LIMIT = 11;
|
||||||
static {
|
|
||||||
try {
|
private static final @Stable NamedFunction[] NFS = new NamedFunction[NF_LIMIT];
|
||||||
NamedFunction nfs[] = {
|
|
||||||
NF_internalMemberName = new NamedFunction(DirectMethodHandle.class
|
private static NamedFunction getFunction(byte func) {
|
||||||
.getDeclaredMethod("internalMemberName", Object.class)),
|
NamedFunction nf = NFS[func];
|
||||||
NF_internalMemberNameEnsureInit = new NamedFunction(DirectMethodHandle.class
|
if (nf != null) {
|
||||||
.getDeclaredMethod("internalMemberNameEnsureInit", Object.class)),
|
return nf;
|
||||||
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.
|
// Each nf must be statically invocable or we get tied up in our bootstraps.
|
||||||
assert(InvokerBytecodeGenerator.isStaticallyInvocable(nfs));
|
nf = NFS[func] = createFunction(func);
|
||||||
|
assert(InvokerBytecodeGenerator.isStaticallyInvocable(nf));
|
||||||
|
return nf;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static NamedFunction createFunction(byte func) {
|
||||||
|
try {
|
||||||
|
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) {
|
} catch (ReflectiveOperationException ex) {
|
||||||
throw newInternalError(ex);
|
throw newInternalError(ex);
|
||||||
}
|
}
|
||||||
|
@ -908,7 +908,7 @@ class InvokerBytecodeGenerator {
|
|||||||
//MethodHandle.class already covered
|
//MethodHandle.class already covered
|
||||||
};
|
};
|
||||||
|
|
||||||
static boolean isStaticallyInvocable(NamedFunction[] functions) {
|
static boolean isStaticallyInvocable(NamedFunction ... functions) {
|
||||||
for (NamedFunction nf : functions) {
|
for (NamedFunction nf : functions) {
|
||||||
if (!isStaticallyInvocable(nf.member())) {
|
if (!isStaticallyInvocable(nf.member())) {
|
||||||
return false;
|
return false;
|
||||||
|
@ -313,15 +313,15 @@ class Invokers {
|
|||||||
Object[] outArgs = Arrays.copyOfRange(names, CALL_MH, OUTARG_LIMIT, Object[].class);
|
Object[] outArgs = Arrays.copyOfRange(names, CALL_MH, OUTARG_LIMIT, Object[].class);
|
||||||
Object mtypeArg = (customized ? mtype : names[MTYPE_ARG]);
|
Object mtypeArg = (customized ? mtype : names[MTYPE_ARG]);
|
||||||
if (!isGeneric) {
|
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*)
|
// mh.invokeExact(a*):R => checkExactType(mh, TYPEOF(a*:R)); mh.invokeBasic(a*)
|
||||||
} else {
|
} 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*)
|
// mh.invokeGeneric(a*):R => checkGenericType(mh, TYPEOF(a*:R)).invokeBasic(a*)
|
||||||
outArgs[0] = names[CHECK_TYPE];
|
outArgs[0] = names[CHECK_TYPE];
|
||||||
}
|
}
|
||||||
if (CHECK_CUSTOM != -1) {
|
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);
|
names[LINKER_CALL] = new Name(outCallType, outArgs);
|
||||||
if (customized) {
|
if (customized) {
|
||||||
@ -368,7 +368,7 @@ class Invokers {
|
|||||||
}
|
}
|
||||||
names[VAD_ARG] = new Name(ARG_LIMIT, BasicType.basicType(Object.class));
|
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];
|
Object[] outArgs = new Object[ARG_LIMIT + 1];
|
||||||
outArgs[0] = names[CHECK_TYPE];
|
outArgs[0] = names[CHECK_TYPE];
|
||||||
@ -377,7 +377,7 @@ class Invokers {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (CHECK_CUSTOM != -1) {
|
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)
|
MethodType outCallType = mtype.insertParameterTypes(0, VarHandle.class)
|
||||||
@ -420,9 +420,9 @@ class Invokers {
|
|||||||
names[VAD_ARG] = new Name(getter, names[THIS_MH]);
|
names[VAD_ARG] = new Name(getter, names[THIS_MH]);
|
||||||
|
|
||||||
if (isExact) {
|
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 {
|
} 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];
|
Object[] outArgs = new Object[ARG_LIMIT];
|
||||||
outArgs[0] = names[CHECK_TYPE];
|
outArgs[0] = names[CHECK_TYPE];
|
||||||
@ -543,7 +543,7 @@ class Invokers {
|
|||||||
assert(names.length == nameCursor);
|
assert(names.length == nameCursor);
|
||||||
assert(names[APPENDIX_ARG] != null);
|
assert(names[APPENDIX_ARG] != null);
|
||||||
if (!skipCallSite)
|
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*)
|
// (site.)invokedynamic(a*):R => mh = site.getTarget(); mh.invokeBasic(a*)
|
||||||
final int PREPEND_MH = 0, PREPEND_COUNT = 1;
|
final int PREPEND_MH = 0, PREPEND_COUNT = 1;
|
||||||
Object[] outArgs = Arrays.copyOfRange(names, ARG_BASE, OUTARG_LIMIT + PREPEND_COUNT, Object[].class);
|
Object[] outArgs = Arrays.copyOfRange(names, ARG_BASE, OUTARG_LIMIT + PREPEND_COUNT, Object[].class);
|
||||||
@ -586,31 +586,51 @@ class Invokers {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Local constant functions:
|
// Local constant functions:
|
||||||
private static final NamedFunction
|
private static final byte NF_checkExactType = 0,
|
||||||
NF_checkExactType,
|
NF_checkGenericType = 1,
|
||||||
NF_checkGenericType,
|
NF_getCallSiteTarget = 2,
|
||||||
NF_getCallSiteTarget,
|
NF_checkCustomized = 3,
|
||||||
NF_checkCustomized,
|
NF_checkVarHandleGenericType = 4,
|
||||||
NF_checkVarHandleGenericType,
|
NF_checkVarHandleExactType = 5,
|
||||||
NF_checkVarHandleExactType;
|
NF_LIMIT = 6;
|
||||||
static {
|
|
||||||
try {
|
private static final @Stable NamedFunction[] NFS = new NamedFunction[NF_LIMIT];
|
||||||
NamedFunction nfs[] = {
|
|
||||||
NF_checkExactType = new NamedFunction(Invokers.class
|
private static NamedFunction getFunction(byte func) {
|
||||||
.getDeclaredMethod("checkExactType", MethodHandle.class, MethodType.class)),
|
NamedFunction nf = NFS[func];
|
||||||
NF_checkGenericType = new NamedFunction(Invokers.class
|
if (nf != null) {
|
||||||
.getDeclaredMethod("checkGenericType", MethodHandle.class, MethodType.class)),
|
return nf;
|
||||||
NF_getCallSiteTarget = new NamedFunction(Invokers.class
|
}
|
||||||
.getDeclaredMethod("getCallSiteTarget", CallSite.class)),
|
NFS[func] = nf = createFunction(func);
|
||||||
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.
|
// Each nf must be statically invocable or we get tied up in our bootstraps.
|
||||||
assert(InvokerBytecodeGenerator.isStaticallyInvocable(nfs));
|
assert(InvokerBytecodeGenerator.isStaticallyInvocable(nf));
|
||||||
|
return nf;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static NamedFunction createFunction(byte func) {
|
||||||
|
try {
|
||||||
|
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) {
|
} catch (ReflectiveOperationException ex) {
|
||||||
throw newInternalError(ex);
|
throw newInternalError(ex);
|
||||||
}
|
}
|
||||||
|
@ -270,21 +270,21 @@ class LambdaForm {
|
|||||||
GENERIC("invoke"),
|
GENERIC("invoke"),
|
||||||
ZERO("zero"),
|
ZERO("zero"),
|
||||||
IDENTITY("identity"),
|
IDENTITY("identity"),
|
||||||
BOUND_REINVOKER("BMH.reinvoke"),
|
BOUND_REINVOKER("BMH.reinvoke", "reinvoke"),
|
||||||
REINVOKER("MH.reinvoke"),
|
REINVOKER("MH.reinvoke", "reinvoke"),
|
||||||
DELEGATE("MH.delegate"),
|
DELEGATE("MH.delegate", "delegate"),
|
||||||
EXACT_LINKER("MH.invokeExact_MT"),
|
EXACT_LINKER("MH.invokeExact_MT", "invokeExact_MT"),
|
||||||
EXACT_INVOKER("MH.exactInvoker"),
|
EXACT_INVOKER("MH.exactInvoker", "exactInvoker"),
|
||||||
GENERIC_LINKER("MH.invoke_MT"),
|
GENERIC_LINKER("MH.invoke_MT", "invoke_MT"),
|
||||||
GENERIC_INVOKER("MH.invoker"),
|
GENERIC_INVOKER("MH.invoker", "invoker"),
|
||||||
LINK_TO_TARGET_METHOD("linkToTargetMethod"),
|
LINK_TO_TARGET_METHOD("linkToTargetMethod"),
|
||||||
LINK_TO_CALL_SITE("linkToCallSite"),
|
LINK_TO_CALL_SITE("linkToCallSite"),
|
||||||
DIRECT_INVOKE_VIRTUAL("DMH.invokeVirtual"),
|
DIRECT_INVOKE_VIRTUAL("DMH.invokeVirtual", "invokeVirtual"),
|
||||||
DIRECT_INVOKE_SPECIAL("DMH.invokeSpecial"),
|
DIRECT_INVOKE_SPECIAL("DMH.invokeSpecial", "invokeSpecial"),
|
||||||
DIRECT_INVOKE_STATIC("DMH.invokeStatic"),
|
DIRECT_INVOKE_STATIC("DMH.invokeStatic", "invokeStatic"),
|
||||||
DIRECT_NEW_INVOKE_SPECIAL("DMH.newInvokeSpecial"),
|
DIRECT_NEW_INVOKE_SPECIAL("DMH.newInvokeSpecial", "newInvokeSpecial"),
|
||||||
DIRECT_INVOKE_INTERFACE("DMH.invokeInterface"),
|
DIRECT_INVOKE_INTERFACE("DMH.invokeInterface", "invokeInterface"),
|
||||||
DIRECT_INVOKE_STATIC_INIT("DMH.invokeStaticInit"),
|
DIRECT_INVOKE_STATIC_INIT("DMH.invokeStaticInit", "invokeStaticInit"),
|
||||||
GET_OBJECT("getObject"),
|
GET_OBJECT("getObject"),
|
||||||
PUT_OBJECT("putObject"),
|
PUT_OBJECT("putObject"),
|
||||||
GET_OBJECT_VOLATILE("getObjectVolatile"),
|
GET_OBJECT_VOLATILE("getObjectVolatile"),
|
||||||
@ -330,20 +330,19 @@ class LambdaForm {
|
|||||||
GUARD("guard"),
|
GUARD("guard"),
|
||||||
GUARD_WITH_CATCH("guardWithCatch"),
|
GUARD_WITH_CATCH("guardWithCatch"),
|
||||||
VARHANDLE_EXACT_INVOKER("VH.exactInvoker"),
|
VARHANDLE_EXACT_INVOKER("VH.exactInvoker"),
|
||||||
VARHANDLE_INVOKER("VH.invoker"),
|
VARHANDLE_INVOKER("VH.invoker", "invoker"),
|
||||||
VARHANDLE_LINKER("VH.invoke_MT");
|
VARHANDLE_LINKER("VH.invoke_MT", "invoke_MT");
|
||||||
|
|
||||||
final String defaultLambdaName;
|
final String defaultLambdaName;
|
||||||
final String methodName;
|
final String methodName;
|
||||||
|
|
||||||
private Kind(String defaultLambdaName) {
|
private Kind(String defaultLambdaName) {
|
||||||
this.defaultLambdaName = defaultLambdaName;
|
this(defaultLambdaName, defaultLambdaName);
|
||||||
int p = defaultLambdaName.indexOf('.');
|
|
||||||
if (p > -1) {
|
|
||||||
this.methodName = defaultLambdaName.substring(p + 1);
|
|
||||||
} else {
|
|
||||||
this.methodName = defaultLambdaName;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private Kind(String defaultLambdaName, String methodName) {
|
||||||
|
this.defaultLambdaName = defaultLambdaName;
|
||||||
|
this.methodName = methodName;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -532,7 +532,8 @@ class LambdaFormEditor {
|
|||||||
assert(pos > 0); // cannot spread the MH arg itself
|
assert(pos > 0); // cannot spread the MH arg itself
|
||||||
|
|
||||||
Name spreadParam = new Name(L_TYPE);
|
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
|
// insert the new expressions
|
||||||
int exprPos = lambdaForm.arity();
|
int exprPos = lambdaForm.arity();
|
||||||
@ -932,14 +933,14 @@ class LambdaFormEditor {
|
|||||||
|
|
||||||
// replace the null entry in the MHImpl.loop invocation with localTypes
|
// replace the null entry in the MHImpl.loop invocation with localTypes
|
||||||
Name invokeLoop = lambdaForm.names[pos + 1];
|
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);
|
Object[] args = Arrays.copyOf(invokeLoop.arguments, invokeLoop.arguments.length);
|
||||||
assert(args[0] == null);
|
assert(args[0] == null);
|
||||||
args[0] = localTypes;
|
args[0] = localTypes;
|
||||||
|
|
||||||
LambdaFormBuffer buf = buffer();
|
LambdaFormBuffer buf = buffer();
|
||||||
buf.startEdit();
|
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();
|
form = buf.endEdit();
|
||||||
|
|
||||||
return putInCache(key, form);
|
return putInCache(key, form);
|
||||||
|
@ -589,7 +589,7 @@ import static jdk.internal.org.objectweb.asm.Opcodes.*;
|
|||||||
// Spread the array.
|
// Spread the array.
|
||||||
MethodHandle aload = MethodHandles.arrayElementGetter(spreadArgType);
|
MethodHandle aload = MethodHandles.arrayElementGetter(spreadArgType);
|
||||||
Name array = names[argIndex];
|
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++) {
|
for (int j = 0; j < spreadArgCount; i++, j++) {
|
||||||
indexes[i] = nameCursor;
|
indexes[i] = nameCursor;
|
||||||
names[nameCursor++] = new Name(aload, array, j);
|
names[nameCursor++] = new Name(aload, array, j);
|
||||||
@ -934,7 +934,7 @@ import static jdk.internal.org.objectweb.asm.Opcodes.*;
|
|||||||
|
|
||||||
// profile branch
|
// profile branch
|
||||||
if (PROFILE != -1) {
|
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
|
// call selectAlternative
|
||||||
names[SELECT_ALT] = new Name(getConstantHandle(MH_selectAlternative), names[TEST], names[GET_TARGET], names[GET_FALLBACK]);
|
names[SELECT_ALT] = new Name(getConstantHandle(MH_selectAlternative), names[TEST], names[GET_TARGET], names[GET_FALLBACK]);
|
||||||
@ -1012,7 +1012,7 @@ import static jdk.internal.org.objectweb.asm.Opcodes.*;
|
|||||||
|
|
||||||
// t_{i+1}:L=MethodHandleImpl.guardWithCatch(target:L,exType:L,catcher:L,t_{i}:L);
|
// 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]};
|
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);
|
// t_{i+2}:I=MethodHandle.invokeBasic(unbox:L,t_{i+1}:L);
|
||||||
MethodHandle invokeBasicUnbox = MethodHandles.basicInvoker(MethodType.methodType(basicType.rtype(), Object.class));
|
MethodHandle invokeBasicUnbox = MethodHandles.basicInvoker(MethodType.methodType(basicType.rtype(), Object.class));
|
||||||
@ -1085,7 +1085,7 @@ import static jdk.internal.org.objectweb.asm.Opcodes.*;
|
|||||||
mh = MethodHandles.dropArguments(mh, 1, Arrays.copyOfRange(type.parameterArray(), 1, arity));
|
mh = MethodHandles.dropArguments(mh, 1, Arrays.copyOfRange(type.parameterArray(), 1, arity));
|
||||||
return mh;
|
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; }
|
static <T extends Throwable> Empty throwException(T t) throws T { throw t; }
|
||||||
@ -1673,33 +1673,57 @@ import static jdk.internal.org.objectweb.asm.Opcodes.*;
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Local constant functions:
|
// Local constant functions:
|
||||||
/*non-public*/ static final NamedFunction
|
|
||||||
NF_checkSpreadArgument,
|
|
||||||
NF_guardWithCatch,
|
|
||||||
NF_throwException,
|
|
||||||
NF_tryFinally,
|
|
||||||
NF_loop,
|
|
||||||
NF_profileBoolean;
|
|
||||||
|
|
||||||
static {
|
static final byte NF_checkSpreadArgument = 0,
|
||||||
|
NF_guardWithCatch = 1,
|
||||||
|
NF_throwException = 2,
|
||||||
|
NF_tryFinally = 3,
|
||||||
|
NF_loop = 4,
|
||||||
|
NF_profileBoolean = 5,
|
||||||
|
NF_LIMIT = 6;
|
||||||
|
|
||||||
|
/*non-public*/
|
||||||
|
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 {
|
try {
|
||||||
NF_checkSpreadArgument = new NamedFunction(MethodHandleImpl.class
|
switch (func) {
|
||||||
|
case NF_checkSpreadArgument:
|
||||||
|
return new NamedFunction(MethodHandleImpl.class
|
||||||
.getDeclaredMethod("checkSpreadArgument", Object.class, int.class));
|
.getDeclaredMethod("checkSpreadArgument", Object.class, int.class));
|
||||||
NF_guardWithCatch = new NamedFunction(MethodHandleImpl.class
|
case NF_guardWithCatch:
|
||||||
|
return new NamedFunction(MethodHandleImpl.class
|
||||||
.getDeclaredMethod("guardWithCatch", MethodHandle.class, Class.class,
|
.getDeclaredMethod("guardWithCatch", MethodHandle.class, Class.class,
|
||||||
MethodHandle.class, Object[].class));
|
MethodHandle.class, Object[].class));
|
||||||
NF_tryFinally = new NamedFunction(MethodHandleImpl.class
|
case NF_tryFinally:
|
||||||
|
return new NamedFunction(MethodHandleImpl.class
|
||||||
.getDeclaredMethod("tryFinally", MethodHandle.class, MethodHandle.class, Object[].class));
|
.getDeclaredMethod("tryFinally", MethodHandle.class, MethodHandle.class, Object[].class));
|
||||||
NF_loop = new NamedFunction(MethodHandleImpl.class
|
case NF_loop:
|
||||||
|
return new NamedFunction(MethodHandleImpl.class
|
||||||
.getDeclaredMethod("loop", BasicType[].class, LoopClauses.class, Object[].class));
|
.getDeclaredMethod("loop", BasicType[].class, LoopClauses.class, Object[].class));
|
||||||
NF_throwException = new NamedFunction(MethodHandleImpl.class
|
case NF_throwException:
|
||||||
|
return new NamedFunction(MethodHandleImpl.class
|
||||||
.getDeclaredMethod("throwException", Throwable.class));
|
.getDeclaredMethod("throwException", Throwable.class));
|
||||||
NF_profileBoolean = new NamedFunction(MethodHandleImpl.class
|
case NF_profileBoolean:
|
||||||
|
return new NamedFunction(MethodHandleImpl.class
|
||||||
.getDeclaredMethod("profileBoolean", boolean.class, int[].class));
|
.getDeclaredMethod("profileBoolean", boolean.class, int[].class));
|
||||||
|
default:
|
||||||
|
throw new InternalError("Undefined function: " + func);
|
||||||
|
}
|
||||||
} catch (ReflectiveOperationException ex) {
|
} catch (ReflectiveOperationException ex) {
|
||||||
throw newInternalError(ex);
|
throw newInternalError(ex);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static {
|
||||||
SharedSecrets.setJavaLangInvokeAccess(new JavaLangInvokeAccess() {
|
SharedSecrets.setJavaLangInvokeAccess(new JavaLangInvokeAccess() {
|
||||||
@Override
|
@Override
|
||||||
public Object newMemberName() {
|
public Object newMemberName() {
|
||||||
@ -1878,7 +1902,7 @@ import static jdk.internal.org.objectweb.asm.Opcodes.*;
|
|||||||
Object[] lArgs =
|
Object[] lArgs =
|
||||||
new Object[]{null, // placeholder for BasicType[] localTypes - will be added by LambdaFormEditor
|
new Object[]{null, // placeholder for BasicType[] localTypes - will be added by LambdaFormEditor
|
||||||
names[GET_CLAUSE_DATA], names[BOXED_ARGS]};
|
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);
|
// t_{i+2}:I=MethodHandle.invokeBasic(unbox:L,t_{i+1}:L);
|
||||||
MethodHandle invokeBasicUnbox = MethodHandles.basicInvoker(MethodType.methodType(basicType.rtype(), Object.class));
|
MethodHandle invokeBasicUnbox = MethodHandles.basicInvoker(MethodType.methodType(basicType.rtype(), Object.class));
|
||||||
@ -2113,7 +2137,7 @@ import static jdk.internal.org.objectweb.asm.Opcodes.*;
|
|||||||
|
|
||||||
// t_{i+1}:L=MethodHandleImpl.tryFinally(target:L,exType:L,catcher:L,t_{i}:L);
|
// 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]};
|
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);
|
// t_{i+2}:I=MethodHandle.invokeBasic(unbox:L,t_{i+1}:L);
|
||||||
MethodHandle invokeBasicUnbox = MethodHandles.basicInvoker(MethodType.methodType(basicType.rtype(), Object.class));
|
MethodHandle invokeBasicUnbox = MethodHandles.basicInvoker(MethodType.methodType(basicType.rtype(), Object.class));
|
||||||
|
@ -26,20 +26,20 @@
|
|||||||
package sun.invoke.util;
|
package sun.invoke.util;
|
||||||
|
|
||||||
public enum Wrapper {
|
public enum Wrapper {
|
||||||
// wrapperType primitiveType char emptyArray format
|
// wrapperType simple primitiveType simple char emptyArray format
|
||||||
BOOLEAN( Boolean.class, boolean.class, 'Z', new boolean[0], Format.unsigned( 1)),
|
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
|
// 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
|
// Avoid boxing integral types here to defer initialization of internal caches
|
||||||
BYTE ( Byte.class, byte.class, 'B', new byte[0], Format.signed( 8)),
|
BYTE ( Byte.class, "Byte", byte.class, "byte", 'B', new byte[0], Format.signed( 8)),
|
||||||
SHORT ( Short.class, short.class, 'S', new short[0], Format.signed( 16)),
|
SHORT ( Short.class, "Short", short.class, "short", 'S', new short[0], Format.signed( 16)),
|
||||||
CHAR (Character.class, char.class, 'C', new char[0], Format.unsigned(16)),
|
CHAR (Character.class, "Character", char.class, "char", 'C', new char[0], Format.unsigned(16)),
|
||||||
INT ( Integer.class, int.class, 'I', new int[0], Format.signed( 32)),
|
INT ( Integer.class, "Integer", int.class, "int", 'I', new int[0], Format.signed( 32)),
|
||||||
LONG ( Long.class, long.class, 'J', new long[0], Format.signed( 64)),
|
LONG ( Long.class, "Long", long.class, "long", 'J', new long[0], Format.signed( 64)),
|
||||||
FLOAT ( Float.class, float.class, 'F', new float[0], Format.floating(32)),
|
FLOAT ( Float.class, "Float", float.class, "float", 'F', new float[0], Format.floating(32)),
|
||||||
DOUBLE ( Double.class, double.class, 'D', new double[0], Format.floating(64)),
|
DOUBLE ( Double.class, "Double", double.class, "double", 'D', new double[0], Format.floating(64)),
|
||||||
OBJECT ( Object.class, Object.class, 'L', new Object[0], Format.other( 1)),
|
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 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;
|
public static final int COUNT = 10;
|
||||||
@ -52,14 +52,14 @@ public enum Wrapper {
|
|||||||
private final String wrapperSimpleName;
|
private final String wrapperSimpleName;
|
||||||
private final String primitiveSimpleName;
|
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.wrapperType = wtype;
|
||||||
this.primitiveType = ptype;
|
this.primitiveType = ptype;
|
||||||
this.basicTypeChar = tchar;
|
this.basicTypeChar = tchar;
|
||||||
this.emptyArray = emptyArray;
|
this.emptyArray = emptyArray;
|
||||||
this.format = format;
|
this.format = format;
|
||||||
this.wrapperSimpleName = wtype.getSimpleName();
|
this.wrapperSimpleName = wtypeName;
|
||||||
this.primitiveSimpleName = ptype.getSimpleName();
|
this.primitiveSimpleName = ptypeName;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** For debugging, give the details of this wrapper. */
|
/** For debugging, give the details of this wrapper. */
|
||||||
|
Loading…
x
Reference in New Issue
Block a user