@@ -121,38 +121,9 @@ public class ImageLayerWriter {
121121 private final boolean useSharedLayerGraphs ;
122122 private final boolean useSharedLayerStrengthenedGraphs ;
123123
124- /*
125- * Types, members and constants to persist even when they are not considered reachable by the
126- * analysis, or referenced from the image heap. Typically, these elements would be reachable
127- * from a persisted graph.
128- */
129- private boolean sealed = false ;
130- private final Set <AnalysisType > typesToPersist = ConcurrentHashMap .newKeySet ();
131- private final Set <AnalysisMethod > methodsToPersist = ConcurrentHashMap .newKeySet ();
132- private final Set <AnalysisField > fieldsToPersist = ConcurrentHashMap .newKeySet ();
133124 private final Set <ImageHeapConstant > constantsToPersist = ConcurrentHashMap .newKeySet ();
134125
135- public void ensureTypePersisted (AnalysisType type ) {
136- assert !sealed ;
137- if (typesToPersist .add (type )) {
138- afterTypeAdded (type );
139- }
140- }
141-
142- public void ensureMethodPersisted (AnalysisMethod method ) {
143- assert !sealed ;
144- if (methodsToPersist .add (method )) {
145- afterMethodAdded (method );
146- }
147- }
148-
149- public void ensureFieldPersisted (AnalysisField field ) {
150- assert !sealed ;
151- fieldsToPersist .add (field );
152- }
153-
154126 public void ensureConstantPersisted (ImageHeapConstant constant ) {
155- assert !sealed ;
156127 constantsToPersist .add (constant );
157128 afterConstantAdded (constant );
158129 }
@@ -164,7 +135,8 @@ protected record ConstantParent(int constantId, int index) {
164135 private record FileInfo (Path layerFilePath , String fileName , String suffix ) {
165136 }
166137
167- protected record MethodGraphsInfo (String analysisGraphLocation , boolean analysisGraphIsIntrinsic , String strengthenedGraphLocation ) {
138+ protected record MethodGraphsInfo (String analysisGraphLocation , boolean analysisGraphIsIntrinsic ,
139+ String strengthenedGraphLocation ) {
168140
169141 static final MethodGraphsInfo NO_GRAPHS = new MethodGraphsInfo (null , false , null );
170142
@@ -254,6 +226,11 @@ public void setAnalysisUniverse(AnalysisUniverse aUniverse) {
254226 this .aUniverse = aUniverse ;
255227 }
256228
229+ @ SuppressWarnings ("unused" )
230+ public void onTrackedAcrossLayer (AnalysisMethod method , Object reason ) {
231+ imageLayerWriterHelper .onTrackedAcrossLayer (method , reason );
232+ }
233+
257234 public void dumpFiles () {
258235 graphsOutput .finish ();
259236
@@ -293,6 +270,10 @@ public void persistAnalysisInfo() {
293270 snapshotBuilder .setNextFieldId (aUniverse .getNextFieldId ());
294271 snapshotBuilder .setNextConstantId (ImageHeapConstant .getCurrentId ());
295272
273+ List <AnalysisType > typesToPersist = aUniverse .getTypes ().stream ().filter (AnalysisType ::isTrackedAcrossLayers ).toList ();
274+ List <AnalysisMethod > methodsToPersist = aUniverse .getMethods ().stream ().filter (AnalysisMethod ::isTrackedAcrossLayers ).toList ();
275+ List <AnalysisField > fieldsToPersist = aUniverse .getFields ().stream ().filter (AnalysisField ::isTrackedAcrossLayers ).toList ();
276+
296277 initSortedList (snapshotBuilder ::initTypes , typesToPersist , Comparator .comparingInt (AnalysisType ::getId ), this ::persistType );
297278 initSortedList (snapshotBuilder ::initMethods , methodsToPersist , Comparator .comparingInt (AnalysisMethod ::getId ), this ::persistMethod );
298279 initSortedList (snapshotBuilder ::initFields , fieldsToPersist , Comparator .comparingInt (AnalysisField ::getId ), this ::persistField );
@@ -347,7 +328,7 @@ protected void persistHook() {
347328 }
348329
349330 public boolean isTypePersisted (AnalysisType type ) {
350- return typesToPersist . contains ( type );
331+ return type . isTrackedAcrossLayers ( );
351332 }
352333
353334 private void persistType (AnalysisType type , Supplier <PersistedAnalysisType .Builder > builderSupplier ) {
@@ -375,12 +356,6 @@ protected void persistType(AnalysisType type, String typeDescriptor, PersistedAn
375356 if (enclosingType != null ) {
376357 builder .setEnclosingTypeId (enclosingType .getId ());
377358 }
378- } catch (AnalysisError .TypeNotFoundError e ) {
379- /*
380- * GR-59571: The enclosing type is not automatically created when the inner type is
381- * created. If the enclosing type is missing, it is ignored for now. This try/catch
382- * block could be removed after the trackAcrossLayers is fully implemented.
383- */
384359 } catch (InternalError | TypeNotPresentException | LinkageError e ) {
385360 /* Ignore missing type errors. */
386361 }
@@ -401,6 +376,8 @@ protected void persistType(AnalysisType type, String typeDescriptor, PersistedAn
401376 builder .setIsReachable (type .isReachable ());
402377
403378 imageLayerWriterHelper .persistType (type , builder );
379+
380+ afterTypeAdded (type );
404381 }
405382
406383 protected static void initInts (IntFunction <PrimitiveList .Int .Builder > builderSupplier , IntStream ids ) {
@@ -419,31 +396,17 @@ protected static void initStringList(IntFunction<TextList.Builder> builderSuppli
419396 }
420397 }
421398
399+ @ SuppressWarnings ("unused" )
422400 protected void afterTypeAdded (AnalysisType type ) {
423- /*
424- * Some persisted types are not reachable. In this case, the super class and interfaces have
425- * to be persisted manually as well.
426- */
427- if (type .getSuperclass () != null ) {
428- ensureTypePersisted (type .getSuperclass ());
429- }
430- for (AnalysisType iface : type .getInterfaces ()) {
431- ensureTypePersisted (iface );
432- }
433- }
434-
435- protected void afterMethodAdded (AnalysisMethod method ) {
436- ensureTypePersisted (method .getSignature ().getReturnType ());
437- imageLayerWriterHelper .afterMethodAdded (method );
438401 }
439402
440403 private void afterConstantAdded (ImageHeapConstant constant ) {
441- ensureTypePersisted ( constant .getType ());
404+ constant .getType (). registerAsTrackedAcrossLayers ( constant );
442405 /* If this is a Class constant persist the corresponding type. */
443406 ConstantReflectionProvider constantReflection = aUniverse .getBigbang ().getConstantReflectionProvider ();
444407 AnalysisType typeFromClassConstant = (AnalysisType ) constantReflection .asJavaType (constant );
445408 if (typeFromClassConstant != null ) {
446- ensureTypePersisted ( typeFromClassConstant );
409+ typeFromClassConstant . registerAsTrackedAcrossLayers ( constant );
447410 }
448411 }
449412
@@ -537,31 +500,25 @@ public boolean isMethodPersisted(AnalysisMethod method) {
537500 return methodsMap .containsKey (name );
538501 }
539502
540- public void persistMethodGraphs () {
541- assert aUniverse .sealed ();
542-
543- aUniverse .getTypes ().stream ().filter (AnalysisType ::isTrackedAcrossLayers )
544- .forEach (this ::ensureTypePersisted );
545-
546- aUniverse .getMethods ().stream ().filter (AnalysisMethod ::isTrackedAcrossLayers )
547- .forEach (this ::ensureMethodPersisted );
548-
549- aUniverse .getFields ().stream ().filter (AnalysisField ::isTrackedAcrossLayers )
550- .forEach (this ::ensureFieldPersisted );
551-
503+ public void persistAnalysisParsedGraphs () {
552504 // Persisting graphs discovers additional types, members and constants that need persisting
553505 Set <AnalysisMethod > persistedGraphMethods = new HashSet <>();
506+ boolean modified ;
554507 do {
555- for (AnalysisMethod method : methodsToPersist ) {
508+ modified = false ;
509+ /*
510+ * GR-60503: It would be better to mark all the elements as trackedAcrossLayers before
511+ * the end of the analysis and only iterate only once over all methods.
512+ */
513+ for (AnalysisMethod method : aUniverse .getMethods ().stream ().filter (AnalysisMethod ::isTrackedAcrossLayers ).toList ()) {
556514 if (persistedGraphMethods .add (method )) {
515+ modified = true ;
557516 persistAnalysisParsedGraph (method );
558517 }
559518 }
560- } while (! persistedGraphMethods . equals ( methodsToPersist ) );
519+ } while (modified );
561520
562521 // Note that constants are scanned late so all values are available.
563-
564- sealed = true ;
565522 }
566523
567524 private void persistAnalysisParsedGraph (AnalysisMethod method ) {
@@ -649,7 +606,9 @@ protected void persistField(AnalysisField field, PersistedAnalysisField.Builder
649606 protected void persistConstant (ImageHeapConstant imageHeapConstant , ConstantParent parent , PersistedConstant .Builder builder , Set <Integer > constantsToRelink ) {
650607 int id = getConstantId (imageHeapConstant );
651608 builder .setId (id );
652- builder .setTypeId (imageHeapConstant .getType ().getId ());
609+ AnalysisType type = imageHeapConstant .getType ();
610+ AnalysisError .guarantee (type .isTrackedAcrossLayers (), "Type %s from constant %s should have been marked as trackedAcrossLayers, but was not" , type , imageHeapConstant );
611+ builder .setTypeId (type .getId ());
653612
654613 IdentityHashCodeProvider identityHashCodeProvider = (IdentityHashCodeProvider ) aUniverse .getBigbang ().getConstantReflectionProvider ();
655614 int identityHashCode = identityHashCodeProvider .identityHashCode (imageHeapConstant );
0 commit comments