< prev index next >
src/java.base/share/classes/java/lang/invoke/DirectMethodHandle.java
Print this page
rev 13064 : 8142334: Improve lazy initialization of java.lang.invoke
Reviewed-by: psandoz, vlivanov, mhaupt
*** 222,237 ****
final int LINKER_CALL = nameCursor++;
Name[] names = arguments(nameCursor - ARG_LIMIT, mtype.invokerType());
assert(names.length == nameCursor);
if (doesAlloc) {
// names = { argx,y,z,... new C, init method }
! names[NEW_OBJ] = new Name(Lazy.NF_allocateInstance, names[DMH_THIS]);
! names[GET_MEMBER] = new Name(Lazy.NF_constructorMethod, names[DMH_THIS]);
} else if (needsInit) {
! names[GET_MEMBER] = new Name(Lazy.NF_internalMemberNameEnsureInit, names[DMH_THIS]);
} else {
! names[GET_MEMBER] = new Name(Lazy.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);
assert(outArgs[outArgs.length-1] == names[GET_MEMBER]); // look, shifted args!
int result = LAST_RESULT;
--- 222,237 ----
final int LINKER_CALL = nameCursor++;
Name[] names = arguments(nameCursor - ARG_LIMIT, mtype.invokerType());
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]);
} else if (needsInit) {
! names[GET_MEMBER] = new Name(NF_internalMemberNameEnsureInit, names[DMH_THIS]);
} else {
! names[GET_MEMBER] = new Name(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);
assert(outArgs[outArgs.length-1] == names[GET_MEMBER]); // look, shifted args!
int result = LAST_RESULT;
*** 248,260 ****
lform.compileToBytecode();
return lform;
}
static Object findDirectMethodHandle(Name name) {
! if (name.function == Lazy.NF_internalMemberName ||
! name.function == Lazy.NF_internalMemberNameEnsureInit ||
! name.function == Lazy.NF_constructorMethod) {
assert(name.arguments.length == 1);
return name.arguments[0];
}
return null;
}
--- 248,260 ----
lform.compileToBytecode();
return lform;
}
static Object findDirectMethodHandle(Name name) {
! if (name.function == NF_internalMemberName ||
! name.function == NF_internalMemberNameEnsureInit ||
! name.function == NF_constructorMethod) {
assert(name.arguments.length == 1);
return name.arguments[0];
}
return null;
}
*** 611,640 ****
final int LINKER_CALL = nameCursor++;
final int POST_CAST = (needsCast && isGetter ? nameCursor++ : -1);
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(Lazy.NF_ensureInitialized, names[DMH_THIS]);
if (needsCast && !isGetter)
! names[PRE_CAST] = new Name(Lazy.NF_checkCast, names[DMH_THIS], names[SET_VALUE]);
Object[] outArgs = new Object[1 + linkerType.parameterCount()];
assert(outArgs.length == (isGetter ? 3 : 4));
outArgs[0] = UNSAFE;
if (isStatic) {
! outArgs[1] = names[F_HOLDER] = new Name(Lazy.NF_staticBase, names[DMH_THIS]);
! outArgs[2] = names[F_OFFSET] = new Name(Lazy.NF_staticOffset, names[DMH_THIS]);
} else {
! outArgs[1] = names[OBJ_CHECK] = new Name(Lazy.NF_checkBase, names[OBJ_BASE]);
! outArgs[2] = names[F_OFFSET] = new Name(Lazy.NF_fieldOffset, names[DMH_THIS]);
}
if (!isGetter) {
outArgs[3] = (needsCast ? names[PRE_CAST] : names[SET_VALUE]);
}
for (Object a : outArgs) assert(a != null);
names[LINKER_CALL] = new Name(linker, outArgs);
if (needsCast && isGetter)
! names[POST_CAST] = new Name(Lazy.NF_checkCast, names[DMH_THIS], names[LINKER_CALL]);
for (Name n : names) assert(n != null);
String fieldOrStatic = (isStatic ? "Static" : "Field");
String lambdaName = (linkerName + fieldOrStatic); // significant only for debugging
if (needsCast) lambdaName += "Cast";
if (needsInit) lambdaName += "Init";
--- 611,640 ----
final int LINKER_CALL = nameCursor++;
final int POST_CAST = (needsCast && isGetter ? nameCursor++ : -1);
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]);
if (needsCast && !isGetter)
! names[PRE_CAST] = new Name(NF_checkCast, names[DMH_THIS], names[SET_VALUE]);
Object[] outArgs = new Object[1 + linkerType.parameterCount()];
assert(outArgs.length == (isGetter ? 3 : 4));
outArgs[0] = 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]);
} 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]);
}
if (!isGetter) {
outArgs[3] = (needsCast ? names[PRE_CAST] : names[SET_VALUE]);
}
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]);
for (Name n : names) assert(n != null);
String fieldOrStatic = (isStatic ? "Static" : "Field");
String lambdaName = (linkerName + fieldOrStatic); // significant only for debugging
if (needsCast) lambdaName += "Cast";
if (needsInit) lambdaName += "Init";
*** 643,653 ****
/**
* Pre-initialized NamedFunctions for bootstrapping purposes.
* Factored in an inner class to delay initialization until first usage.
*/
- private static class Lazy {
static final NamedFunction
NF_internalMemberName,
NF_internalMemberNameEnsureInit,
NF_ensureInitialized,
NF_fieldOffset,
--- 643,652 ----
*** 679,694 ****
NF_allocateInstance = new NamedFunction(DirectMethodHandle.class
.getDeclaredMethod("allocateInstance", Object.class)),
NF_constructorMethod = new NamedFunction(DirectMethodHandle.class
.getDeclaredMethod("constructorMethod", Object.class))
};
- for (NamedFunction nf : nfs) {
// Each nf must be statically invocable or we get tied up in our bootstraps.
! assert(InvokerBytecodeGenerator.isStaticallyInvocable(nf.member)) : nf;
! nf.resolve();
! }
} catch (ReflectiveOperationException ex) {
throw newInternalError(ex);
}
}
- }
}
--- 678,689 ----
NF_allocateInstance = new NamedFunction(DirectMethodHandle.class
.getDeclaredMethod("allocateInstance", Object.class)),
NF_constructorMethod = new NamedFunction(DirectMethodHandle.class
.getDeclaredMethod("constructorMethod", Object.class))
};
// Each nf must be statically invocable or we get tied up in our bootstraps.
! assert(InvokerBytecodeGenerator.isStaticallyInvocable(nfs));
} catch (ReflectiveOperationException ex) {
throw newInternalError(ex);
}
}
}
< prev index next >