3535import java .util .List ;
3636import java .util .Map ;
3737import java .util .Set ;
38+ import java .util .concurrent .ConcurrentHashMap ;
39+ import java .util .stream .Collectors ;
3840
3941import org .graalvm .nativeimage .ImageSingletons ;
4042import org .graalvm .word .PointerBase ;
5759import com .oracle .svm .hosted .c .CGlobalDataFeature ;
5860import com .oracle .svm .hosted .image .NativeImage ;
5961import com .oracle .svm .hosted .meta .HostedMethod ;
62+ import com .oracle .svm .hosted .meta .HostedMethodNameFactory .MethodNameInfo ;
6063
6164import jdk .graal .compiler .debug .Assertions ;
6265
6366public class HostedDynamicLayerInfo extends DynamicImageLayerInfo implements LayeredImageSingleton {
6467 private final Map <Integer , Integer > methodIdToOffsetMap ;
68+ private final ConcurrentHashMap <Integer , MethodNameInfo > methodIdToNameInfoMap ;
6569 private final CGlobalData <PointerBase > cGlobalData ;
6670 private final Set <HostedMethod > priorLayerHostedMethods = new HashSet <>();
71+ private boolean persisted = false ;
6772
6873 HostedDynamicLayerInfo () {
69- this (0 , null , new HashMap <>());
74+ this (0 , null , new HashMap <>(), new ConcurrentHashMap <>() );
7075 }
7176
7277 public static HostedDynamicLayerInfo singleton () {
7378 return (HostedDynamicLayerInfo ) ImageSingletons .lookup (DynamicImageLayerInfo .class );
7479 }
7580
76- private HostedDynamicLayerInfo (int layerNumber , String codeSectionStartSymbol , Map <Integer , Integer > methodIdToOffsetMap ) {
81+ private HostedDynamicLayerInfo (int layerNumber , String codeSectionStartSymbol , Map <Integer , Integer > methodIdToOffsetMap , ConcurrentHashMap < Integer , MethodNameInfo > methodIdToNameInfoMap ) {
7782 super (layerNumber );
7883 this .methodIdToOffsetMap = methodIdToOffsetMap ;
84+ this .methodIdToNameInfoMap = methodIdToNameInfoMap ;
7985 cGlobalData = codeSectionStartSymbol == null ? null : CGlobalDataFactory .forSymbol (codeSectionStartSymbol );
8086 }
8187
@@ -95,7 +101,23 @@ public boolean compiledInPriorLayer(AnalysisMethod aMethod) {
95101 return methodIdToOffsetMap .containsKey (aMethod .getId ());
96102 }
97103
98- void registerOffset (HostedMethod method ) {
104+ public MethodNameInfo loadMethodNameInfo (AnalysisMethod method ) {
105+ return methodIdToNameInfoMap .get (method .getId ());
106+ }
107+
108+ public void recordPersistedMethod (HostedMethod hMethod ) {
109+ assert !persisted : "Too late to record this information" ;
110+ MethodNameInfo info = new MethodNameInfo (hMethod .getName (), hMethod .getUniqueShortName ());
111+ var prev = methodIdToNameInfoMap .put (hMethod .getWrapped ().getId (), info );
112+ // will have to change for multiple layers
113+ assert prev == null : prev ;
114+ }
115+
116+ public Set <String > getReservedNames () {
117+ return methodIdToNameInfoMap .values ().stream ().map (MethodNameInfo ::uniqueShortName ).collect (Collectors .toUnmodifiableSet ());
118+ }
119+
120+ void registerCompilation (HostedMethod method ) {
99121 assert BuildPhaseProvider .isCompileQueueFinished ();
100122 int offset = method .getCodeAddressOffset ();
101123 int methodID = method .getWrapped ().getId ();
@@ -143,6 +165,7 @@ boolean verifyUniqueOffsets(Collection<? extends SharedMethod> methods) {
143165
144166 @ Override
145167 public PersistFlags preparePersist (ImageSingletonWriter writer ) {
168+ persisted = true ;
146169 /*
147170 * When there are multiple shared layers we will need to store the starting code offset of
148171 * each layer.
@@ -163,20 +186,33 @@ public PersistFlags preparePersist(ImageSingletonWriter writer) {
163186 * Write out all method offsets.
164187 */
165188 List <Integer > offsets = new ArrayList <>(methodIdToOffsetMap .size ());
166- List <Integer > methodIDs = new ArrayList <>(methodIdToOffsetMap .size ());
189+ List <Integer > methodOffsetIds = new ArrayList <>(methodIdToOffsetMap .size ());
167190 methodIdToOffsetMap .forEach ((key , value ) -> {
168- methodIDs .add (key );
191+ methodOffsetIds .add (key );
169192 offsets .add (value );
170193 });
171- writer .writeIntList ("methodIDs " , methodIDs );
194+ writer .writeIntList ("methodOffsetIDs " , methodOffsetIds );
172195 writer .writeIntList ("offsets" , offsets );
173196
197+ /*
198+ * Write out all persisted method names
199+ */
200+ List <Integer > methodNameIds = new ArrayList <>(methodIdToNameInfoMap .size ());
201+ List <String > names = new ArrayList <>(methodIdToNameInfoMap .size () * 2 );
202+ methodIdToNameInfoMap .forEach ((key , value ) -> {
203+ methodNameIds .add (key );
204+ names .add (value .name ());
205+ names .add (value .uniqueShortName ());
206+ });
207+ writer .writeIntList ("methodNameIDs" , methodNameIds );
208+ writer .writeStringList ("names" , names );
209+
174210 return PersistFlags .CREATE ;
175211 }
176212
177213 @ SuppressWarnings ("unused" )
178214 public static Object createFromLoader (ImageSingletonLoader loader ) {
179- assert loader .readIntList ("offsets" ).size () == loader .readIntList ("methodIDs " ).size () : Assertions .errorMessage ("Offsets and methodIDs are incompatible" , loader .readIntList ("offsets" ),
215+ assert loader .readIntList ("offsets" ).size () == loader .readIntList ("methodOffsetIDs " ).size () : Assertions .errorMessage ("Offsets and methodIDs are incompatible" , loader .readIntList ("offsets" ),
180216 loader .readIntList ("methodIDs" ));
181217
182218 int layerNumber = loader .readInt ("nextLayerNumber" );
@@ -187,16 +223,32 @@ public static Object createFromLoader(ImageSingletonLoader loader) {
187223 * Load the offsets of all methods in the prior layers.
188224 */
189225 var offsets = loader .readIntList ("offsets" ).iterator ();
190- var methodIDs = loader .readIntList ("methodIDs " ).iterator ();
226+ var methodOffsetIds = loader .readIntList ("methodOffsetIDs " ).iterator ();
191227 Map <Integer , Integer > initialMethodIdToOffsetMap = new HashMap <>();
192228
193229 while (offsets .hasNext ()) {
194- int methodId = methodIDs .next ();
230+ int methodId = methodOffsetIds .next ();
195231 int offset = offsets .next ();
196- initialMethodIdToOffsetMap .put (methodId , offset );
232+ var prev = initialMethodIdToOffsetMap .put (methodId , offset );
233+ assert prev == null ;
234+ }
235+
236+ /*
237+ * Load the names of all methods in the prior layers.
238+ */
239+ var names = loader .readStringList ("names" ).iterator ();
240+ var methodNameIds = loader .readIntList ("methodNameIDs" ).iterator ();
241+ ConcurrentHashMap <Integer , MethodNameInfo > initialMethodIdToMethodNameMap = new ConcurrentHashMap <>();
242+
243+ while (methodNameIds .hasNext ()) {
244+ int methodId = methodNameIds .next ();
245+ String name = names .next ();
246+ String uniqueShortName = names .next ();
247+ var prev = initialMethodIdToMethodNameMap .put (methodId , new MethodNameInfo (name , uniqueShortName ));
248+ assert prev == null ;
197249 }
198250
199- return new HostedDynamicLayerInfo (layerNumber , codeSectionStartSymbol , initialMethodIdToOffsetMap );
251+ return new HostedDynamicLayerInfo (layerNumber , codeSectionStartSymbol , initialMethodIdToOffsetMap , initialMethodIdToMethodNameMap );
200252 }
201253}
202254
@@ -231,7 +283,7 @@ public void afterCompilation(AfterCompilationAccess access) {
231283 assert HostedDynamicLayerInfo .singleton ().verifyUniqueOffsets (config .getMethods ());
232284
233285 for (var entry : config .getCodeCache ().getOrderedCompilations ()) {
234- HostedDynamicLayerInfo .singleton ().registerOffset (entry .getLeft ());
286+ HostedDynamicLayerInfo .singleton ().registerCompilation (entry .getLeft ());
235287 }
236288 }
237289}
0 commit comments