24
24
*/
25
25
package com .oracle .svm .hosted .imagelayer ;
26
26
27
+ import static com .oracle .svm .hosted .imagelayer .CrossLayerConstantRegistryFeature .INVALID ;
28
+
27
29
import java .util .ArrayList ;
28
30
import java .util .EnumSet ;
29
31
import java .util .HashMap ;
56
58
import jdk .graal .compiler .core .common .CompressEncoding ;
57
59
import jdk .graal .compiler .core .common .NumUtil ;
58
60
import jdk .graal .compiler .debug .Assertions ;
61
+ import jdk .vm .ci .meta .JavaConstant ;
59
62
60
63
@ AutomaticallyRegisteredFeature
61
64
public class CrossLayerConstantRegistryFeature implements InternalFeature , FeatureSingleton , CrossLayerConstantRegistry {
65
+ static final int INVALID = -1 ;
66
+ private static final Object NULL_CONSTANT_MARKER = new Object ();
62
67
63
68
private record FutureConstantCandidateInfo (ImageHeapRelocatableConstant constant ) {
64
69
}
@@ -122,7 +127,7 @@ public void duringSetup(DuringSetupAccess access) {
122
127
*/
123
128
ImageHeapConstant replacePriorMarkersWithConstant (CrossLayerConstantRegistry registry , Object object ) {
124
129
if (object instanceof PriorLayerMarker priorLayerMarker ) {
125
- return registry .getConstant (priorLayerMarker .getKey ());
130
+ return ( ImageHeapConstant ) registry .getConstant (priorLayerMarker .getKey ());
126
131
}
127
132
128
133
return null ;
@@ -142,7 +147,7 @@ private void addInitialObjects(NativeImageHeap heap, HostedUniverse hUniverse) {
142
147
* used by a prior layer. However, currently it is not worth introducing this
143
148
* complication to the code.
144
149
*/
145
- ImageHeapConstant singletonConstant = (ImageHeapConstant ) hUniverse .getSnippetReflection ().forObject (futureConstant );
150
+ JavaConstant singletonConstant = futureConstant == NULL_CONSTANT_MARKER ? JavaConstant . NULL_POINTER : (ImageHeapConstant ) hUniverse .getSnippetReflection ().forObject (futureConstant );
146
151
heap .addConstant (singletonConstant , false , addReason );
147
152
}
148
153
}
@@ -159,7 +164,7 @@ public void afterCompilation(AfterCompilationAccess access) {
159
164
FutureConstantCandidateInfo futureConstant = (FutureConstantCandidateInfo ) entry .getValue ();
160
165
var constant = futureConstant .constant ();
161
166
AnalysisType type = constant .getType ();
162
- tracker .registerFutureTrackingInfo (new FutureTrackingInfo (key , FutureTrackingInfo .State .Type , type .getId (), - 1 ));
167
+ tracker .registerFutureTrackingInfo (new FutureTrackingInfo (key , FutureTrackingInfo .State .Type , type .getId (), INVALID ));
163
168
164
169
});
165
170
}
@@ -194,11 +199,17 @@ public void beforeImageWrite(BeforeImageWriteAccess access) {
194
199
*/
195
200
for (var entry : finalizedFutureConstants .entrySet ()) {
196
201
// We know these constants have been installed via addInitialObjects
197
- var futureConstant = (ImageHeapConstant ) snippetReflection .forObject (entry .getValue ());
198
- var objectInfo = heap .getConstantInfo (futureConstant );
199
- int id = ImageHeapConstant .getConstantID (futureConstant );
200
- FutureTrackingInfo info = (FutureTrackingInfo ) tracker .getTrackingInfo (entry .getKey ());
201
- tracker .updateFutureTrackingInfo (new FutureTrackingInfo (info .key (), FutureTrackingInfo .State .Final , id , NumUtil .safeToInt (objectInfo .getOffset ())));
202
+ Object value = entry .getValue ();
203
+ if (value == NULL_CONSTANT_MARKER ) {
204
+ FutureTrackingInfo info = (FutureTrackingInfo ) tracker .getTrackingInfo (entry .getKey ());
205
+ tracker .updateFutureTrackingInfo (new FutureTrackingInfo (info .key (), FutureTrackingInfo .State .Final , INVALID , INVALID ));
206
+ } else {
207
+ var futureConstant = (ImageHeapConstant ) snippetReflection .forObject (value );
208
+ var objectInfo = heap .getConstantInfo (futureConstant );
209
+ int id = ImageHeapConstant .getConstantID (futureConstant );
210
+ FutureTrackingInfo info = (FutureTrackingInfo ) tracker .getTrackingInfo (entry .getKey ());
211
+ tracker .updateFutureTrackingInfo (new FutureTrackingInfo (info .key (), FutureTrackingInfo .State .Final , id , NumUtil .safeToInt (objectInfo .getOffset ())));
212
+ }
202
213
}
203
214
204
215
if (ImageLayerBuildingSupport .buildingApplicationLayer ()) {
@@ -241,7 +252,8 @@ private void generateRelocationPatchArray() {
241
252
FutureTrackingInfo info = (FutureTrackingInfo ) tracker .getTrackingInfo (entry .getKey ());
242
253
VMError .guarantee (info .state () == FutureTrackingInfo .State .Final , "Invalid future %s" , info );
243
254
244
- int referenceEncoding = info .offset () >>> shift ;
255
+ int offset = info .offset ();
256
+ int referenceEncoding = offset == INVALID ? 0 : offset >>> shift ;
245
257
for (int heapOffset : offsetsToPatch ) {
246
258
patchArray .add (heapOffset - heapBeginOffset );
247
259
patchArray .add (referenceEncoding );
@@ -271,7 +283,7 @@ public boolean constantExists(String keyName) {
271
283
}
272
284
273
285
@ Override
274
- public ImageHeapConstant getConstant (String keyName ) {
286
+ public JavaConstant getConstant (String keyName ) {
275
287
TrackingInfo idInfo = tracker .getTrackingInfo (keyName );
276
288
if (idInfo instanceof PriorTrackingInfo prior ) {
277
289
return loader .getOrCreateConstant (prior .constantId ());
@@ -287,6 +299,10 @@ public ImageHeapConstant getConstant(String keyName) {
287
299
if (idInfo instanceof FutureTrackingInfo future ) {
288
300
VMError .guarantee (!finalizedFutureConstants .containsKey (keyName ), "Future was finalized in this layer: %s" , future );
289
301
302
+ if (future .loaderId () == INVALID ) {
303
+ return JavaConstant .NULL_POINTER ;
304
+ }
305
+
290
306
if (future .state () != FutureTrackingInfo .State .Type ) {
291
307
return loader .getOrCreateConstant (future .loaderId ());
292
308
}
@@ -339,7 +355,8 @@ public void finalizeFutureHeapConstant(String keyName, Object obj) {
339
355
checkCandidateRegistry ();
340
356
VMError .guarantee (tracker .getTrackingInfo (keyName ) instanceof FutureTrackingInfo , "This key was not registered as a future constant %s" , keyName );
341
357
342
- var previous = finalizedFutureConstants .putIfAbsent (keyName , obj );
358
+ Object object = obj == null ? NULL_CONSTANT_MARKER : obj ;
359
+ var previous = finalizedFutureConstants .putIfAbsent (keyName , object );
343
360
VMError .guarantee (previous == null , "This key has been registered before: %s" , keyName );
344
361
}
345
362
@@ -351,7 +368,7 @@ public void markFutureHeapConstantPatchSite(ImageHeapRelocatableConstant constan
351
368
VMError .guarantee (!patchingSealed , "Cross layer patching is sealed" );
352
369
var data = constant .getConstantData ();
353
370
tracker .registerPatchSite (data .key , heapOffset );
354
- tracker .updateFutureTrackingInfo (new FutureTrackingInfo (data .key , FutureTrackingInfo .State .Relocatable , ImageHeapConstant .getConstantID (constant ), - 1 ));
371
+ tracker .updateFutureTrackingInfo (new FutureTrackingInfo (data .key , FutureTrackingInfo .State .Relocatable , ImageHeapConstant .getConstantID (constant ), INVALID ));
355
372
}
356
373
357
374
/**
@@ -506,7 +523,7 @@ public static Object createFromLoader(ImageSingletonLoader loader) {
506
523
String key = futureKeys .next ();
507
524
FutureTrackingInfo .State state = FutureTrackingInfo .State .values ()[futureStates .next ()];
508
525
int loaderId = futureLoaderIds .next ();
509
- int offset = state == FutureTrackingInfo .State .Final ? futureOffsets .next () : - 1 ;
526
+ int offset = state == FutureTrackingInfo .State .Final ? futureOffsets .next () : INVALID ;
510
527
tracker .registerFutureTrackingInfo (new FutureTrackingInfo (key , state , loaderId , offset ));
511
528
512
529
List <Integer > offsetsToPatch = loader .readIntList (futureKeyPatchKey (key ));
@@ -531,14 +548,14 @@ enum State {
531
548
}
532
549
533
550
public FutureTrackingInfo {
534
- assert key != null && loaderId >= 0 : Assertions .errorMessage (key , loaderId );
551
+ assert key != null && loaderId >= INVALID : Assertions .errorMessage (key , loaderId );
535
552
switch (state ) {
536
553
case Type :
537
554
case Relocatable :
538
- assert offset == - 1 : Assertions .errorMessage (state , offset );
555
+ assert offset == INVALID : Assertions .errorMessage (state , offset );
539
556
break ;
540
557
case Final :
541
- assert offset > 0 : Assertions .errorMessage (state , offset );
558
+ assert offset > 0 || ( offset == INVALID && loaderId == INVALID ) : Assertions .errorMessage (state , offset );
542
559
}
543
560
}
544
561
}
0 commit comments