@@ -1110,7 +1110,10 @@ protected void setupNativeImage(OptionValues options, Map<Method, CEntryPointDat
11101110 initializeBigBang(bb, options, featureHandler, nativeLibraries, debug, aMetaAccess, aUniverse.getSubstitutions(), loader, true,
11111111 new SubstrateClassInitializationPlugin(hostVM), this.isStubBasedPluginsSupported(), aProviders);
11121112
1113- loader.classLoaderSupport.getClassesToIncludeUnconditionally().forEach(clazz -> bb.tryRegisterTypeForBaseImage(originalMetaAccess.lookupJavaType(clazz)));
1113+ if (ImageLayerBuildingSupport.buildingSharedLayer()) {
1114+ HostedImageLayerBuildingSupport.singleton().registerBaseLayerTypes(bb, originalMetaAccess, loader.classLoaderSupport);
1115+ }
1116+
11141117 if (loader.classLoaderSupport.isPreserveMode()) {
11151118 PreserveOptionsSupport.registerPreservedClasses(bb, originalMetaAccess, loader.classLoaderSupport);
11161119 }
@@ -1244,71 +1247,8 @@ public static void initializeBigBang(Inflation bb, OptionValues options, Feature
12441247 HostedImageLayerBuildingSupport.singleton().getLoader().relinkNonTransformedStaticFinalFieldValues();
12451248 }
12461249
1247- /*
1248- * System classes and fields are necessary to tell the static analysis that certain things
1249- * really "exist". The most common reason for that is that there are no instances and
1250- * allocations of these classes seen during the static analysis. The heap chunks are one
1251- * good example.
1252- */
12531250 try (Indent ignored = debug.logAndIndent("add initial classes/fields/methods")) {
1254- bb.addRootClass(Object.class, false, false).registerAsInstantiated("root class");
1255- bb.addRootField(DynamicHub.class, "vtable");
1256- bb.addRootClass(String.class, false, false).registerAsInstantiated("root class");
1257- bb.addRootClass(String[].class, false, false).registerAsInstantiated("root class");
1258- bb.addRootField(String.class, "value").registerAsInstantiated("root class");
1259- bb.addRootClass(long[].class, false, false).registerAsInstantiated("root class");
1260- bb.addRootClass(byte[].class, false, false).registerAsInstantiated("root class");
1261- bb.addRootClass(byte[][].class, false, false).registerAsInstantiated("root class");
1262- bb.addRootClass(Object[].class, false, false).registerAsInstantiated("root class");
1263- bb.addRootClass(CFunctionPointer[].class, false, false).registerAsInstantiated("root class");
1264- bb.addRootClass(PointerBase[].class, false, false).registerAsInstantiated("root class");
1265-
1266- /* MethodRef can conceal use of MethodPointer and MethodOffset until after analysis. */
1267- bb.addRootClass(MethodPointer.class, false, true);
1268- if (SubstrateOptions.useRelativeCodePointers()) {
1269- bb.addRootClass(MethodOffset.class, false, true);
1270- }
1271-
1272- bb.addRootMethod(ReflectionUtil.lookupMethod(SubstrateArraycopySnippets.class, "doArraycopy", Object.class, int.class, Object.class, int.class, int.class), true,
1273- "Runtime support, registered in " + NativeImageGenerator.class);
1274- bb.addRootMethod(ReflectionUtil.lookupMethod(Object.class, "getClass"), true, "Runtime support, registered in " + NativeImageGenerator.class);
1275-
1276- for (JavaKind kind : JavaKind.values()) {
1277- if (kind.isPrimitive() && kind != JavaKind.Void) {
1278- bb.addRootClass(kind.toJavaClass(), false, true);
1279- bb.addRootClass(kind.toBoxedJavaClass(), false, true).registerAsInstantiated("root class");
1280- bb.addRootField(kind.toBoxedJavaClass(), "value");
1281- bb.addRootMethod(ReflectionUtil.lookupMethod(kind.toBoxedJavaClass(), "valueOf", kind.toJavaClass()), true, "Runtime support, registered in " + NativeImageGenerator.class);
1282- bb.addRootMethod(ReflectionUtil.lookupMethod(kind.toBoxedJavaClass(), kind.getJavaName() + "Value"), true, "Runtime support, registered in " + NativeImageGenerator.class);
1283- /*
1284- * Register the cache location as reachable.
1285- * BoxingSnippets$Templates#getCacheLocation accesses the cache field.
1286- */
1287- Class<?>[] innerClasses = kind.toBoxedJavaClass().getDeclaredClasses();
1288- if (innerClasses != null && innerClasses.length > 0) {
1289- bb.getMetaAccess().lookupJavaType(innerClasses[0]).registerAsReachable("inner class of root class");
1290- }
1291- }
1292- }
1293- /* SubstrateTemplates#toLocationIdentity accesses the Counter.value field. */
1294- bb.getMetaAccess().lookupJavaType(JavaKind.Void.toJavaClass()).registerAsReachable("root class");
1295- bb.getMetaAccess().lookupJavaType(com.oracle.svm.core.util.Counter.class).registerAsReachable("root class");
1296- bb.getMetaAccess().lookupJavaType(com.oracle.svm.core.allocationprofile.AllocationCounter.class).registerAsReachable("root class");
1297- /*
1298- * SubstrateAllocationProfilingData is not actually present in the image since it is
1299- * only allocated at build time, is passed to snippets as a @ConstantParameter, and it
1300- * only contains final fields that are constant-folded. However, since the profiling
1301- * object is only allocated during lowering it is processed by the shadow heap after
1302- * analysis, so its type needs to be already marked reachable at this point.
1303- */
1304- bb.getMetaAccess().lookupJavaType(com.oracle.svm.core.graal.snippets.SubstrateAllocationSnippets.SubstrateAllocationProfilingData.class).registerAsReachable("root class");
1305- /*
1306- * Similarly to above, StackSlotIdentity only gets reachable during lowering, through
1307- * build time allocated constants. It doesn't actually end up in the image heap since
1308- * all its fields are final and are constant-folded, but the type becomes reachable,
1309- * through the shadow heap processing, after analysis.
1310- */
1311- bb.getMetaAccess().lookupJavaType(com.oracle.svm.core.graal.stackvalue.StackValueNode.StackSlotIdentity.class).registerAsReachable("root class");
1251+ registerRootElements(bb);
13121252
13131253 NativeImageGenerator.registerGraphBuilderPlugins(featureHandler, null, aProviders, aMetaAccess, aUniverse, nativeLibraries, loader, ParsingReason.PointsToAnalysis,
13141254 bb.getAnnotationSubstitutionProcessor(), classInitializationPlugin, ConfigurationValues.getTarget(), supportsStubBasedPlugins);
@@ -1318,6 +1258,75 @@ public static void initializeBigBang(Inflation bb, OptionValues options, Feature
13181258 }
13191259 }
13201260
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+ String rootClassReason = "system class included unconditionally";
1269+ String rootMethodReason = "system method included unconditionally";
1270+ bb.addRootClass(Object.class, false, false).registerAsInstantiated(rootClassReason);
1271+ bb.addRootField(DynamicHub.class, "vtable");
1272+ bb.addRootClass(String.class, false, false).registerAsInstantiated(rootClassReason);
1273+ bb.addRootClass(String[].class, false, false).registerAsInstantiated(rootClassReason);
1274+ bb.addRootField(String.class, "value").registerAsInstantiated(rootClassReason);
1275+ bb.addRootClass(long[].class, false, false).registerAsInstantiated(rootClassReason);
1276+ bb.addRootClass(byte[].class, false, false).registerAsInstantiated(rootClassReason);
1277+ bb.addRootClass(byte[][].class, false, false).registerAsInstantiated(rootClassReason);
1278+ bb.addRootClass(Object[].class, false, false).registerAsInstantiated(rootClassReason);
1279+ bb.addRootClass(CFunctionPointer[].class, false, false).registerAsInstantiated(rootClassReason);
1280+ bb.addRootClass(PointerBase[].class, false, false).registerAsInstantiated(rootClassReason);
1281+
1282+ /* MethodRef can conceal use of MethodPointer and MethodOffset until after analysis. */
1283+ bb.addRootClass(MethodPointer.class, false, true);
1284+ if (SubstrateOptions.useRelativeCodePointers()) {
1285+ bb.addRootClass(MethodOffset.class, false, true);
1286+ }
1287+
1288+ bb.addRootMethod(ReflectionUtil.lookupMethod(SubstrateArraycopySnippets.class, "doArraycopy",
1289+ Object.class, int.class, Object.class, int.class, int.class), true, rootMethodReason);
1290+ bb.addRootMethod(ReflectionUtil.lookupMethod(Object.class, "getClass"), true, rootMethodReason);
1291+
1292+ for (JavaKind kind : JavaKind.values()) {
1293+ if (kind.isPrimitive() && kind != JavaKind.Void) {
1294+ bb.addRootClass(kind.toJavaClass(), false, true);
1295+ bb.addRootClass(kind.toBoxedJavaClass(), false, true).registerAsInstantiated(rootClassReason);
1296+ bb.addRootField(kind.toBoxedJavaClass(), "value");
1297+ bb.addRootMethod(ReflectionUtil.lookupMethod(kind.toBoxedJavaClass(), "valueOf", kind.toJavaClass()), true, rootMethodReason);
1298+ bb.addRootMethod(ReflectionUtil.lookupMethod(kind.toBoxedJavaClass(), kind.getJavaName() + "Value"), true, rootMethodReason);
1299+ /*
1300+ * Register the cache location as reachable.
1301+ * BoxingSnippets$Templates#getCacheLocation accesses the cache field.
1302+ */
1303+ Class<?>[] innerClasses = kind.toBoxedJavaClass().getDeclaredClasses();
1304+ if (innerClasses != null && innerClasses.length > 0) {
1305+ bb.getMetaAccess().lookupJavaType(innerClasses[0]).registerAsReachable("inner class of " + rootClassReason);
1306+ }
1307+ }
1308+ }
1309+ /* SubstrateTemplates#toLocationIdentity accesses the Counter.value field. */
1310+ bb.getMetaAccess().lookupJavaType(JavaKind.Void.toJavaClass()).registerAsReachable(rootClassReason);
1311+ bb.getMetaAccess().lookupJavaType(com.oracle.svm.core.util.Counter.class).registerAsReachable(rootClassReason);
1312+ bb.getMetaAccess().lookupJavaType(com.oracle.svm.core.allocationprofile.AllocationCounter.class).registerAsReachable(rootClassReason);
1313+ /*
1314+ * SubstrateAllocationProfilingData is not actually present in the image since it is only
1315+ * allocated at build time, is passed to snippets as a @ConstantParameter, and it only
1316+ * contains final fields that are constant-folded. However, since the profiling object is
1317+ * only allocated during lowering it is processed by the shadow heap after analysis, so its
1318+ * type needs to be already marked reachable at this point.
1319+ */
1320+ bb.getMetaAccess().lookupJavaType(com.oracle.svm.core.graal.snippets.SubstrateAllocationSnippets.SubstrateAllocationProfilingData.class).registerAsReachable(rootClassReason);
1321+ /*
1322+ * Similarly to above, StackSlotIdentity only gets reachable during lowering, through build
1323+ * time allocated constants. It doesn't actually end up in the image heap since all its
1324+ * fields are final and are constant-folded, but the type becomes reachable, through the
1325+ * shadow heap processing, after analysis.
1326+ */
1327+ bb.getMetaAccess().lookupJavaType(com.oracle.svm.core.graal.stackvalue.StackValueNode.StackSlotIdentity.class).registerAsReachable(rootClassReason);
1328+ }
1329+
13211330 public static void performSnippetGraphAnalysis(BigBang bb, SubstrateReplacements replacements, OptionValues options, Function<Object, Object> objectTransformer) {
13221331 Collection<StructuredGraph> snippetGraphs = replacements.getSnippetGraphs(GraalOptions.TrackNodeSourcePosition.getValue(options), options, objectTransformer);
13231332 if (bb instanceof NativeImagePointsToAnalysis pointsToAnalysis) {
0 commit comments