Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -343,11 +343,7 @@ public void forScannedConstant(JavaConstant value, ScanReason reason) {
}

private void ensureTypeScanned(JavaConstant typeConstant, AnalysisType type, ScanReason reason) {
if (typeConstant instanceof ImageHeapConstant imageHeapConstant) {
ensureTypeScanned(null, imageHeapConstant.getHostedObject(), type, reason);
} else {
ensureTypeScanned(null, typeConstant, type, reason);
}
ensureTypeScanned(null, typeConstant, type, reason);
}

@SuppressWarnings({"unchecked", "rawtypes"})
Expand All @@ -361,14 +357,13 @@ private void ensureTypeScanned(JavaConstant value, JavaConstant typeConstant, An
onNoTaskForClassConstant(type, reason);
scanner.toImageHeapObject(typeConstant, reason);
heapPatched = true;
} else if (task instanceof ImageHeapConstant) {
JavaConstant snapshot = ((ImageHeapConstant) task).getHostedObject();
verifyTypeConstant(snapshot, typeConstant, reason);
} else if (task instanceof ImageHeapConstant snapshot) {
verifyTypeConstant(maybeUnwrapSnapshot(snapshot, typeConstant instanceof ImageHeapConstant), typeConstant, reason);
} else {
assert task instanceof AnalysisFuture;
AnalysisFuture<ImageHeapConstant> future = ((AnalysisFuture<ImageHeapConstant>) task);
if (future.isDone()) {
JavaConstant snapshot = future.guardedGet().getHostedObject();
JavaConstant snapshot = maybeUnwrapSnapshot(future.guardedGet(), typeConstant instanceof ImageHeapConstant);
verifyTypeConstant(snapshot, typeConstant, reason);
} else {
onTaskForClassConstantNotDone(value, type, reason);
Expand All @@ -379,7 +374,7 @@ private void ensureTypeScanned(JavaConstant value, JavaConstant typeConstant, An

private void verifyTypeConstant(JavaConstant snapshot, JavaConstant typeConstant, ScanReason reason) {
if (!Objects.equals(snapshot, typeConstant)) {
throw error(reason, "Value mismatch for class constant snapshot: %s %n new value: %s %n", snapshot, typeConstant);
throw error(reason, "Value mismatch for class constant%n snapshot: %s %n new value: %s %n", snapshot, typeConstant);
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,8 +35,8 @@
import org.graalvm.collections.MapCursor;
import org.graalvm.compiler.api.replacements.SnippetReflectionProvider;
import org.graalvm.compiler.core.common.SuppressFBWarnings;
import org.graalvm.compiler.core.common.type.TypedConstant;
import org.graalvm.compiler.debug.GraalError;
import org.graalvm.word.WordBase;

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

private boolean isNonNullObjectConstant(JavaConstant constant) {
return constant.getJavaKind() == JavaKind.Object && constant.isNonNull() && !isWordType(constant);
}

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

private boolean notifyAnalysis(JavaConstant array, AnalysisType arrayType, JavaConstant elementValue, int elementIndex, ScanReason reason) {
boolean analysisModified;
if (elementValue.isNull()) {
analysisModified = scanningObserver.forNullArrayElement(array, arrayType, elementIndex, reason);
} else {
if (isWordType(elementValue)) {
if (universe.hostVM().isRelocatedPointer(metaAccess, elementValue)) {
return false;
}
AnalysisType elementType = metaAccess.lookupJavaType(elementValue);
Expand Down Expand Up @@ -524,10 +515,6 @@ protected ValueSupplier<JavaConstant> readHostedFieldValue(AnalysisField field,
return ValueSupplier.eagerValue(value);
}

public JavaConstant readFieldValue(AnalysisField field, JavaConstant receiver) {
return constantReflection.readFieldValue(field, receiver);
}

public void rescanRoot(Field reflectionField) {
maybeRunInExecutor(unused -> {
AnalysisType type = metaAccess.lookupJavaType(reflectionField.getDeclaringClass());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,6 @@
import com.oracle.graal.pointsto.flow.MethodFlowsGraph;
import com.oracle.graal.pointsto.flow.MethodTypeFlow;
import com.oracle.graal.pointsto.flow.TypeFlow;
import com.oracle.graal.pointsto.heap.ImageHeapConstant;
import com.oracle.graal.pointsto.infrastructure.Universe;
import com.oracle.graal.pointsto.meta.AnalysisField;
import com.oracle.graal.pointsto.meta.AnalysisMethod;
Expand Down Expand Up @@ -728,15 +727,6 @@ private Object strengthenStampFromTypeFlow(ValueNode node, TypeFlow<?> nodeFlow,

if (hasUsages && allowConstantFolding && !nodeTypeState.canBeNull()) {
JavaConstant constantValue = nodeTypeState.asConstant();
if (constantValue instanceof ImageHeapConstant) {
/*
* GR-42996: until the AOT compilation can properly constant fold also
* ImageHeapConstant, we unwrap the ImageHeapConstant to the hosted object. This
* also means we do not constant fold yet when the constant does not wrap a
* hosted object.
*/
constantValue = ((ImageHeapConstant) constantValue).getHostedObject();
}
if (constantValue != null) {
return constantValue;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -603,7 +603,7 @@ protected void doRun(Map<Method, CEntryPointData> entryPoints,

hUniverse = new HostedUniverse(bb);
hMetaAccess = new HostedMetaAccess(hUniverse, bb.getMetaAccess());
((SVMImageHeapScanner) aUniverse.getHeapScanner()).setHostedMetaAccess(hMetaAccess);
((AnalysisConstantReflectionProvider) bb.getConstantReflectionProvider()).setHostedMetaAccess(hMetaAccess);

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

NativeImageGenerator.registerGraphBuilderPlugins(featureHandler, null, aProviders, aMetaAccess, aUniverse, null, null, nativeLibraries, loader, ParsingReason.PointsToAnalysis,
bb.getAnnotationSubstitutionProcessor(), classInitializationPlugin, ConfigurationValues.getTarget(), supportsStubBasedPlugins);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,6 @@
import org.graalvm.nativeimage.ImageSingletons;
import org.graalvm.nativeimage.Platform;
import org.graalvm.nativeimage.Platforms;
import org.graalvm.nativeimage.c.function.RelocatedPointer;

import com.oracle.graal.pointsto.BigBang;
import com.oracle.graal.pointsto.PointsToAnalysis;
Expand Down Expand Up @@ -134,6 +133,7 @@
import com.oracle.svm.hosted.meta.HostedField;
import com.oracle.svm.hosted.meta.HostedType;
import com.oracle.svm.hosted.meta.HostedUniverse;
import com.oracle.svm.hosted.meta.RelocatableConstant;
import com.oracle.svm.hosted.phases.AnalysisGraphBuilderPhase;
import com.oracle.svm.hosted.phases.ImplicitAssertionsPhase;
import com.oracle.svm.hosted.phases.InlineBeforeAnalysisGraphDecoderImpl;
Expand Down Expand Up @@ -272,7 +272,7 @@ public String getImageName() {

@Override
public boolean isRelocatedPointer(UniverseMetaAccess metaAccess, JavaConstant constant) {
return metaAccess.isInstanceOf(constant, RelocatedPointer.class);
return constant instanceof RelocatableConstant;
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@
import com.oracle.graal.pointsto.util.AnalysisError;
import com.oracle.svm.core.RuntimeAssertionsSupport;
import com.oracle.svm.core.annotate.InjectAccessors;
import com.oracle.svm.core.annotate.RecomputeFieldValue;
import com.oracle.svm.core.graal.meta.SharedConstantReflectionProvider;
import com.oracle.svm.core.hub.DynamicHub;
import com.oracle.svm.core.meta.ObjectConstantEquality;
Expand All @@ -54,20 +55,25 @@
import com.oracle.svm.hosted.SVMHost;
import com.oracle.svm.hosted.classinitialization.ClassInitializationSupport;
import com.oracle.svm.hosted.classinitialization.SimulateClassInitializerSupport;
import com.oracle.svm.hosted.meta.HostedField;
import com.oracle.svm.hosted.meta.HostedLookupSnippetReflectionProvider;
import com.oracle.svm.hosted.meta.HostedMetaAccess;
import com.oracle.svm.hosted.meta.RelocatableConstant;

import jdk.vm.ci.meta.Constant;
import jdk.vm.ci.meta.JavaConstant;
import jdk.vm.ci.meta.JavaKind;
import jdk.vm.ci.meta.MemoryAccessProvider;
import jdk.vm.ci.meta.MethodHandleAccessProvider;
import jdk.vm.ci.meta.PrimitiveConstant;
import jdk.vm.ci.meta.ResolvedJavaField;
import jdk.vm.ci.meta.ResolvedJavaType;

@Platforms(Platform.HOSTED_ONLY.class)
public class AnalysisConstantReflectionProvider extends SharedConstantReflectionProvider {
private final AnalysisUniverse universe;
private final UniverseMetaAccess metaAccess;
private HostedMetaAccess hMetaAccess;
private final ClassInitializationSupport classInitializationSupport;
private final AnalysisMethodHandleAccessProvider methodHandleAccess;
private SimulateClassInitializerSupport simulateClassInitializerSupport;
Expand All @@ -79,6 +85,10 @@ public AnalysisConstantReflectionProvider(AnalysisUniverse universe, UniverseMet
this.methodHandleAccess = new AnalysisMethodHandleAccessProvider(universe);
}

public void setHostedMetaAccess(HostedMetaAccess hMetaAccess) {
this.hMetaAccess = hMetaAccess;
}

@Override
public Boolean constantEquals(Constant x, Constant y) {
if (x == y) {
Expand Down Expand Up @@ -212,7 +222,7 @@ public JavaConstant readValue(UniverseMetaAccess suppliedMetaAccess, AnalysisFie
}

/** Read the field value and wrap it in a value supplier without performing any replacements. */
public ValueSupplier<JavaConstant> readHostedFieldValue(AnalysisField field, HostedMetaAccess hMetaAccess, JavaConstant receiver, boolean returnSimulatedValues) {
public ValueSupplier<JavaConstant> readHostedFieldValue(AnalysisField field, JavaConstant receiver, boolean returnSimulatedValues) {
if (returnSimulatedValues) {
var simulatedValue = readSimulatedValue(field);
if (simulatedValue != null) {
Expand All @@ -233,7 +243,17 @@ public ValueSupplier<JavaConstant> readHostedFieldValue(AnalysisField field, Hos
* during analysis or in a later phase. Attempts to materialize the value before it becomes
* available will result in an error.
*/
return ValueSupplier.lazyValue(() -> doReadValue(field, receiver, hMetaAccess), () -> ReadableJavaField.isValueAvailable(field));
return ValueSupplier.lazyValue(() -> doReadValue(field, receiver), () -> ReadableJavaField.isValueAvailable(field));
}

/**
* The {@link HostedMetaAccess} is used to access the {@link HostedField} in the re-computation
* of {@link RecomputeFieldValue.Kind#AtomicFieldUpdaterOffset} and
* {@link RecomputeFieldValue.Kind#TranslateFieldOffset} annotated fields .
*/
private JavaConstant doReadValue(AnalysisField field, JavaConstant receiver) {
Objects.requireNonNull(hMetaAccess);
return doReadValue(field, receiver, hMetaAccess);
}

private JavaConstant doReadValue(AnalysisField field, JavaConstant receiver, UniverseMetaAccess access) {
Expand Down Expand Up @@ -265,7 +285,7 @@ public JavaConstant interceptValue(UniverseMetaAccess suppliedMetaAccess, Analys
result = filterInjectedAccessor(field, result);
result = replaceObject(result);
result = interceptAssertionStatus(field, result);
result = interceptWordType(suppliedMetaAccess, field, result);
result = interceptWordField(suppliedMetaAccess, field, result);
}
return result;
}
Expand Down Expand Up @@ -321,23 +341,17 @@ private static JavaConstant interceptAssertionStatus(AnalysisField field, JavaCo
}

/**
* Intercept {@link Word} types. They are boxed objects in the hosted world, but primitive
* values in the runtime world.
* Intercept {@link Word} fields. {@link Word} values are boxed objects in the hosted world, but
* primitive values in the runtime world, so the default value of {@link Word} fields is 0.
*
* {@link HostedLookupSnippetReflectionProvider} replaces relocatable pointers with
* {@link RelocatableConstant} and regular {@link WordBase} values with
* {@link PrimitiveConstant}. No other {@link WordBase} values can be reachable at this point.
*/
private JavaConstant interceptWordType(UniverseMetaAccess suppliedMetaAccess, AnalysisField field, JavaConstant value) {
private JavaConstant interceptWordField(UniverseMetaAccess suppliedMetaAccess, AnalysisField field, JavaConstant value) {
if (value.getJavaKind() == JavaKind.Object) {
if (universe.hostVM().isRelocatedPointer(suppliedMetaAccess, value)) {
/*
* Such pointers are subject to relocation therefore we don't know their values yet.
* Therefore there should not be a relocated pointer constant in a function which is
* compiled. RelocatedPointers are only allowed in non-constant fields. The caller
* of readValue is responsible of handling the returned value correctly.
*/
return value;
} else if (suppliedMetaAccess.isInstanceOf(value, WordBase.class)) {
Object originalObject = universe.getSnippetReflection().asObject(Object.class, value);
return JavaConstant.forIntegerKind(universe.getWordKind(), ((WordBase) originalObject).rawValue());
} else if (value.isNull() && field.getType().isWordType()) {
VMError.guarantee(value instanceof RelocatableConstant || !suppliedMetaAccess.isInstanceOf(value, WordBase.class));
if (value.isNull() && field.getType().isWordType()) {
return JavaConstant.forIntegerKind(universe.getWordKind(), 0);
}
}
Expand All @@ -364,7 +378,7 @@ public AnalysisType asJavaType(Constant constant) {

@Override
public JavaConstant asJavaClass(ResolvedJavaType type) {
return SubstrateObjectConstant.forObject(getHostVM().dynamicHub(type));
return universe.getHeapScanner().createImageHeapConstant(super.forObject(getHostVM().dynamicHub(type)), ObjectScanner.OtherReason.UNKNOWN);
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -181,7 +181,7 @@ private Enum<?>[] retrieveEnumConstantArray(AnalysisType type, Class<?> javaClas
*/
enumConstants = (Enum<?>[]) javaClass.getEnumConstants();
} else {
enumConstants = metaAccess.getUniverse().getSnippetReflection().asObject(Enum[].class, constantReflection.readFieldValue(found, null));
enumConstants = bb.getSnippetReflectionProvider().asObject(Enum[].class, constantReflection.readFieldValue(found, null));
assert enumConstants != null;
}
return enumConstants;
Expand Down
Loading