mirror of
https://github.com/openjdk/jdk.git
synced 2025-08-27 14:54:52 +02:00
8198418: Invoke LambdaMetafactory::metafactory exactly from the BootstrapMethodInvoker
Reviewed-by: briangoetz, forax, vlivanov
This commit is contained in:
parent
2591c21c01
commit
d4c69026bf
2 changed files with 48 additions and 2 deletions
|
@ -116,8 +116,24 @@ final class BootstrapMethodInvoker {
|
|||
argv[0], argv[1]);
|
||||
break;
|
||||
case 3:
|
||||
result = bootstrapMethod.invoke(caller, name, type,
|
||||
argv[0], argv[1], argv[2]);
|
||||
// Special case the LambdaMetafactory::metafactory BSM
|
||||
//
|
||||
// By invoking exactly, we can avoid generating a number of
|
||||
// classes on first (and subsequent) lambda initialization,
|
||||
// most of which won't be shared with other invoke uses.
|
||||
MethodType bsmType = bootstrapMethod.type();
|
||||
if (isLambdaMetafactoryIndyBSM(bsmType)) {
|
||||
result = (CallSite)bootstrapMethod
|
||||
.invokeExact(caller, name, (MethodType)type, (MethodType)argv[0],
|
||||
(MethodHandle)argv[1], (MethodType)argv[2]);
|
||||
} else if (isLambdaMetafactoryCondyBSM(bsmType)) {
|
||||
result = bootstrapMethod
|
||||
.invokeExact(caller, name, (Class<?>)type, (MethodType)argv[0],
|
||||
(MethodHandle)argv[1], (MethodType)argv[2]);
|
||||
} else {
|
||||
result = bootstrapMethod.invoke(caller, name, type,
|
||||
argv[0], argv[1], argv[2]);
|
||||
}
|
||||
break;
|
||||
case 4:
|
||||
result = bootstrapMethod.invoke(caller, name, type,
|
||||
|
@ -175,6 +191,30 @@ final class BootstrapMethodInvoker {
|
|||
}
|
||||
}
|
||||
|
||||
private static final MethodType LMF_INDY_MT = MethodType.methodType(CallSite.class,
|
||||
Lookup.class, String.class, MethodType.class, MethodType.class, MethodHandle.class, MethodType.class);
|
||||
|
||||
private static final MethodType LMF_CONDY_MT = MethodType.methodType(Object.class,
|
||||
Lookup.class, String.class, Class.class, MethodType.class, MethodHandle.class, MethodType.class);
|
||||
|
||||
/**
|
||||
* @return true iff the BSM method type exactly matches
|
||||
* {@see java.lang.invoke.LambdaMetafactory#metafactory(
|
||||
* MethodHandles.Lookup,String,Class,MethodType,MethodHandle,MethodType)}
|
||||
*/
|
||||
private static boolean isLambdaMetafactoryCondyBSM(MethodType bsmType) {
|
||||
return bsmType == LMF_CONDY_MT;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return true iff the BSM method type exactly matches
|
||||
* {@see java.lang.invoke.LambdaMetafactory#metafactory(
|
||||
* MethodHandles.Lookup,String,MethodType,MethodType,MethodHandle,MethodType)}
|
||||
*/
|
||||
private static boolean isLambdaMetafactoryIndyBSM(MethodType bsmType) {
|
||||
return bsmType == LMF_INDY_MT;
|
||||
}
|
||||
|
||||
/** The JVM produces java.lang.Integer values to box
|
||||
* CONSTANT_Integer boxes but does not intern them.
|
||||
* Let's intern them. This is slightly wrong for
|
||||
|
|
|
@ -242,6 +242,12 @@ public final class LambdaMetafactory {
|
|||
private static final Class<?>[] EMPTY_CLASS_ARRAY = new Class<?>[0];
|
||||
private static final MethodType[] EMPTY_MT_ARRAY = new MethodType[0];
|
||||
|
||||
// LambdaMetafactory bootstrap methods are startup sensitive, and may be
|
||||
// special cased in java.lang.invokeBootstrapMethodInvoker to ensure
|
||||
// methods are invoked with exact type information to avoid generating
|
||||
// code for runtime checks. Take care any changes or additions here are
|
||||
// reflected there as appropriate.
|
||||
|
||||
/**
|
||||
* Facilitates the creation of simple "function objects" that implement one
|
||||
* or more interfaces by delegation to a provided {@link MethodHandle},
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue