< prev index next >
src/java.base/share/classes/java/lang/invoke/LambdaForm.java
Print this page
rev 13066 : 8142487: Cleanup sun.invoke.util.Wrapper zeroes to be both reliable and lazy
Reviewed-by: vlivanov, jrose
@@ -1702,87 +1702,109 @@
}
private static final MemberName.Factory IMPL_NAMES = MemberName.getFactory();
static LambdaForm identityForm(BasicType type) {
- return LF_identityForm[type.ordinal()];
+ int ord = type.ordinal();
+ LambdaForm form = LF_identity[ord];
+ if (form != null) {
+ return form;
+ }
+ createFormsFor(type);
+ return LF_identity[ord];
}
+
static LambdaForm zeroForm(BasicType type) {
- return LF_zeroForm[type.ordinal()];
+ int ord = type.ordinal();
+ LambdaForm form = LF_zero[ord];
+ if (form != null) {
+ return form;
}
+ createFormsFor(type);
+ return LF_zero[ord];
+ }
+
static NamedFunction identity(BasicType type) {
- return NF_identity[type.ordinal()];
+ int ord = type.ordinal();
+ NamedFunction function = NF_identity[ord];
+ if (function != null) {
+ return function;
}
- static NamedFunction constantZero(BasicType type) {
- return NF_zero[type.ordinal()];
+ createFormsFor(type);
+ return NF_identity[ord];
}
- private static final LambdaForm[] LF_identityForm = new LambdaForm[TYPE_LIMIT];
- private static final LambdaForm[] LF_zeroForm = new LambdaForm[TYPE_LIMIT];
- private static final NamedFunction[] NF_identity = new NamedFunction[TYPE_LIMIT];
- private static final NamedFunction[] NF_zero = new NamedFunction[TYPE_LIMIT];
- private static void createIdentityForms() {
- for (BasicType type : BasicType.ALL_TYPES) {
+
+ static NamedFunction constantZero(BasicType type) {
int ord = type.ordinal();
+ NamedFunction function = NF_zero[ord];
+ if (function != null) {
+ return function;
+ }
+ createFormsFor(type);
+ return NF_zero[ord];
+ }
+
+ private static final @Stable LambdaForm[] LF_identity = new LambdaForm[TYPE_LIMIT];
+ private static final @Stable LambdaForm[] LF_zero = new LambdaForm[TYPE_LIMIT];
+ private static final @Stable NamedFunction[] NF_identity = new NamedFunction[TYPE_LIMIT];
+ private static final @Stable NamedFunction[] NF_zero = new NamedFunction[TYPE_LIMIT];
+
+ private static void createFormsFor(BasicType type) {
+ synchronized (LF_identity) {
+ final int ord = type.ordinal();
+ LambdaForm idForm = LF_identity[ord];
+ if (idForm != null) {
+ return;
+ }
char btChar = type.basicTypeChar();
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 : zeType.appendParameterTypes(btClass);
- // Look up some symbolic names. It might not be necessary to have these,
+ // Look up symbolic names. It might not be necessary to have these,
// but if we need to emit direct references to bytecodes, it helps.
// Zero is built from a call to an identity function with a constant zero input.
MemberName idMem = new MemberName(LambdaForm.class, "identity_"+btChar, idType, REF_invokeStatic);
- MemberName zeMem = new MemberName(LambdaForm.class, "zero_"+btChar, zeType, REF_invokeStatic);
+ MemberName zeMem = null;
try {
- zeMem = IMPL_NAMES.resolveOrFail(REF_invokeStatic, zeMem, null, NoSuchMethodException.class);
idMem = IMPL_NAMES.resolveOrFail(REF_invokeStatic, idMem, null, NoSuchMethodException.class);
+ if (!isVoid) {
+ zeMem = new MemberName(LambdaForm.class, "zero_"+btChar, zeType, REF_invokeStatic);
+ zeMem = IMPL_NAMES.resolveOrFail(REF_invokeStatic, zeMem, null, NoSuchMethodException.class);
+ }
} catch (IllegalAccessException|NoSuchMethodException ex) {
throw newInternalError(ex);
}
- NamedFunction idFun = new NamedFunction(idMem);
- LambdaForm idForm;
+ NamedFunction idFun;
+ LambdaForm zeForm;
+ NamedFunction zeFun;
if (isVoid) {
Name[] idNames = new Name[] { argument(0, L_TYPE) };
idForm = new LambdaForm(idMem.getName(), 1, idNames, VOID_RESULT);
+ idFun = new NamedFunction(idMem, SimpleMethodHandle.make(idMem.getInvocationType(), idForm));
+
+ assert(zeMem == null);
+ zeForm = idForm;
+ zeFun = idFun;
} else {
Name[] idNames = new Name[] { argument(0, L_TYPE), argument(1, type) };
idForm = new LambdaForm(idMem.getName(), 2, idNames, 1);
- }
- LF_identityForm[ord] = idForm;
- NF_identity[ord] = idFun;
+ idFun = new NamedFunction(idMem, SimpleMethodHandle.make(idMem.getInvocationType(), idForm));
- NamedFunction zeFun = new NamedFunction(zeMem);
- LambdaForm zeForm;
- if (isVoid) {
- zeForm = idForm;
- } else {
+ assert(zeMem != null);
Object zeValue = Wrapper.forBasicType(btChar).zero();
Name[] zeNames = new Name[] { argument(0, L_TYPE), new Name(idFun, zeValue) };
zeForm = new LambdaForm(zeMem.getName(), 1, zeNames, 1);
- }
- LF_zeroForm[ord] = zeForm;
- NF_zero[ord] = zeFun;
-
- assert(idFun.isIdentity());
- assert(zeFun.isConstantZero());
- assert(new Name(zeFun).isConstantZero());
+ zeFun = new NamedFunction(zeMem, SimpleMethodHandle.make(zeMem.getInvocationType(), zeForm));
}
- // Do this in a separate pass, so that SimpleMethodHandle.make can see the tables.
- for (BasicType type : BasicType.ALL_TYPES) {
- int ord = type.ordinal();
- NamedFunction idFun = NF_identity[ord];
- LambdaForm idForm = LF_identityForm[ord];
- MemberName idMem = idFun.member;
- idFun.resolvedHandle = SimpleMethodHandle.make(idMem.getInvocationType(), idForm);
-
- NamedFunction zeFun = NF_zero[ord];
- LambdaForm zeForm = LF_zeroForm[ord];
- MemberName zeMem = zeFun.member;
- zeFun.resolvedHandle = SimpleMethodHandle.make(zeMem.getInvocationType(), zeForm);
+ NF_zero[ord] = zeFun;
+ LF_identity[ord] = idForm;
+ LF_zero[ord] = zeForm;
+ NF_identity[ord] = idFun;
assert(idFun.isIdentity());
assert(zeFun.isConstantZero());
assert(new Name(zeFun).isConstantZero());
}
@@ -1792,17 +1814,16 @@
private static int identity_I(int x) { return x; }
private static long identity_J(long x) { return x; }
private static float identity_F(float x) { return x; }
private static double identity_D(double x) { return x; }
private static Object identity_L(Object x) { return x; }
- private static void identity_V() { return; } // same as zeroV, but that's OK
+ private static void identity_V() { return; }
private static int zero_I() { return 0; }
private static long zero_J() { return 0; }
private static float zero_F() { return 0; }
private static double zero_D() { return 0; }
private static Object zero_L() { return null; }
- private static void zero_V() { return; }
/**
* Internal marker for byte-compiled LambdaForms.
*/
/*non-public*/
@@ -1828,11 +1849,10 @@
DEBUG_NAME_COUNTERS = null;
}
// Put this last, so that previous static inits can run before.
static {
- createIdentityForms();
if (USE_PREDEFINED_INTERPRET_METHODS)
computeInitialPreparedForms();
NamedFunction.initializeInvokers();
}
< prev index next >