@@ -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