Skip to content

Commit 796c6ce

Browse files
committed
[GR-64703] Clear caches after analysis phase.
PullRequest: graal/20721
2 parents e065aa8 + c6ff33e commit 796c6ce

File tree

3 files changed

+101
-28
lines changed

3 files changed

+101
-28
lines changed

substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/code/RuntimeMetadataEncoderImpl.java

Lines changed: 84 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -159,25 +159,25 @@ public RuntimeMetadataEncoder create(SnippetReflectionProvider snippetReflection
159159
private final CodeInfoEncoder.Encoders encoders;
160160
private final ReflectionDataAccessors accessors;
161161
private final ReflectionDataBuilder dataBuilder;
162-
private final TreeSet<HostedType> sortedTypes = new TreeSet<>(Comparator.comparingLong(t -> t.getHub().getTypeID()));
163-
private final Map<HostedType, ClassMetadata> classData = new HashMap<>();
164-
private final Map<HostedType, Map<Object, FieldMetadata>> fieldData = new HashMap<>();
165-
private final Map<HostedType, Map<Object, MethodMetadata>> methodData = new HashMap<>();
166-
private final Map<HostedType, Map<Object, ConstructorMetadata>> constructorData = new HashMap<>();
167-
168-
private final Map<HostedType, Throwable> classLookupErrors = new HashMap<>();
169-
private final Map<HostedType, Throwable> fieldLookupErrors = new HashMap<>();
170-
private final Map<HostedType, Throwable> methodLookupErrors = new HashMap<>();
171-
private final Map<HostedType, Throwable> constructorLookupErrors = new HashMap<>();
172-
private final Map<HostedType, Throwable> recordComponentLookupErrors = new HashMap<>();
173-
174-
private final Set<AccessibleObjectMetadata> heapData = new HashSet<>();
175-
176-
private final Map<AccessibleObject, byte[]> annotationsEncodings = new HashMap<>();
177-
private final Map<Executable, byte[]> parameterAnnotationsEncodings = new HashMap<>();
178-
private final Map<Method, byte[]> annotationDefaultEncodings = new HashMap<>();
179-
private final Map<AccessibleObject, byte[]> typeAnnotationsEncodings = new HashMap<>();
180-
private final Map<Executable, byte[]> reflectParametersEncodings = new HashMap<>();
162+
private TreeSet<HostedType> sortedTypes = new TreeSet<>(Comparator.comparingLong(t -> t.getHub().getTypeID()));
163+
private Map<HostedType, ClassMetadata> classData = new HashMap<>();
164+
private Map<HostedType, Map<Object, FieldMetadata>> fieldData = new HashMap<>();
165+
private Map<HostedType, Map<Object, MethodMetadata>> methodData = new HashMap<>();
166+
private Map<HostedType, Map<Object, ConstructorMetadata>> constructorData = new HashMap<>();
167+
168+
private Map<HostedType, Throwable> classLookupErrors = new HashMap<>();
169+
private Map<HostedType, Throwable> fieldLookupErrors = new HashMap<>();
170+
private Map<HostedType, Throwable> methodLookupErrors = new HashMap<>();
171+
private Map<HostedType, Throwable> constructorLookupErrors = new HashMap<>();
172+
private Map<HostedType, Throwable> recordComponentLookupErrors = new HashMap<>();
173+
174+
private Set<AccessibleObjectMetadata> heapData = new HashSet<>();
175+
176+
private Map<AccessibleObject, byte[]> annotationsEncodings = new HashMap<>();
177+
private Map<Executable, byte[]> parameterAnnotationsEncodings = new HashMap<>();
178+
private Map<Method, byte[]> annotationDefaultEncodings = new HashMap<>();
179+
private Map<AccessibleObject, byte[]> typeAnnotationsEncodings = new HashMap<>();
180+
private Map<Executable, byte[]> reflectParametersEncodings = new HashMap<>();
181181

182182
public RuntimeMetadataEncoderImpl(SnippetReflectionProvider snippetReflection, CodeInfoEncoder.Encoders encoders) {
183183
this.snippetReflection = snippetReflection;
@@ -853,7 +853,35 @@ public void encodeAllAndInstall() {
853853
}
854854
install(buf);
855855
/* Enable field recomputers in reflection objects to see the computed values */
856-
ImageSingletons.add(EncodedRuntimeMetadataSupplier.class, this);
856+
EncodedRuntimeMetadataSupplierImpl supplierImpl = new EncodedRuntimeMetadataSupplierImpl(annotationsEncodings, parameterAnnotationsEncodings, annotationDefaultEncodings,
857+
typeAnnotationsEncodings, reflectParametersEncodings);
858+
clearDataAfterEncoding();
859+
ImageSingletons.add(EncodedRuntimeMetadataSupplier.class, supplierImpl);
860+
}
861+
862+
/**
863+
* After the buffer has been created and installed, all other data can be cleaned.
864+
*/
865+
private void clearDataAfterEncoding() {
866+
this.annotationsEncodings = null;
867+
this.parameterAnnotationsEncodings = null;
868+
this.annotationDefaultEncodings = null;
869+
this.typeAnnotationsEncodings = null;
870+
this.reflectParametersEncodings = null;
871+
872+
this.sortedTypes = null;
873+
this.classData = null;
874+
this.fieldData = null;
875+
this.methodData = null;
876+
this.constructorData = null;
877+
878+
this.classLookupErrors = null;
879+
this.fieldLookupErrors = null;
880+
this.methodLookupErrors = null;
881+
this.constructorLookupErrors = null;
882+
this.recordComponentLookupErrors = null;
883+
884+
this.heapData = null;
857885
}
858886

859887
private int encodeErrorIndex(Throwable error) {
@@ -1271,4 +1299,40 @@ public static Object createFromLoader(ImageSingletonLoader loader) {
12711299
return new LayeredRuntimeMetadataSingleton(registeredMethods, registeredFields);
12721300
}
12731301
}
1302+
1303+
/**
1304+
* Container for data required in later phases. Cleaner separation, rest of
1305+
* RuntimeMetadataEncoderImpl can be cleaned after encoding.
1306+
*/
1307+
public record EncodedRuntimeMetadataSupplierImpl(Map<AccessibleObject, byte[]> annotationsEncodings,
1308+
Map<Executable, byte[]> parameterAnnotationsEncodings,
1309+
Map<Method, byte[]> annotationDefaultEncodings,
1310+
Map<AccessibleObject, byte[]> typeAnnotationsEncodings,
1311+
Map<Executable, byte[]> reflectParametersEncodings) implements EncodedRuntimeMetadataSupplier {
1312+
1313+
@Override
1314+
public byte[] getAnnotationsEncoding(AccessibleObject object) {
1315+
return annotationsEncodings.get(object);
1316+
}
1317+
1318+
@Override
1319+
public byte[] getParameterAnnotationsEncoding(Executable object) {
1320+
return parameterAnnotationsEncodings.get(object);
1321+
}
1322+
1323+
@Override
1324+
public byte[] getAnnotationDefaultEncoding(Method object) {
1325+
return annotationDefaultEncodings.get(object);
1326+
}
1327+
1328+
@Override
1329+
public byte[] getTypeAnnotationsEncoding(AccessibleObject object) {
1330+
return typeAnnotationsEncodings.get(object);
1331+
}
1332+
1333+
@Override
1334+
public byte[] getReflectParametersEncoding(Executable object) {
1335+
return reflectParametersEncodings.get(object);
1336+
}
1337+
}
12741338
}

substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/phases/EnumSwitchPlugin.java

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -95,8 +95,8 @@ public boolean handleInvoke(GraphBuilderContext b, ResolvedJavaMethod m, ValueNo
9595
* that end up in the same class or in the JDK.
9696
*/
9797
EnumSwitchFeature feature = ImageSingletons.lookup(EnumSwitchFeature.class);
98-
method.ensureGraphParsed(feature.bb);
99-
Boolean methodSafeForExecution = feature.methodsSafeForExecution.get(method);
98+
method.ensureGraphParsed(feature.getBigBang());
99+
Boolean methodSafeForExecution = feature.isMethodsSafeForExecution(method);
100100
assert methodSafeForExecution != null : "after-parsing hook not executed for method " + method.format("%H.%n(%p)");
101101
if (!methodSafeForExecution.booleanValue()) {
102102
return false;
@@ -121,9 +121,9 @@ public boolean handleInvoke(GraphBuilderContext b, ResolvedJavaMethod m, ValueNo
121121
@AutomaticallyRegisteredFeature
122122
final class EnumSwitchFeature implements InternalFeature {
123123

124-
BigBang bb;
124+
private BigBang bb;
125125

126-
final ConcurrentMap<AnalysisMethod, Boolean> methodsSafeForExecution = new ConcurrentHashMap<>();
126+
private ConcurrentMap<AnalysisMethod, Boolean> methodsSafeForExecution = new ConcurrentHashMap<>();
127127

128128
@Override
129129
public void duringSetup(DuringSetupAccess a) {
@@ -142,10 +142,19 @@ private void onMethodParsed(AnalysisMethod method, StructuredGraph graph) {
142142
@Override
143143
public void afterAnalysis(AfterAnalysisAccess access) {
144144
bb = null;
145+
methodsSafeForExecution = null;
145146
}
146147

147148
@Override
148149
public void registerGraphBuilderPlugins(Providers providers, Plugins plugins, ParsingReason reason) {
149150
plugins.appendNodePlugin(new EnumSwitchPlugin(reason));
150151
}
152+
153+
Boolean isMethodsSafeForExecution(AnalysisMethod method) {
154+
return methodsSafeForExecution.get(method);
155+
}
156+
157+
public BigBang getBigBang() {
158+
return bb;
159+
}
151160
}

substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/reflect/ReflectionDataBuilder.java

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -145,8 +145,8 @@ public class ReflectionDataBuilder extends ConditionalConfigurationRegistry impl
145145
private final Map<Class<?>, Throwable> recordComponentsLookupExceptions = new ConcurrentHashMap<>();
146146

147147
// Intermediate bookkeeping
148-
private final Map<Type, Set<Integer>> processedTypes = new ConcurrentHashMap<>();
149-
private final Map<Class<?>, Set<Method>> pendingRecordClasses;
148+
private Map<Type, Set<Integer>> processedTypes = new ConcurrentHashMap<>();
149+
private Map<Class<?>, Set<Method>> pendingRecordClasses;
150150

151151
record ConditionalTask(ConfigurationCondition condition, Consumer<ConfigurationCondition> task) {
152152
}
@@ -1133,9 +1133,9 @@ private static void reportLinkingErrors(Class<?> clazz, List<Throwable> errors)
11331133

11341134
protected void afterAnalysis() {
11351135
sealed = true;
1136-
processedTypes.clear();
1136+
processedTypes = null;
11371137
if (!throwMissingRegistrationErrors()) {
1138-
pendingRecordClasses.clear();
1138+
pendingRecordClasses = null;
11391139
}
11401140
}
11411141

0 commit comments

Comments
 (0)