8198492: Bootstrapping java.lang.invoke can cause deadlock after JDK-8198418
8198490: java/util/logging/TestLogConfigurationDeadLock.java timed out Reviewed-by: alanb
This commit is contained in:
parent
e1f8cacc0b
commit
703621f15f
@ -1734,70 +1734,75 @@ class LambdaForm {
|
||||
private static final @Stable NamedFunction[] NF_identity = new NamedFunction[TYPE_LIMIT];
|
||||
private static final @Stable NamedFunction[] NF_zero = new NamedFunction[TYPE_LIMIT];
|
||||
|
||||
private static synchronized void createFormsFor(BasicType type) {
|
||||
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 : 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.
|
||||
// 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 = null;
|
||||
try {
|
||||
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);
|
||||
private static final Object createFormsLock = new Object();
|
||||
private static void createFormsFor(BasicType type) {
|
||||
// Avoid racy initialization during bootstrap
|
||||
UNSAFE.ensureClassInitialized(BoundMethodHandle.class);
|
||||
synchronized (createFormsLock) {
|
||||
final int ord = type.ordinal();
|
||||
LambdaForm idForm = LF_identity[ord];
|
||||
if (idForm != null) {
|
||||
return;
|
||||
}
|
||||
} catch (IllegalAccessException|NoSuchMethodException ex) {
|
||||
throw newInternalError(ex);
|
||||
char btChar = type.basicTypeChar();
|
||||
boolean isVoid = (type == V_TYPE);
|
||||
Class<?> btClass = type.btClass;
|
||||
MethodType zeType = MethodType.methodType(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.
|
||||
// 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 = null;
|
||||
try {
|
||||
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;
|
||||
LambdaForm zeForm;
|
||||
NamedFunction zeFun;
|
||||
|
||||
// Create the LFs and NamedFunctions. Precompiling LFs to byte code is needed to break circular
|
||||
// bootstrap dependency on this method in case we're interpreting LFs
|
||||
if (isVoid) {
|
||||
Name[] idNames = new Name[] { argument(0, L_TYPE) };
|
||||
idForm = new LambdaForm(1, idNames, VOID_RESULT, Kind.IDENTITY);
|
||||
idForm.compileToBytecode();
|
||||
idFun = new NamedFunction(idMem, SimpleMethodHandle.make(idMem.getInvocationType(), idForm));
|
||||
|
||||
zeForm = idForm;
|
||||
zeFun = idFun;
|
||||
} else {
|
||||
Name[] idNames = new Name[] { argument(0, L_TYPE), argument(1, type) };
|
||||
idForm = new LambdaForm(2, idNames, 1, Kind.IDENTITY);
|
||||
idForm.compileToBytecode();
|
||||
idFun = new NamedFunction(idMem, SimpleMethodHandle.make(idMem.getInvocationType(), idForm),
|
||||
MethodHandleImpl.Intrinsic.IDENTITY);
|
||||
|
||||
Object zeValue = Wrapper.forBasicType(btChar).zero();
|
||||
Name[] zeNames = new Name[] { argument(0, L_TYPE), new Name(idFun, zeValue) };
|
||||
zeForm = new LambdaForm(1, zeNames, 1, Kind.ZERO);
|
||||
zeForm.compileToBytecode();
|
||||
zeFun = new NamedFunction(zeMem, SimpleMethodHandle.make(zeMem.getInvocationType(), zeForm),
|
||||
MethodHandleImpl.Intrinsic.ZERO);
|
||||
}
|
||||
|
||||
LF_zero[ord] = zeForm;
|
||||
NF_zero[ord] = zeFun;
|
||||
LF_identity[ord] = idForm;
|
||||
NF_identity[ord] = idFun;
|
||||
|
||||
assert(idFun.isIdentity());
|
||||
assert(zeFun.isConstantZero());
|
||||
assert(new Name(zeFun).isConstantZero());
|
||||
}
|
||||
|
||||
NamedFunction idFun;
|
||||
LambdaForm zeForm;
|
||||
NamedFunction zeFun;
|
||||
|
||||
// Create the LFs and NamedFunctions. Precompiling LFs to byte code is needed to break circular
|
||||
// bootstrap dependency on this method in case we're interpreting LFs
|
||||
if (isVoid) {
|
||||
Name[] idNames = new Name[] { argument(0, L_TYPE) };
|
||||
idForm = new LambdaForm(1, idNames, VOID_RESULT, Kind.IDENTITY);
|
||||
idForm.compileToBytecode();
|
||||
idFun = new NamedFunction(idMem, SimpleMethodHandle.make(idMem.getInvocationType(), idForm));
|
||||
|
||||
zeForm = idForm;
|
||||
zeFun = idFun;
|
||||
} else {
|
||||
Name[] idNames = new Name[] { argument(0, L_TYPE), argument(1, type) };
|
||||
idForm = new LambdaForm(2, idNames, 1, Kind.IDENTITY);
|
||||
idForm.compileToBytecode();
|
||||
idFun = new NamedFunction(idMem, SimpleMethodHandle.make(idMem.getInvocationType(), idForm),
|
||||
MethodHandleImpl.Intrinsic.IDENTITY);
|
||||
|
||||
Object zeValue = Wrapper.forBasicType(btChar).zero();
|
||||
Name[] zeNames = new Name[] { argument(0, L_TYPE), new Name(idFun, zeValue) };
|
||||
zeForm = new LambdaForm(1, zeNames, 1, Kind.ZERO);
|
||||
zeForm.compileToBytecode();
|
||||
zeFun = new NamedFunction(zeMem, SimpleMethodHandle.make(zeMem.getInvocationType(), zeForm),
|
||||
MethodHandleImpl.Intrinsic.ZERO);
|
||||
}
|
||||
|
||||
LF_zero[ord] = zeForm;
|
||||
NF_zero[ord] = zeFun;
|
||||
LF_identity[ord] = idForm;
|
||||
NF_identity[ord] = idFun;
|
||||
|
||||
assert(idFun.isIdentity());
|
||||
assert(zeFun.isConstantZero());
|
||||
assert(new Name(zeFun).isConstantZero());
|
||||
}
|
||||
|
||||
// Avoid appealing to ValueConversions at bootstrap time:
|
||||
|
Loading…
x
Reference in New Issue
Block a user