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 @@ -64,6 +64,15 @@ public interface SnippetReflectionProvider {
*/
<T> T asObject(Class<T> type, JavaConstant constant);

/**
* Get the wrapped constant object, if any. This is a temporary workaround required in Native
* Image to expand the use of ImageHeapConstant. It will be removed when all hosted phases
* support ImageHeapConstant by default and no unwrapping is necessary. (GR-48682)
*/
default JavaConstant unwrapConstant(JavaConstant constant) {
return constant;
}

/**
* Creates a boxed constant for the given kind from an Object. The object needs to be of the
* Java boxed type corresponding to the kind.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ public StandaloneConstantReflectionProvider(AnalysisUniverse universe, HotSpotJV
@Override
public final JavaConstant readFieldValue(ResolvedJavaField field, JavaConstant receiver) {
ResolvedJavaField wrappedField = ((AnalysisField) field).getWrapped();
JavaConstant ret = universe.lookup(super.readFieldValue(wrappedField, universe.toHosted(receiver)));
JavaConstant ret = universe.fromHosted(super.readFieldValue(wrappedField, universe.toHosted(receiver)));
if (ret == null) {
ret = wrappedField.getConstantValue();
if (ret == null) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -245,10 +245,10 @@ protected final void scanArray(JavaConstant array, ScanReason prevReason) {
scanningObserver.forNullArrayElement(array, arrayType, idx, reason);
} else {
try {
JavaConstant element = bb.getSnippetReflectionProvider().forObject(bb.getUniverse().replaceObject(e));
JavaConstant element = bb.getUniverse().getSnippetReflection().forObject(bb.getUniverse().replaceObject(e));
scanArrayElement(array, arrayType, reason, idx, element);
} catch (UnsupportedFeatureException ex) { /* Object replacement can throw. */
unsupportedFeatureDuringConstantScan(bb, bb.getSnippetReflectionProvider().forObject(e), ex, reason);
unsupportedFeatureDuringConstantScan(bb, bb.getUniverse().getSnippetReflection().forObject(e), ex, reason);
}
}
}
Expand Down Expand Up @@ -497,6 +497,7 @@ public String toString(BigBang bb) {
}

public static class OtherReason extends ScanReason {
public static final ScanReason UNKNOWN = new OtherReason("manually created constant");
public static final ScanReason RESCAN = new OtherReason("manually triggered rescan");
public static final ScanReason HUB = new OtherReason("scanning a class constant");

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
import static com.oracle.graal.pointsto.ObjectScanner.ScanReason;

import java.util.Objects;
import java.util.concurrent.ForkJoinPool;
import java.util.function.Consumer;

import org.graalvm.compiler.options.Option;
Expand Down Expand Up @@ -73,6 +74,12 @@ public HeapSnapshotVerifier(BigBang bb, ImageHeap imageHeap, ImageHeapScanner sc
verbosity = Options.HeapVerifierVerbosity.getValue(bb.getOptions());
}

public boolean checkHeapSnapshot(UniverseMetaAccess metaAccess, ForkJoinPool threadPool, String stage) {
CompletionExecutor executor = new CompletionExecutor(bb, threadPool, bb.getHeartbeatCallback());
executor.init();
return checkHeapSnapshot(metaAccess, executor, stage, false);
}

/**
* Heap verification does a complete scan from roots (static fields and embedded constant) and
* compares the object graph against the shadow heap. If any new reachable objects or primitive
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,6 @@
import com.oracle.graal.pointsto.api.HostVM;
import com.oracle.graal.pointsto.constraints.UnsupportedFeatureException;
import com.oracle.graal.pointsto.heap.value.ValueSupplier;
import com.oracle.graal.pointsto.infrastructure.UniverseMetaAccess;
import com.oracle.graal.pointsto.meta.AnalysisField;
import com.oracle.graal.pointsto.meta.AnalysisMetaAccess;
import com.oracle.graal.pointsto.meta.AnalysisType;
Expand Down Expand Up @@ -196,9 +195,6 @@ protected ImageHeapConstant getOrCreateImageHeapConstant(JavaConstant javaConsta
ScanReason nonNullReason = Objects.requireNonNull(reason);
Object existingTask = imageHeap.getSnapshot(javaConstant);
if (existingTask == null) {
if (universe.sealed()) {
throw AnalysisError.shouldNotReachHere("Universe is sealed. New constant reachable: " + javaConstant.toValueString());
}
AnalysisFuture<ImageHeapConstant> newTask = new AnalysisFuture<>(() -> {
ImageHeapConstant imageHeapConstant = createImageHeapObject(javaConstant, nonNullReason);
/* When the image heap object is created replace the future in the map. */
Expand Down Expand Up @@ -434,19 +430,26 @@ private void notifyAnalysis(ImageHeapArray array, AnalysisType arrayType, int el
}

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

public static boolean isWordType(JavaConstant rawElementValue, UniverseMetaAccess metaAccess) {
return metaAccess.isInstanceOf(rawElementValue, WordBase.class);
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;
}

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, metaAccess)) {
if (isWordType(elementValue)) {
return false;
}
AnalysisType elementType = metaAccess.lookupJavaType(elementValue);
Expand Down Expand Up @@ -517,23 +520,15 @@ protected String formatReason(String message, ScanReason reason) {

protected ValueSupplier<JavaConstant> readHostedFieldValue(AnalysisField field, JavaConstant receiver) {
// Wrap the hosted constant into a substrate constant
JavaConstant value = universe.lookup(hostedConstantReflection.readFieldValue(field.wrapped, receiver));
JavaConstant value = universe.fromHosted(hostedConstantReflection.readFieldValue(field.wrapped, receiver));
return ValueSupplier.eagerValue(value);
}

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

protected boolean skipScanning() {
return false;
}

public void rescanRoot(Field reflectionField) {
if (skipScanning()) {
return;
}

maybeRunInExecutor(unused -> {
AnalysisType type = metaAccess.lookupJavaType(reflectionField.getDeclaringClass());
if (type.isReachable()) {
Expand All @@ -549,9 +544,6 @@ public void rescanRoot(Field reflectionField) {
}

public void rescanField(Object receiver, Field reflectionField) {
if (skipScanning()) {
return;
}
maybeRunInExecutor(unused -> {
AnalysisType type = metaAccess.lookupJavaType(reflectionField.getDeclaringClass());
if (type.isReachable()) {
Expand Down Expand Up @@ -621,9 +613,6 @@ public void rescanObject(Object object) {
* Add the object to the image heap.
*/
public void rescanObject(Object object, ScanReason reason) {
if (skipScanning()) {
return;
}
if (object == null) {
return;
}
Expand Down Expand Up @@ -681,8 +670,8 @@ protected Object asObject(JavaConstant constant) {
return snippetReflection.asObject(Object.class, constant);
}

public JavaConstant asConstant(Object object) {
return snippetReflection.forObject(object);
private JavaConstant asConstant(Object object) {
return universe.getSnippetReflection().forObject(object);
}

public void cleanupAfterAnalysis() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,9 +24,12 @@
*/
package com.oracle.graal.pointsto.infrastructure;

import com.oracle.graal.pointsto.api.HostVM;
import org.graalvm.compiler.api.replacements.SnippetReflectionProvider;

import com.oracle.graal.pointsto.api.HostVM;
import com.oracle.graal.pointsto.heap.ImageHeap;
import com.oracle.graal.pointsto.heap.ImageHeapConstant;

import jdk.vm.ci.meta.ConstantPool;
import jdk.vm.ci.meta.JavaConstant;
import jdk.vm.ci.meta.JavaField;
Expand Down Expand Up @@ -59,6 +62,11 @@ public interface Universe {

WrappedConstantPool lookup(ConstantPool constantPool, ResolvedJavaType defaultAccessingClass);

/**
* Lookup a constant originating from the underlying VM, via JVMCI, in the analysis universe.
* This method will unpack hosted object constants and repack the raw constant object into an
* {@link ImageHeapConstant} cached in the {@link ImageHeap}.
*/
JavaConstant lookup(JavaConstant constant);

ResolvedJavaMethod resolveSubstitution(ResolvedJavaMethod method);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@

import org.graalvm.compiler.core.common.BootstrapMethodIntrospection;
import org.graalvm.compiler.debug.GraalError;
import org.graalvm.compiler.serviceprovider.GraalServices;

import com.oracle.graal.pointsto.constraints.UnresolvedElementException;
import com.oracle.svm.util.ReflectionUtil;
Expand All @@ -44,7 +45,6 @@
import jdk.vm.ci.meta.JavaType;
import jdk.vm.ci.meta.ResolvedJavaMethod;
import jdk.vm.ci.meta.ResolvedJavaType;
import org.graalvm.compiler.serviceprovider.GraalServices;

public class WrappedConstantPool implements ConstantPool, ConstantPoolPatch {

Expand All @@ -63,6 +63,10 @@ public int length() {
return wrapped.length();
}

private JavaConstant lookupConstant(JavaConstant constant) {
return universe.lookup(constant);
}

/**
* The method jdk.vm.ci.meta.ConstantPool#lookupBootstrapMethodInvocation(int cpi, int opcode)
* was introduced in JVMCI 22.1.
Expand Down Expand Up @@ -155,7 +159,7 @@ public WrappedSignature lookupSignature(int cpi) {

@Override
public JavaConstant lookupAppendix(int cpi, int opcode) {
return universe.lookup(wrapped.lookupAppendix(cpi, opcode));
return lookupConstant(wrapped.lookupAppendix(cpi, opcode));
}

@Override
Expand All @@ -179,7 +183,7 @@ public Object lookupConstant(int cpi, boolean resolve) {
return con;
}
} else if (con instanceof JavaConstant) {
return universe.lookup((JavaConstant) con);
return lookupConstant((JavaConstant) con);
} else if (con == null && resolve == false) {
return null;
} else {
Expand Down Expand Up @@ -251,7 +255,7 @@ public String getName() {
public JavaConstant getType() {
if (bsmGetType != null) {
try {
return universe.lookup((JavaConstant) bsmGetType.invoke(wrapped));
return lookupConstant((JavaConstant) bsmGetType.invoke(wrapped));
} catch (Throwable t) {
throw GraalError.shouldNotReachHere(t); // ExcludeFromJacocoGeneratedReport
}
Expand All @@ -264,7 +268,7 @@ public List<JavaConstant> getStaticArguments() {
if (bsmGetStaticArguments != null) {
try {
List<?> original = (List<?>) bsmGetStaticArguments.invoke(wrapped);
return original.stream().map(e -> universe.lookup((JavaConstant) e)).collect(Collectors.toList());
return original.stream().map(e -> lookupConstant((JavaConstant) e)).collect(Collectors.toList());
} catch (Throwable t) {
throw GraalError.shouldNotReachHere(t); // ExcludeFromJacocoGeneratedReport
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -186,9 +186,10 @@ public enum UsageKind {
private final AnalysisFuture<Void> initializeMetaDataTask;

/**
* Additional information that is only available for types that are marked as reachable.
* Additional information that is only available for types that are marked as reachable. It is
* preserved after analysis.
*/
private AnalysisFuture<TypeData> typeData;
private final AnalysisFuture<TypeData> typeData;

/**
* Contains reachability handlers that are notified when any of the subtypes are marked as
Expand Down Expand Up @@ -347,7 +348,6 @@ public void cleanupAfterAnalysis() {
constantObjectsCache = null;
uniqueConstant = null;
unsafeAccessedFields = null;
typeData = null;
scheduledTypeReachableNotifications = null;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@

import com.oracle.graal.pointsto.AnalysisPolicy;
import com.oracle.graal.pointsto.BigBang;
import com.oracle.graal.pointsto.ObjectScanner;
import com.oracle.graal.pointsto.api.HostVM;
import com.oracle.graal.pointsto.constraints.UnsupportedFeatureException;
import com.oracle.graal.pointsto.heap.HeapSnapshotVerifier;
Expand Down Expand Up @@ -496,6 +497,16 @@ public WrappedConstantPool lookup(ConstantPool constantPool, ResolvedJavaType de

@Override
public JavaConstant lookup(JavaConstant constant) {
if (constant == null || constant.isNull() || constant.getJavaKind().isPrimitive()) {
return constant;
}
return heapScanner.createImageHeapConstant(fromHosted(constant), ObjectScanner.OtherReason.UNKNOWN);
}

/**
* Convert a hosted HotSpotObjectConstant into a SubstrateObjectConstant.
*/
public JavaConstant fromHosted(JavaConstant constant) {
if (constant == null) {
return null;
} else if (constant.getJavaKind().isObject() && !constant.isNull()) {
Expand All @@ -516,6 +527,9 @@ public JavaConstant lookup(JavaConstant constant) {
}
}

/**
* Convert a hosted SubstrateObjectConstant into a HotSpotObjectConstant.
*/
public JavaConstant toHosted(JavaConstant constant) {
if (constant == null) {
return null;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,8 @@
public final class PointsToAnalysisMethod extends AnalysisMethod {

private MethodTypeFlow typeFlow;
/** The parsing context in which given method was parsed, preserved after analysis. */
private final Object parsingReason;

private Set<InvokeTypeFlow> invokedBy;
private Set<InvokeTypeFlow> implementationInvokedBy;
Expand All @@ -69,11 +71,13 @@ public final class PointsToAnalysisMethod extends AnalysisMethod {
public PointsToAnalysisMethod(AnalysisUniverse universe, ResolvedJavaMethod wrapped) {
super(universe, wrapped, MultiMethod.ORIGINAL_METHOD, null);
typeFlow = declaringClass.universe.analysisPolicy().createMethodTypeFlow(this);
parsingReason = typeFlow.getParsingReason();
}

private PointsToAnalysisMethod(AnalysisMethod original, MultiMethodKey multiMethodKey) {
super(original, multiMethodKey);
typeFlow = declaringClass.universe.analysisPolicy().createMethodTypeFlow(this);
parsingReason = typeFlow.getParsingReason();
}

@Override
Expand Down Expand Up @@ -149,7 +153,7 @@ public Iterable<? extends InvokeInfo> getInvokes() {

@Override
public Object getParsingReason() {
return typeFlow.getParsingReason();
return parsingReason;
}

public InvokeTypeFlow initAndGetContextInsensitiveInvoke(PointsToAnalysis bb, BytecodePosition originalLocation, boolean isSpecial, MultiMethodKey callerMultiMethodKey) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -693,7 +693,7 @@ public void visitBreakpointNode(BreakpointNode node) {

@Override
protected DebugInfoBuilder createDebugInfoBuilder(StructuredGraph graph, NodeValueMap nodeValueMap) {
return new SubstrateDebugInfoBuilder(graph, gen.getProviders().getMetaAccessExtensionProvider(), nodeValueMap);
return new SubstrateDebugInfoBuilder(graph, getProviders().getSnippetReflection(), gen.getProviders().getMetaAccessExtensionProvider(), nodeValueMap);
}

private boolean getDestroysCallerSavedRegisters(ResolvedJavaMethod targetMethod) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -828,7 +828,7 @@ public void visitBreakpointNode(BreakpointNode node) {

@Override
protected DebugInfoBuilder createDebugInfoBuilder(StructuredGraph graph, NodeValueMap nodeValueMap) {
return new SubstrateDebugInfoBuilder(graph, gen.getProviders().getMetaAccessExtensionProvider(), nodeValueMap);
return new SubstrateDebugInfoBuilder(graph, getProviders().getSnippetReflection(), gen.getProviders().getMetaAccessExtensionProvider(), nodeValueMap);
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,6 @@
import org.graalvm.compiler.core.common.memory.BarrierType;
import org.graalvm.compiler.core.common.memory.MemoryExtendKind;
import org.graalvm.compiler.core.common.memory.MemoryOrderMode;
import org.graalvm.compiler.core.common.spi.CodeGenProviders;
import org.graalvm.compiler.core.common.spi.ForeignCallLinkage;
import org.graalvm.compiler.core.common.spi.ForeignCallsProvider;
import org.graalvm.compiler.core.common.spi.LIRKindTool;
Expand Down Expand Up @@ -204,7 +203,7 @@ public BarrierSetLIRGeneratorTool getBarrierSet() {
}

@Override
public CodeGenProviders getProviders() {
public Providers getProviders() {
return providers;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -149,7 +149,7 @@ public class NodeLLVMBuilder implements NodeLIRBuilderTool, SubstrateNodeLIRBuil
protected NodeLLVMBuilder(StructuredGraph graph, LLVMGenerator gen) {
this.gen = gen;
this.builder = gen.getBuilder();
this.debugInfoBuilder = new SubstrateDebugInfoBuilder(graph, gen.getProviders().getMetaAccessExtensionProvider(), this);
this.debugInfoBuilder = new SubstrateDebugInfoBuilder(graph, gen.getProviders().getSnippetReflection(), gen.getProviders().getMetaAccessExtensionProvider(), this);
setCompilationResultMethod(gen.getCompilationResult(), graph);

for (HIRBlock block : graph.getLastSchedule().getCFG().getBlocks()) {
Expand Down
Loading