Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We鈥檒l occasionally send you account related emails.

Already on GitHub? Sign in to your account

[GR-53382] Update the MethodHandleFeature to initialize basic types #8846

Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
Expand Up @@ -91,10 +91,6 @@ public class MethodHandleFeature implements InternalFeature {
private Method memberNameIsConstructor;
private Method memberNameIsField;
private Method memberNameGetMethodType;
private Field lambdaFormLFIdentity;
private Field lambdaFormLFZero;
private Field lambdaFormNFIdentity;
private Field lambdaFormNFZero;
private Field typedAccessors;
private Field typedCollectors;

Expand All @@ -118,12 +114,6 @@ public void duringSetup(DuringSetupAccess access) {
memberNameIsField = ReflectionUtil.lookupMethod(memberNameClass, "isField");
memberNameGetMethodType = ReflectionUtil.lookupMethod(memberNameClass, "getMethodType");

Class<?> lambdaFormClass = access.findClassByName("java.lang.invoke.LambdaForm");
lambdaFormLFIdentity = ReflectionUtil.lookupField(lambdaFormClass, "LF_identity");
lambdaFormLFZero = ReflectionUtil.lookupField(lambdaFormClass, "LF_zero");
lambdaFormNFIdentity = ReflectionUtil.lookupField(lambdaFormClass, "NF_identity");
lambdaFormNFZero = ReflectionUtil.lookupField(lambdaFormClass, "NF_zero");

Class<?> arrayAccessorClass = access.findClassByName("java.lang.invoke.MethodHandleImpl$ArrayAccessor");
typedAccessors = ReflectionUtil.lookupField(arrayAccessorClass, "TYPED_ACCESSORS");
Class<?> methodHandleImplClass = access.findClassByName("java.lang.invoke.MethodHandleImpl$Makers");
Expand Down Expand Up @@ -277,6 +267,26 @@ public Object transform(Object receiver, Object originalValue) {
return filteredArray;
}
});

/*
* Retrieve all six basic types from the java.lang.invoke.LambdaForm$BasicType class (void,
* int, long, float, double, Object) and invoke the
* java.lang.invoke.LambdaForm.createFormsFor method to ensure that the analysis tracks
* these types. This addresses an issue that arises when these types are created after
* analysis as a side effect of using reflection in the image builder (for example in a
* method Feature.beforeCompilation()), thereby registering new elements into the image heap
* (elements that were not tracked in the analysis).
*/
Class<?> lambdaFormClass = ReflectionUtil.lookupClass(false, "java.lang.invoke.LambdaForm");
Class<?> basicTypeClass = ReflectionUtil.lookupClass(false, "java.lang.invoke.LambdaForm$BasicType");
Method createFormsForMethod = ReflectionUtil.lookupMethod(lambdaFormClass, "createFormsFor", basicTypeClass);
try {
for (Object type : (Object[]) ReflectionUtil.readStaticField(basicTypeClass, "ALL_TYPES")) {
createFormsForMethod.invoke(null, type);
}
} catch (ReflectiveOperationException e) {
VMError.shouldNotReachHere("Can not invoke createFormsForm method to register base types from the java.lang.invoke.LambdaForm$BasicType class.");
}
}

private static void registerMHImplFunctionsForReflection(DuringAnalysisAccess access) {
Expand Down Expand Up @@ -419,10 +429,6 @@ public void registerHeapMemberName(Member memberName) {
@Override
public void duringAnalysis(DuringAnalysisAccess a) {
DuringAnalysisAccessImpl access = (DuringAnalysisAccessImpl) a;
access.rescanRoot(lambdaFormLFIdentity);
access.rescanRoot(lambdaFormLFZero);
access.rescanRoot(lambdaFormNFIdentity);
access.rescanRoot(lambdaFormNFZero);
access.rescanRoot(typedAccessors);
access.rescanRoot(typedCollectors);
access.rescanObject(runtimeMethodTypeInternTable);
Expand Down