35
35
import java .util .List ;
36
36
import java .util .Map ;
37
37
import java .util .Set ;
38
+ import java .util .concurrent .ConcurrentHashMap ;
39
+ import java .util .stream .Collectors ;
38
40
39
41
import org .graalvm .nativeimage .ImageSingletons ;
40
42
import org .graalvm .word .PointerBase ;
57
59
import com .oracle .svm .hosted .c .CGlobalDataFeature ;
58
60
import com .oracle .svm .hosted .image .NativeImage ;
59
61
import com .oracle .svm .hosted .meta .HostedMethod ;
62
+ import com .oracle .svm .hosted .meta .HostedMethodNameFactory .MethodNameInfo ;
60
63
61
64
import jdk .graal .compiler .debug .Assertions ;
62
65
63
66
public class HostedDynamicLayerInfo extends DynamicImageLayerInfo implements LayeredImageSingleton {
64
67
private final Map <Integer , Integer > methodIdToOffsetMap ;
68
+ private final ConcurrentHashMap <Integer , MethodNameInfo > methodIdToNameInfoMap ;
65
69
private final CGlobalData <PointerBase > cGlobalData ;
66
70
private final Set <HostedMethod > priorLayerHostedMethods = new HashSet <>();
71
+ private boolean persisted = false ;
67
72
68
73
HostedDynamicLayerInfo () {
69
- this (0 , null , new HashMap <>());
74
+ this (0 , null , new HashMap <>(), new ConcurrentHashMap <>() );
70
75
}
71
76
72
77
public static HostedDynamicLayerInfo singleton () {
73
78
return (HostedDynamicLayerInfo ) ImageSingletons .lookup (DynamicImageLayerInfo .class );
74
79
}
75
80
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 ) {
77
82
super (layerNumber );
78
83
this .methodIdToOffsetMap = methodIdToOffsetMap ;
84
+ this .methodIdToNameInfoMap = methodIdToNameInfoMap ;
79
85
cGlobalData = codeSectionStartSymbol == null ? null : CGlobalDataFactory .forSymbol (codeSectionStartSymbol );
80
86
}
81
87
@@ -95,7 +101,23 @@ public boolean compiledInPriorLayer(AnalysisMethod aMethod) {
95
101
return methodIdToOffsetMap .containsKey (aMethod .getId ());
96
102
}
97
103
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 ) {
99
121
assert BuildPhaseProvider .isCompileQueueFinished ();
100
122
int offset = method .getCodeAddressOffset ();
101
123
int methodID = method .getWrapped ().getId ();
@@ -143,6 +165,7 @@ boolean verifyUniqueOffsets(Collection<? extends SharedMethod> methods) {
143
165
144
166
@ Override
145
167
public PersistFlags preparePersist (ImageSingletonWriter writer ) {
168
+ persisted = true ;
146
169
/*
147
170
* When there are multiple shared layers we will need to store the starting code offset of
148
171
* each layer.
@@ -163,20 +186,33 @@ public PersistFlags preparePersist(ImageSingletonWriter writer) {
163
186
* Write out all method offsets.
164
187
*/
165
188
List <Integer > offsets = new ArrayList <>(methodIdToOffsetMap .size ());
166
- List <Integer > methodIDs = new ArrayList <>(methodIdToOffsetMap .size ());
189
+ List <Integer > methodOffsetIds = new ArrayList <>(methodIdToOffsetMap .size ());
167
190
methodIdToOffsetMap .forEach ((key , value ) -> {
168
- methodIDs .add (key );
191
+ methodOffsetIds .add (key );
169
192
offsets .add (value );
170
193
});
171
- writer .writeIntList ("methodIDs " , methodIDs );
194
+ writer .writeIntList ("methodOffsetIDs " , methodOffsetIds );
172
195
writer .writeIntList ("offsets" , offsets );
173
196
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
+
174
210
return PersistFlags .CREATE ;
175
211
}
176
212
177
213
@ SuppressWarnings ("unused" )
178
214
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" ),
180
216
loader .readIntList ("methodIDs" ));
181
217
182
218
int layerNumber = loader .readInt ("nextLayerNumber" );
@@ -187,16 +223,32 @@ public static Object createFromLoader(ImageSingletonLoader loader) {
187
223
* Load the offsets of all methods in the prior layers.
188
224
*/
189
225
var offsets = loader .readIntList ("offsets" ).iterator ();
190
- var methodIDs = loader .readIntList ("methodIDs " ).iterator ();
226
+ var methodOffsetIds = loader .readIntList ("methodOffsetIDs " ).iterator ();
191
227
Map <Integer , Integer > initialMethodIdToOffsetMap = new HashMap <>();
192
228
193
229
while (offsets .hasNext ()) {
194
- int methodId = methodIDs .next ();
230
+ int methodId = methodOffsetIds .next ();
195
231
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 ;
197
249
}
198
250
199
- return new HostedDynamicLayerInfo (layerNumber , codeSectionStartSymbol , initialMethodIdToOffsetMap );
251
+ return new HostedDynamicLayerInfo (layerNumber , codeSectionStartSymbol , initialMethodIdToOffsetMap , initialMethodIdToMethodNameMap );
200
252
}
201
253
}
202
254
@@ -231,7 +283,7 @@ public void afterCompilation(AfterCompilationAccess access) {
231
283
assert HostedDynamicLayerInfo .singleton ().verifyUniqueOffsets (config .getMethods ());
232
284
233
285
for (var entry : config .getCodeCache ().getOrderedCompilations ()) {
234
- HostedDynamicLayerInfo .singleton ().registerOffset (entry .getLeft ());
286
+ HostedDynamicLayerInfo .singleton ().registerCompilation (entry .getLeft ());
235
287
}
236
288
}
237
289
}
0 commit comments