@@ -1110,7 +1110,10 @@ protected void setupNativeImage(OptionValues options, Map<Method, CEntryPointDat
1110
1110
initializeBigBang (bb , options , featureHandler , nativeLibraries , debug , aMetaAccess , aUniverse .getSubstitutions (), loader , true ,
1111
1111
new SubstrateClassInitializationPlugin (hostVM ), this .isStubBasedPluginsSupported (), aProviders );
1112
1112
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
+
1114
1117
if (loader .classLoaderSupport .isPreserveMode ()) {
1115
1118
PreserveOptionsSupport .registerPreservedClasses (bb , originalMetaAccess , loader .classLoaderSupport );
1116
1119
}
@@ -1244,71 +1247,8 @@ public static void initializeBigBang(Inflation bb, OptionValues options, Feature
1244
1247
HostedImageLayerBuildingSupport .singleton ().getLoader ().relinkNonTransformedStaticFinalFieldValues ();
1245
1248
}
1246
1249
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
- */
1253
1250
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 );
1312
1252
1313
1253
NativeImageGenerator .registerGraphBuilderPlugins (featureHandler , null , aProviders , aMetaAccess , aUniverse , nativeLibraries , loader , ParsingReason .PointsToAnalysis ,
1314
1254
bb .getAnnotationSubstitutionProcessor (), classInitializationPlugin , ConfigurationValues .getTarget (), supportsStubBasedPlugins );
@@ -1318,6 +1258,75 @@ public static void initializeBigBang(Inflation bb, OptionValues options, Feature
1318
1258
}
1319
1259
}
1320
1260
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
+
1321
1330
public static void performSnippetGraphAnalysis (BigBang bb , SubstrateReplacements replacements , OptionValues options , Function <Object , Object > objectTransformer ) {
1322
1331
Collection <StructuredGraph > snippetGraphs = replacements .getSnippetGraphs (GraalOptions .TrackNodeSourcePosition .getValue (options ), options , objectTransformer );
1323
1332
if (bb instanceof NativeImagePointsToAnalysis pointsToAnalysis ) {
0 commit comments