mirror of
https://github.com/openjdk/jdk.git
synced 2025-08-27 14:54:52 +02:00
8327499: MethodHandleStatics.traceLambdaForm includes methods that cannot be generated
Reviewed-by: redestad, iklam
This commit is contained in:
parent
5a8df4106a
commit
adaa509b6e
5 changed files with 140 additions and 34 deletions
|
@ -28,7 +28,6 @@ package java.lang.invoke;
|
|||
import jdk.internal.org.objectweb.asm.ClassWriter;
|
||||
import jdk.internal.org.objectweb.asm.Opcodes;
|
||||
import sun.invoke.util.Wrapper;
|
||||
import sun.util.logging.PlatformLogger;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashSet;
|
||||
|
@ -73,6 +72,7 @@ class GenerateJLIClassesHelper {
|
|||
|
||||
private final TreeSet<String> speciesTypes = new TreeSet<>();
|
||||
private final TreeSet<String> invokerTypes = new TreeSet<>();
|
||||
private final TreeSet<String> linkerTypes = new TreeSet<>();
|
||||
private final TreeSet<String> callSiteTypes = new TreeSet<>();
|
||||
private final Map<String, Set<String>> dmhMethods = new TreeMap<>();
|
||||
|
||||
|
@ -87,6 +87,12 @@ class GenerateJLIClassesHelper {
|
|||
return this;
|
||||
}
|
||||
|
||||
HolderClassBuilder addLinkerType(String methodType) {
|
||||
validateMethodType(methodType);
|
||||
linkerTypes.add(methodType);
|
||||
return this;
|
||||
}
|
||||
|
||||
HolderClassBuilder addCallSiteType(String csType) {
|
||||
validateMethodType(csType);
|
||||
callSiteTypes.add(csType);
|
||||
|
@ -130,19 +136,33 @@ class GenerateJLIClassesHelper {
|
|||
}
|
||||
}
|
||||
|
||||
// The invoker type to ask for is retrieved by removing the first
|
||||
// The linker type to ask for is retrieved by removing the first
|
||||
// and the last argument, which needs to be of Object.class
|
||||
MethodType[] linkerMethodTypes = new MethodType[linkerTypes.size()];
|
||||
index = 0;
|
||||
for (String linkerType : linkerTypes) {
|
||||
MethodType mt = asMethodType(linkerType);
|
||||
final int lastParam = mt.parameterCount() - 1;
|
||||
if (!checkLinkerTypeParams(mt)) {
|
||||
throw new RuntimeException(
|
||||
"Linker type parameter must start and end with Object: " + linkerType);
|
||||
}
|
||||
mt = mt.dropParameterTypes(lastParam, lastParam + 1);
|
||||
linkerMethodTypes[index] = mt.dropParameterTypes(0, 1);
|
||||
index++;
|
||||
}
|
||||
|
||||
// The invoker type to ask for is retrieved by removing the first
|
||||
// argument, which needs to be of Object.class
|
||||
MethodType[] invokerMethodTypes = new MethodType[invokerTypes.size()];
|
||||
index = 0;
|
||||
for (String invokerType : invokerTypes) {
|
||||
MethodType mt = asMethodType(invokerType);
|
||||
final int lastParam = mt.parameterCount() - 1;
|
||||
if (!checkInvokerTypeParams(mt)) {
|
||||
throw new RuntimeException(
|
||||
"Invoker type parameter must start and end with Object: " + invokerType);
|
||||
"Invoker type parameter must start with 2 Objects: " + invokerType);
|
||||
}
|
||||
mt = mt.dropParameterTypes(lastParam, lastParam + 1);
|
||||
invokerMethodTypes[index] = mt.dropParameterTypes(0, 1);
|
||||
invokerMethodTypes[index] = mt.dropParameterTypes(0, 2);
|
||||
index++;
|
||||
}
|
||||
|
||||
|
@ -171,7 +191,7 @@ class GenerateJLIClassesHelper {
|
|||
DELEGATING_HOLDER, directMethodTypes));
|
||||
result.put(INVOKERS_HOLDER,
|
||||
generateInvokersHolderClassBytes(INVOKERS_HOLDER,
|
||||
invokerMethodTypes, callSiteMethodTypes));
|
||||
linkerMethodTypes, invokerMethodTypes, callSiteMethodTypes));
|
||||
result.put(BASIC_FORMS_HOLDER,
|
||||
generateBasicFormsClassBytes(BASIC_FORMS_HOLDER));
|
||||
|
||||
|
@ -207,6 +227,12 @@ class GenerateJLIClassesHelper {
|
|||
}
|
||||
|
||||
public static boolean checkInvokerTypeParams(MethodType mt) {
|
||||
return (mt.parameterCount() >= 2 &&
|
||||
mt.parameterType(0) == Object.class &&
|
||||
mt.parameterType(1) == Object.class);
|
||||
}
|
||||
|
||||
public static boolean checkLinkerTypeParams(MethodType mt) {
|
||||
final int lastParam = mt.parameterCount() - 1;
|
||||
return (mt.parameterCount() >= 2 &&
|
||||
mt.parameterType(0) == Object.class &&
|
||||
|
@ -320,15 +346,11 @@ class GenerateJLIClassesHelper {
|
|||
if ("linkToTargetMethod".equals(parts[2]) ||
|
||||
"linkToCallSite".equals(parts[2])) {
|
||||
builder.addCallSiteType(methodType);
|
||||
} else if (parts[2].endsWith("nvoker")) {
|
||||
// MH.exactInvoker exactInvoker MH.invoker invoker
|
||||
builder.addInvokerType(methodType);
|
||||
} else {
|
||||
MethodType mt = HolderClassBuilder.asMethodType(methodType);
|
||||
// Work around JDK-8327499
|
||||
if (HolderClassBuilder.checkInvokerTypeParams(mt)) {
|
||||
builder.addInvokerType(methodType);
|
||||
} else {
|
||||
PlatformLogger.getLogger("java.lang.invoke")
|
||||
.warning("Invalid LF_RESOLVE " + parts[1] + " " + parts[2] + " " + parts[3]);
|
||||
}
|
||||
builder.addLinkerType(methodType);
|
||||
}
|
||||
} else if (parts[1].contains("DirectMethodHandle")) {
|
||||
String dmh = parts[2];
|
||||
|
@ -465,27 +487,27 @@ class GenerateJLIClassesHelper {
|
|||
|
||||
/**
|
||||
* Returns a {@code byte[]} representation of a class implementing
|
||||
* the invoker forms for the set of supplied {@code invokerMethodTypes}
|
||||
* and {@code callSiteMethodTypes}.
|
||||
* the invoker forms for the set of supplied {@code linkerMethodTypes}
|
||||
* {@code invokerMethodTypes}, and {@code callSiteMethodTypes}.
|
||||
*/
|
||||
static byte[] generateInvokersHolderClassBytes(String className,
|
||||
MethodType[] invokerMethodTypes, MethodType[] callSiteMethodTypes) {
|
||||
MethodType[] linkerMethodTypes, MethodType[] invokerMethodTypes,
|
||||
MethodType[] callSiteMethodTypes) {
|
||||
|
||||
HashSet<MethodType> dedupSet = new HashSet<>();
|
||||
ArrayList<LambdaForm> forms = new ArrayList<>();
|
||||
ArrayList<String> names = new ArrayList<>();
|
||||
int[] types = {
|
||||
MethodTypeForm.LF_EX_LINKER,
|
||||
|
||||
int[] invokerTypes = {
|
||||
MethodTypeForm.LF_EX_INVOKER,
|
||||
MethodTypeForm.LF_GEN_LINKER,
|
||||
MethodTypeForm.LF_GEN_INVOKER
|
||||
MethodTypeForm.LF_GEN_INVOKER,
|
||||
};
|
||||
|
||||
for (int i = 0; i < invokerMethodTypes.length; i++) {
|
||||
for (MethodType methodType : invokerMethodTypes) {
|
||||
// generate methods representing invokers of the specified type
|
||||
if (dedupSet.add(invokerMethodTypes[i])) {
|
||||
for (int type : types) {
|
||||
LambdaForm invokerForm = Invokers.invokeHandleForm(invokerMethodTypes[i],
|
||||
if (dedupSet.add(methodType)) {
|
||||
for (int type : invokerTypes) {
|
||||
LambdaForm invokerForm = Invokers.invokeHandleForm(methodType,
|
||||
/*customized*/false, type);
|
||||
forms.add(invokerForm);
|
||||
names.add(invokerForm.kind.defaultLambdaName);
|
||||
|
@ -493,6 +515,24 @@ class GenerateJLIClassesHelper {
|
|||
}
|
||||
}
|
||||
|
||||
int[] linkerTypes = {
|
||||
MethodTypeForm.LF_EX_LINKER,
|
||||
MethodTypeForm.LF_GEN_LINKER,
|
||||
};
|
||||
|
||||
dedupSet = new HashSet<>();
|
||||
for (MethodType methodType : linkerMethodTypes) {
|
||||
// generate methods representing linkers of the specified type
|
||||
if (dedupSet.add(methodType)) {
|
||||
for (int type : linkerTypes) {
|
||||
LambdaForm linkerForm = Invokers.invokeHandleForm(methodType,
|
||||
/*customized*/false, type);
|
||||
forms.add(linkerForm);
|
||||
names.add(linkerForm.kind.defaultLambdaName);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
dedupSet = new HashSet<>();
|
||||
for (int i = 0; i < callSiteMethodTypes.length; i++) {
|
||||
// generate methods representing invokers of the specified type
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue