Skip to content

Commit 1ff637a

Browse files
committed
[GR-42996] Clean up use of ImageHeapConstant.
PullRequest: graal/15609
2 parents aafed07 + 5d0ed01 commit 1ff637a

File tree

14 files changed

+210
-84
lines changed

14 files changed

+210
-84
lines changed

substratevm/src/com.oracle.graal.pointsto/src/com/oracle/graal/pointsto/heap/HeapSnapshotVerifier.java

Lines changed: 5 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -343,11 +343,7 @@ public void forScannedConstant(JavaConstant value, ScanReason reason) {
343343
}
344344

345345
private void ensureTypeScanned(JavaConstant typeConstant, AnalysisType type, ScanReason reason) {
346-
if (typeConstant instanceof ImageHeapConstant imageHeapConstant) {
347-
ensureTypeScanned(null, imageHeapConstant.getHostedObject(), type, reason);
348-
} else {
349-
ensureTypeScanned(null, typeConstant, type, reason);
350-
}
346+
ensureTypeScanned(null, typeConstant, type, reason);
351347
}
352348

353349
@SuppressWarnings({"unchecked", "rawtypes"})
@@ -361,14 +357,13 @@ private void ensureTypeScanned(JavaConstant value, JavaConstant typeConstant, An
361357
onNoTaskForClassConstant(type, reason);
362358
scanner.toImageHeapObject(typeConstant, reason);
363359
heapPatched = true;
364-
} else if (task instanceof ImageHeapConstant) {
365-
JavaConstant snapshot = ((ImageHeapConstant) task).getHostedObject();
366-
verifyTypeConstant(snapshot, typeConstant, reason);
360+
} else if (task instanceof ImageHeapConstant snapshot) {
361+
verifyTypeConstant(maybeUnwrapSnapshot(snapshot, typeConstant instanceof ImageHeapConstant), typeConstant, reason);
367362
} else {
368363
assert task instanceof AnalysisFuture;
369364
AnalysisFuture<ImageHeapConstant> future = ((AnalysisFuture<ImageHeapConstant>) task);
370365
if (future.isDone()) {
371-
JavaConstant snapshot = future.guardedGet().getHostedObject();
366+
JavaConstant snapshot = maybeUnwrapSnapshot(future.guardedGet(), typeConstant instanceof ImageHeapConstant);
372367
verifyTypeConstant(snapshot, typeConstant, reason);
373368
} else {
374369
onTaskForClassConstantNotDone(value, type, reason);
@@ -379,7 +374,7 @@ private void ensureTypeScanned(JavaConstant value, JavaConstant typeConstant, An
379374

380375
private void verifyTypeConstant(JavaConstant snapshot, JavaConstant typeConstant, ScanReason reason) {
381376
if (!Objects.equals(snapshot, typeConstant)) {
382-
throw error(reason, "Value mismatch for class constant snapshot: %s %n new value: %s %n", snapshot, typeConstant);
377+
throw error(reason, "Value mismatch for class constant%n snapshot: %s %n new value: %s %n", snapshot, typeConstant);
383378
}
384379
}
385380

substratevm/src/com.oracle.graal.pointsto/src/com/oracle/graal/pointsto/heap/ImageHeapScanner.java

Lines changed: 5 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -35,8 +35,8 @@
3535
import org.graalvm.collections.MapCursor;
3636
import org.graalvm.compiler.api.replacements.SnippetReflectionProvider;
3737
import org.graalvm.compiler.core.common.SuppressFBWarnings;
38+
import org.graalvm.compiler.core.common.type.TypedConstant;
3839
import org.graalvm.compiler.debug.GraalError;
39-
import org.graalvm.word.WordBase;
4040

4141
import com.oracle.graal.pointsto.BigBang;
4242
import com.oracle.graal.pointsto.ObjectScanner;
@@ -397,6 +397,8 @@ private void notifyAnalysis(AnalysisField field, ImageHeapInstance receiver, Jav
397397
private boolean doNotifyAnalysis(AnalysisField field, JavaConstant receiver, JavaConstant fieldValue, ScanReason reason) {
398398
boolean analysisModified = false;
399399
if (fieldValue.getJavaKind() == JavaKind.Object && hostVM.isRelocatedPointer(metaAccess, fieldValue)) {
400+
/* Ensure the relocatable pointer type is analysed. */
401+
((AnalysisType) ((TypedConstant) fieldValue).getType(metaAccess)).registerAsReachable(reason);
400402
analysisModified = scanningObserver.forRelocatedPointerFieldValue(receiver, field, fieldValue, reason);
401403
} else if (fieldValue.isNull()) {
402404
analysisModified = scanningObserver.forNullFieldValue(receiver, field, reason);
@@ -430,26 +432,15 @@ private void notifyAnalysis(ImageHeapArray array, AnalysisType arrayType, int el
430432
}
431433

432434
private boolean isNonNullObjectConstant(JavaConstant constant) {
433-
return constant.getJavaKind() == JavaKind.Object && constant.isNonNull() && !isWordType(constant);
434-
}
435-
436-
public boolean isWordType(JavaConstant rawElementValue) {
437-
/*
438-
* UniverseMetaAccess.isInstanceOf cannot be used here because the object replacers may have
439-
* not yet been applied to the object. This can lead to
440-
* "Type is not available in this platform" issues when accessing the object type. A proper
441-
* fix will add a JavaConstant implementation class for relocatable word values.(GR-48681).
442-
*/
443-
Object obj = snippetReflection.asObject(Object.class, rawElementValue);
444-
return obj instanceof WordBase;
435+
return constant.getJavaKind() == JavaKind.Object && constant.isNonNull() && !universe.hostVM().isRelocatedPointer(metaAccess, constant);
445436
}
446437

447438
private boolean notifyAnalysis(JavaConstant array, AnalysisType arrayType, JavaConstant elementValue, int elementIndex, ScanReason reason) {
448439
boolean analysisModified;
449440
if (elementValue.isNull()) {
450441
analysisModified = scanningObserver.forNullArrayElement(array, arrayType, elementIndex, reason);
451442
} else {
452-
if (isWordType(elementValue)) {
443+
if (universe.hostVM().isRelocatedPointer(metaAccess, elementValue)) {
453444
return false;
454445
}
455446
AnalysisType elementType = metaAccess.lookupJavaType(elementValue);
@@ -524,10 +515,6 @@ protected ValueSupplier<JavaConstant> readHostedFieldValue(AnalysisField field,
524515
return ValueSupplier.eagerValue(value);
525516
}
526517

527-
public JavaConstant readFieldValue(AnalysisField field, JavaConstant receiver) {
528-
return constantReflection.readFieldValue(field, receiver);
529-
}
530-
531518
public void rescanRoot(Field reflectionField) {
532519
maybeRunInExecutor(unused -> {
533520
AnalysisType type = metaAccess.lookupJavaType(reflectionField.getDeclaringClass());

substratevm/src/com.oracle.graal.pointsto/src/com/oracle/graal/pointsto/results/StrengthenGraphs.java

Lines changed: 0 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -94,7 +94,6 @@
9494
import com.oracle.graal.pointsto.flow.MethodFlowsGraph;
9595
import com.oracle.graal.pointsto.flow.MethodTypeFlow;
9696
import com.oracle.graal.pointsto.flow.TypeFlow;
97-
import com.oracle.graal.pointsto.heap.ImageHeapConstant;
9897
import com.oracle.graal.pointsto.infrastructure.Universe;
9998
import com.oracle.graal.pointsto.meta.AnalysisField;
10099
import com.oracle.graal.pointsto.meta.AnalysisMethod;
@@ -728,15 +727,6 @@ private Object strengthenStampFromTypeFlow(ValueNode node, TypeFlow<?> nodeFlow,
728727

729728
if (hasUsages && allowConstantFolding && !nodeTypeState.canBeNull()) {
730729
JavaConstant constantValue = nodeTypeState.asConstant();
731-
if (constantValue instanceof ImageHeapConstant) {
732-
/*
733-
* GR-42996: until the AOT compilation can properly constant fold also
734-
* ImageHeapConstant, we unwrap the ImageHeapConstant to the hosted object. This
735-
* also means we do not constant fold yet when the constant does not wrap a
736-
* hosted object.
737-
*/
738-
constantValue = ((ImageHeapConstant) constantValue).getHostedObject();
739-
}
740730
if (constantValue != null) {
741731
return constantValue;
742732
}

substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/NativeImageGenerator.java

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -603,7 +603,7 @@ protected void doRun(Map<Method, CEntryPointData> entryPoints,
603603

604604
hUniverse = new HostedUniverse(bb);
605605
hMetaAccess = new HostedMetaAccess(hUniverse, bb.getMetaAccess());
606-
((SVMImageHeapScanner) aUniverse.getHeapScanner()).setHostedMetaAccess(hMetaAccess);
606+
((AnalysisConstantReflectionProvider) bb.getConstantReflectionProvider()).setHostedMetaAccess(hMetaAccess);
607607

608608
BeforeUniverseBuildingAccessImpl beforeUniverseBuildingConfig = new BeforeUniverseBuildingAccessImpl(featureHandler, loader, debug, hMetaAccess);
609609
featureHandler.forEachFeature(feature -> feature.beforeUniverseBuilding(beforeUniverseBuildingConfig));
@@ -1126,6 +1126,21 @@ public static void initializeBigBang(Inflation bb, OptionValues options, Feature
11261126
bb.getMetaAccess().lookupJavaType(JavaKind.Void.toJavaClass()).registerAsReachable("root class");
11271127
bb.getMetaAccess().lookupJavaType(com.oracle.svm.core.util.Counter.class).registerAsReachable("root class");
11281128
bb.getMetaAccess().lookupJavaType(com.oracle.svm.core.allocationprofile.AllocationCounter.class).registerAsReachable("root class");
1129+
/*
1130+
* SubstrateAllocationProfilingData is not actually present in the image since it is
1131+
* only allocated at build time, is passed to snippets as a @ConstantParameter, and it
1132+
* only contains final fields that are constant-folded. However, since the profiling
1133+
* object is only allocated during lowering it is processed by the shadow heap after
1134+
* analysis, so its type needs to be already marked reachable at this point.
1135+
*/
1136+
bb.getMetaAccess().lookupJavaType(com.oracle.svm.core.graal.snippets.SubstrateAllocationSnippets.SubstrateAllocationProfilingData.class).registerAsReachable("root class");
1137+
/*
1138+
* Similarly to above, StackSlotIdentity only gets reachable during lowering, through
1139+
* build time allocated constants. It doesn't actually end up in the image heap since
1140+
* all its fields are final and are constant-folded, but the type becomes reachable,
1141+
* through the shadow heap processing, after analysis.
1142+
*/
1143+
bb.getMetaAccess().lookupJavaType(com.oracle.svm.core.graal.stackvalue.StackValueNode.StackSlotIdentity.class).registerAsReachable("root class");
11291144

11301145
NativeImageGenerator.registerGraphBuilderPlugins(featureHandler, null, aProviders, aMetaAccess, aUniverse, null, null, nativeLibraries, loader, ParsingReason.PointsToAnalysis,
11311146
bb.getAnnotationSubstitutionProcessor(), classInitializationPlugin, ConfigurationValues.getTarget(), supportsStubBasedPlugins);

substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/SVMHost.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,6 @@
7676
import org.graalvm.nativeimage.ImageSingletons;
7777
import org.graalvm.nativeimage.Platform;
7878
import org.graalvm.nativeimage.Platforms;
79-
import org.graalvm.nativeimage.c.function.RelocatedPointer;
8079

8180
import com.oracle.graal.pointsto.BigBang;
8281
import com.oracle.graal.pointsto.PointsToAnalysis;
@@ -134,6 +133,7 @@
134133
import com.oracle.svm.hosted.meta.HostedField;
135134
import com.oracle.svm.hosted.meta.HostedType;
136135
import com.oracle.svm.hosted.meta.HostedUniverse;
136+
import com.oracle.svm.hosted.meta.RelocatableConstant;
137137
import com.oracle.svm.hosted.phases.AnalysisGraphBuilderPhase;
138138
import com.oracle.svm.hosted.phases.ImplicitAssertionsPhase;
139139
import com.oracle.svm.hosted.phases.InlineBeforeAnalysisGraphDecoderImpl;
@@ -272,7 +272,7 @@ public String getImageName() {
272272

273273
@Override
274274
public boolean isRelocatedPointer(UniverseMetaAccess metaAccess, JavaConstant constant) {
275-
return metaAccess.isInstanceOf(constant, RelocatedPointer.class);
275+
return constant instanceof RelocatableConstant;
276276
}
277277

278278
@Override

substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/ameta/AnalysisConstantReflectionProvider.java

Lines changed: 33 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@
4646
import com.oracle.graal.pointsto.util.AnalysisError;
4747
import com.oracle.svm.core.RuntimeAssertionsSupport;
4848
import com.oracle.svm.core.annotate.InjectAccessors;
49+
import com.oracle.svm.core.annotate.RecomputeFieldValue;
4950
import com.oracle.svm.core.graal.meta.SharedConstantReflectionProvider;
5051
import com.oracle.svm.core.hub.DynamicHub;
5152
import com.oracle.svm.core.meta.ObjectConstantEquality;
@@ -54,20 +55,25 @@
5455
import com.oracle.svm.hosted.SVMHost;
5556
import com.oracle.svm.hosted.classinitialization.ClassInitializationSupport;
5657
import com.oracle.svm.hosted.classinitialization.SimulateClassInitializerSupport;
58+
import com.oracle.svm.hosted.meta.HostedField;
59+
import com.oracle.svm.hosted.meta.HostedLookupSnippetReflectionProvider;
5760
import com.oracle.svm.hosted.meta.HostedMetaAccess;
61+
import com.oracle.svm.hosted.meta.RelocatableConstant;
5862

5963
import jdk.vm.ci.meta.Constant;
6064
import jdk.vm.ci.meta.JavaConstant;
6165
import jdk.vm.ci.meta.JavaKind;
6266
import jdk.vm.ci.meta.MemoryAccessProvider;
6367
import jdk.vm.ci.meta.MethodHandleAccessProvider;
68+
import jdk.vm.ci.meta.PrimitiveConstant;
6469
import jdk.vm.ci.meta.ResolvedJavaField;
6570
import jdk.vm.ci.meta.ResolvedJavaType;
6671

6772
@Platforms(Platform.HOSTED_ONLY.class)
6873
public class AnalysisConstantReflectionProvider extends SharedConstantReflectionProvider {
6974
private final AnalysisUniverse universe;
7075
private final UniverseMetaAccess metaAccess;
76+
private HostedMetaAccess hMetaAccess;
7177
private final ClassInitializationSupport classInitializationSupport;
7278
private final AnalysisMethodHandleAccessProvider methodHandleAccess;
7379
private SimulateClassInitializerSupport simulateClassInitializerSupport;
@@ -79,6 +85,10 @@ public AnalysisConstantReflectionProvider(AnalysisUniverse universe, UniverseMet
7985
this.methodHandleAccess = new AnalysisMethodHandleAccessProvider(universe);
8086
}
8187

88+
public void setHostedMetaAccess(HostedMetaAccess hMetaAccess) {
89+
this.hMetaAccess = hMetaAccess;
90+
}
91+
8292
@Override
8393
public Boolean constantEquals(Constant x, Constant y) {
8494
if (x == y) {
@@ -212,7 +222,7 @@ public JavaConstant readValue(UniverseMetaAccess suppliedMetaAccess, AnalysisFie
212222
}
213223

214224
/** Read the field value and wrap it in a value supplier without performing any replacements. */
215-
public ValueSupplier<JavaConstant> readHostedFieldValue(AnalysisField field, HostedMetaAccess hMetaAccess, JavaConstant receiver, boolean returnSimulatedValues) {
225+
public ValueSupplier<JavaConstant> readHostedFieldValue(AnalysisField field, JavaConstant receiver, boolean returnSimulatedValues) {
216226
if (returnSimulatedValues) {
217227
var simulatedValue = readSimulatedValue(field);
218228
if (simulatedValue != null) {
@@ -233,7 +243,17 @@ public ValueSupplier<JavaConstant> readHostedFieldValue(AnalysisField field, Hos
233243
* during analysis or in a later phase. Attempts to materialize the value before it becomes
234244
* available will result in an error.
235245
*/
236-
return ValueSupplier.lazyValue(() -> doReadValue(field, receiver, hMetaAccess), () -> ReadableJavaField.isValueAvailable(field));
246+
return ValueSupplier.lazyValue(() -> doReadValue(field, receiver), () -> ReadableJavaField.isValueAvailable(field));
247+
}
248+
249+
/**
250+
* The {@link HostedMetaAccess} is used to access the {@link HostedField} in the re-computation
251+
* of {@link RecomputeFieldValue.Kind#AtomicFieldUpdaterOffset} and
252+
* {@link RecomputeFieldValue.Kind#TranslateFieldOffset} annotated fields .
253+
*/
254+
private JavaConstant doReadValue(AnalysisField field, JavaConstant receiver) {
255+
Objects.requireNonNull(hMetaAccess);
256+
return doReadValue(field, receiver, hMetaAccess);
237257
}
238258

239259
private JavaConstant doReadValue(AnalysisField field, JavaConstant receiver, UniverseMetaAccess access) {
@@ -265,7 +285,7 @@ public JavaConstant interceptValue(UniverseMetaAccess suppliedMetaAccess, Analys
265285
result = filterInjectedAccessor(field, result);
266286
result = replaceObject(result);
267287
result = interceptAssertionStatus(field, result);
268-
result = interceptWordType(suppliedMetaAccess, field, result);
288+
result = interceptWordField(suppliedMetaAccess, field, result);
269289
}
270290
return result;
271291
}
@@ -321,23 +341,17 @@ private static JavaConstant interceptAssertionStatus(AnalysisField field, JavaCo
321341
}
322342

323343
/**
324-
* Intercept {@link Word} types. They are boxed objects in the hosted world, but primitive
325-
* values in the runtime world.
344+
* Intercept {@link Word} fields. {@link Word} values are boxed objects in the hosted world, but
345+
* primitive values in the runtime world, so the default value of {@link Word} fields is 0.
346+
*
347+
* {@link HostedLookupSnippetReflectionProvider} replaces relocatable pointers with
348+
* {@link RelocatableConstant} and regular {@link WordBase} values with
349+
* {@link PrimitiveConstant}. No other {@link WordBase} values can be reachable at this point.
326350
*/
327-
private JavaConstant interceptWordType(UniverseMetaAccess suppliedMetaAccess, AnalysisField field, JavaConstant value) {
351+
private JavaConstant interceptWordField(UniverseMetaAccess suppliedMetaAccess, AnalysisField field, JavaConstant value) {
328352
if (value.getJavaKind() == JavaKind.Object) {
329-
if (universe.hostVM().isRelocatedPointer(suppliedMetaAccess, value)) {
330-
/*
331-
* Such pointers are subject to relocation therefore we don't know their values yet.
332-
* Therefore there should not be a relocated pointer constant in a function which is
333-
* compiled. RelocatedPointers are only allowed in non-constant fields. The caller
334-
* of readValue is responsible of handling the returned value correctly.
335-
*/
336-
return value;
337-
} else if (suppliedMetaAccess.isInstanceOf(value, WordBase.class)) {
338-
Object originalObject = universe.getSnippetReflection().asObject(Object.class, value);
339-
return JavaConstant.forIntegerKind(universe.getWordKind(), ((WordBase) originalObject).rawValue());
340-
} else if (value.isNull() && field.getType().isWordType()) {
353+
VMError.guarantee(value instanceof RelocatableConstant || !suppliedMetaAccess.isInstanceOf(value, WordBase.class));
354+
if (value.isNull() && field.getType().isWordType()) {
341355
return JavaConstant.forIntegerKind(universe.getWordKind(), 0);
342356
}
343357
}
@@ -364,7 +378,7 @@ public AnalysisType asJavaType(Constant constant) {
364378

365379
@Override
366380
public JavaConstant asJavaClass(ResolvedJavaType type) {
367-
return SubstrateObjectConstant.forObject(getHostVM().dynamicHub(type));
381+
return universe.getHeapScanner().createImageHeapConstant(super.forObject(getHostVM().dynamicHub(type)), ObjectScanner.OtherReason.UNKNOWN);
368382
}
369383

370384
@Override

substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/analysis/DynamicHubInitializer.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -181,7 +181,7 @@ private Enum<?>[] retrieveEnumConstantArray(AnalysisType type, Class<?> javaClas
181181
*/
182182
enumConstants = (Enum<?>[]) javaClass.getEnumConstants();
183183
} else {
184-
enumConstants = metaAccess.getUniverse().getSnippetReflection().asObject(Enum[].class, constantReflection.readFieldValue(found, null));
184+
enumConstants = bb.getSnippetReflectionProvider().asObject(Enum[].class, constantReflection.readFieldValue(found, null));
185185
assert enumConstants != null;
186186
}
187187
return enumConstants;

0 commit comments

Comments
 (0)