Skip to content

Commit e2568f1

Browse files
committed
Factor out NativeImageGenerator#registerRootElements.
1 parent ac04c3f commit e2568f1

File tree

1 file changed

+68
-64
lines changed

1 file changed

+68
-64
lines changed

substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/NativeImageGenerator.java

Lines changed: 68 additions & 64 deletions
Original file line numberDiff line numberDiff line change
@@ -1247,71 +1247,8 @@ public static void initializeBigBang(Inflation bb, OptionValues options, Feature
12471247
HostedImageLayerBuildingSupport.singleton().getLoader().relinkNonTransformedStaticFinalFieldValues();
12481248
}
12491249

1250-
/*
1251-
* System classes and fields are necessary to tell the static analysis that certain things
1252-
* really "exist". The most common reason for that is that there are no instances and
1253-
* allocations of these classes seen during the static analysis. The heap chunks are one
1254-
* good example.
1255-
*/
12561250
try (Indent ignored = debug.logAndIndent("add initial classes/fields/methods")) {
1257-
bb.addRootClass(Object.class, false, false).registerAsInstantiated("root class");
1258-
bb.addRootField(DynamicHub.class, "vtable");
1259-
bb.addRootClass(String.class, false, false).registerAsInstantiated("root class");
1260-
bb.addRootClass(String[].class, false, false).registerAsInstantiated("root class");
1261-
bb.addRootField(String.class, "value").registerAsInstantiated("root class");
1262-
bb.addRootClass(long[].class, false, false).registerAsInstantiated("root class");
1263-
bb.addRootClass(byte[].class, false, false).registerAsInstantiated("root class");
1264-
bb.addRootClass(byte[][].class, false, false).registerAsInstantiated("root class");
1265-
bb.addRootClass(Object[].class, false, false).registerAsInstantiated("root class");
1266-
bb.addRootClass(CFunctionPointer[].class, false, false).registerAsInstantiated("root class");
1267-
bb.addRootClass(PointerBase[].class, false, false).registerAsInstantiated("root class");
1268-
1269-
/* MethodRef can conceal use of MethodPointer and MethodOffset until after analysis. */
1270-
bb.addRootClass(MethodPointer.class, false, true);
1271-
if (SubstrateOptions.useRelativeCodePointers()) {
1272-
bb.addRootClass(MethodOffset.class, false, true);
1273-
}
1274-
1275-
bb.addRootMethod(ReflectionUtil.lookupMethod(SubstrateArraycopySnippets.class, "doArraycopy", Object.class, int.class, Object.class, int.class, int.class), true,
1276-
"Runtime support, registered in " + NativeImageGenerator.class);
1277-
bb.addRootMethod(ReflectionUtil.lookupMethod(Object.class, "getClass"), true, "Runtime support, registered in " + NativeImageGenerator.class);
1278-
1279-
for (JavaKind kind : JavaKind.values()) {
1280-
if (kind.isPrimitive() && kind != JavaKind.Void) {
1281-
bb.addRootClass(kind.toJavaClass(), false, true);
1282-
bb.addRootClass(kind.toBoxedJavaClass(), false, true).registerAsInstantiated("root class");
1283-
bb.addRootField(kind.toBoxedJavaClass(), "value");
1284-
bb.addRootMethod(ReflectionUtil.lookupMethod(kind.toBoxedJavaClass(), "valueOf", kind.toJavaClass()), true, "Runtime support, registered in " + NativeImageGenerator.class);
1285-
bb.addRootMethod(ReflectionUtil.lookupMethod(kind.toBoxedJavaClass(), kind.getJavaName() + "Value"), true, "Runtime support, registered in " + NativeImageGenerator.class);
1286-
/*
1287-
* Register the cache location as reachable.
1288-
* BoxingSnippets$Templates#getCacheLocation accesses the cache field.
1289-
*/
1290-
Class<?>[] innerClasses = kind.toBoxedJavaClass().getDeclaredClasses();
1291-
if (innerClasses != null && innerClasses.length > 0) {
1292-
bb.getMetaAccess().lookupJavaType(innerClasses[0]).registerAsReachable("inner class of root class");
1293-
}
1294-
}
1295-
}
1296-
/* SubstrateTemplates#toLocationIdentity accesses the Counter.value field. */
1297-
bb.getMetaAccess().lookupJavaType(JavaKind.Void.toJavaClass()).registerAsReachable("root class");
1298-
bb.getMetaAccess().lookupJavaType(com.oracle.svm.core.util.Counter.class).registerAsReachable("root class");
1299-
bb.getMetaAccess().lookupJavaType(com.oracle.svm.core.allocationprofile.AllocationCounter.class).registerAsReachable("root class");
1300-
/*
1301-
* SubstrateAllocationProfilingData is not actually present in the image since it is
1302-
* only allocated at build time, is passed to snippets as a @ConstantParameter, and it
1303-
* only contains final fields that are constant-folded. However, since the profiling
1304-
* object is only allocated during lowering it is processed by the shadow heap after
1305-
* analysis, so its type needs to be already marked reachable at this point.
1306-
*/
1307-
bb.getMetaAccess().lookupJavaType(com.oracle.svm.core.graal.snippets.SubstrateAllocationSnippets.SubstrateAllocationProfilingData.class).registerAsReachable("root class");
1308-
/*
1309-
* Similarly to above, StackSlotIdentity only gets reachable during lowering, through
1310-
* build time allocated constants. It doesn't actually end up in the image heap since
1311-
* all its fields are final and are constant-folded, but the type becomes reachable,
1312-
* through the shadow heap processing, after analysis.
1313-
*/
1314-
bb.getMetaAccess().lookupJavaType(com.oracle.svm.core.graal.stackvalue.StackValueNode.StackSlotIdentity.class).registerAsReachable("root class");
1251+
registerRootElements(bb);
13151252

13161253
NativeImageGenerator.registerGraphBuilderPlugins(featureHandler, null, aProviders, aMetaAccess, aUniverse, nativeLibraries, loader, ParsingReason.PointsToAnalysis,
13171254
bb.getAnnotationSubstitutionProcessor(), classInitializationPlugin, ConfigurationValues.getTarget(), supportsStubBasedPlugins);
@@ -1321,6 +1258,73 @@ public static void initializeBigBang(Inflation bb, OptionValues options, Feature
13211258
}
13221259
}
13231260

1261+
/**
1262+
* System classes and fields are necessary to tell the static analysis that certain things
1263+
* really "exist". The most common reason for that is that there are no instances and
1264+
* allocations of these classes seen during the static analysis. The heap chunks are one good
1265+
* example.
1266+
*/
1267+
private static void registerRootElements(Inflation bb) {
1268+
bb.addRootClass(Object.class, false, false).registerAsInstantiated("root class");
1269+
bb.addRootField(DynamicHub.class, "vtable");
1270+
bb.addRootClass(String.class, false, false).registerAsInstantiated("root class");
1271+
bb.addRootClass(String[].class, false, false).registerAsInstantiated("root class");
1272+
bb.addRootField(String.class, "value").registerAsInstantiated("root class");
1273+
bb.addRootClass(long[].class, false, false).registerAsInstantiated("root class");
1274+
bb.addRootClass(byte[].class, false, false).registerAsInstantiated("root class");
1275+
bb.addRootClass(byte[][].class, false, false).registerAsInstantiated("root class");
1276+
bb.addRootClass(Object[].class, false, false).registerAsInstantiated("root class");
1277+
bb.addRootClass(CFunctionPointer[].class, false, false).registerAsInstantiated("root class");
1278+
bb.addRootClass(PointerBase[].class, false, false).registerAsInstantiated("root class");
1279+
1280+
/* MethodRef can conceal use of MethodPointer and MethodOffset until after analysis. */
1281+
bb.addRootClass(MethodPointer.class, false, true);
1282+
if (SubstrateOptions.useRelativeCodePointers()) {
1283+
bb.addRootClass(MethodOffset.class, false, true);
1284+
}
1285+
1286+
bb.addRootMethod(ReflectionUtil.lookupMethod(SubstrateArraycopySnippets.class, "doArraycopy", Object.class, int.class, Object.class, int.class, int.class), true,
1287+
"Runtime support, registered in " + NativeImageGenerator.class);
1288+
bb.addRootMethod(ReflectionUtil.lookupMethod(Object.class, "getClass"), true, "Runtime support, registered in " + NativeImageGenerator.class);
1289+
1290+
for (JavaKind kind : JavaKind.values()) {
1291+
if (kind.isPrimitive() && kind != JavaKind.Void) {
1292+
bb.addRootClass(kind.toJavaClass(), false, true);
1293+
bb.addRootClass(kind.toBoxedJavaClass(), false, true).registerAsInstantiated("root class");
1294+
bb.addRootField(kind.toBoxedJavaClass(), "value");
1295+
bb.addRootMethod(ReflectionUtil.lookupMethod(kind.toBoxedJavaClass(), "valueOf", kind.toJavaClass()), true, "Runtime support, registered in " + NativeImageGenerator.class);
1296+
bb.addRootMethod(ReflectionUtil.lookupMethod(kind.toBoxedJavaClass(), kind.getJavaName() + "Value"), true, "Runtime support, registered in " + NativeImageGenerator.class);
1297+
/*
1298+
* Register the cache location as reachable.
1299+
* BoxingSnippets$Templates#getCacheLocation accesses the cache field.
1300+
*/
1301+
Class<?>[] innerClasses = kind.toBoxedJavaClass().getDeclaredClasses();
1302+
if (innerClasses != null && innerClasses.length > 0) {
1303+
bb.getMetaAccess().lookupJavaType(innerClasses[0]).registerAsReachable("inner class of root class");
1304+
}
1305+
}
1306+
}
1307+
/* SubstrateTemplates#toLocationIdentity accesses the Counter.value field. */
1308+
bb.getMetaAccess().lookupJavaType(JavaKind.Void.toJavaClass()).registerAsReachable("root class");
1309+
bb.getMetaAccess().lookupJavaType(com.oracle.svm.core.util.Counter.class).registerAsReachable("root class");
1310+
bb.getMetaAccess().lookupJavaType(com.oracle.svm.core.allocationprofile.AllocationCounter.class).registerAsReachable("root class");
1311+
/*
1312+
* SubstrateAllocationProfilingData is not actually present in the image since it is only
1313+
* allocated at build time, is passed to snippets as a @ConstantParameter, and it only
1314+
* contains final fields that are constant-folded. However, since the profiling object is
1315+
* only allocated during lowering it is processed by the shadow heap after analysis, so its
1316+
* type needs to be already marked reachable at this point.
1317+
*/
1318+
bb.getMetaAccess().lookupJavaType(com.oracle.svm.core.graal.snippets.SubstrateAllocationSnippets.SubstrateAllocationProfilingData.class).registerAsReachable("root class");
1319+
/*
1320+
* Similarly to above, StackSlotIdentity only gets reachable during lowering, through build
1321+
* time allocated constants. It doesn't actually end up in the image heap since all its
1322+
* fields are final and are constant-folded, but the type becomes reachable, through the
1323+
* shadow heap processing, after analysis.
1324+
*/
1325+
bb.getMetaAccess().lookupJavaType(com.oracle.svm.core.graal.stackvalue.StackValueNode.StackSlotIdentity.class).registerAsReachable("root class");
1326+
}
1327+
13241328
public static void performSnippetGraphAnalysis(BigBang bb, SubstrateReplacements replacements, OptionValues options, Function<Object, Object> objectTransformer) {
13251329
Collection<StructuredGraph> snippetGraphs = replacements.getSnippetGraphs(GraalOptions.TrackNodeSourcePosition.getValue(options), options, objectTransformer);
13261330
if (bb instanceof NativeImagePointsToAnalysis pointsToAnalysis) {

0 commit comments

Comments
 (0)