Skip to content

Commit

Permalink
[GR-58050] Add MetaAccessExtensionProvider.getStaticFieldForAccess.
Browse files Browse the repository at this point in the history
PullRequest: graal/18780
  • Loading branch information
gilles-duboscq committed Sep 16, 2024
2 parents dfab40d + f52d469 commit 562c03c
Show file tree
Hide file tree
Showing 11 changed files with 254 additions and 86 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,10 @@
*/
package jdk.graal.compiler.core.common.spi;

import jdk.vm.ci.meta.JavaConstant;
import jdk.vm.ci.meta.JavaKind;
import jdk.vm.ci.meta.JavaType;
import jdk.vm.ci.meta.ResolvedJavaField;
import jdk.vm.ci.meta.ResolvedJavaMethod;
import jdk.vm.ci.meta.ResolvedJavaType;

Expand Down Expand Up @@ -63,4 +65,15 @@ public interface MetaAccessExtensionProvider {
* given type.
*/
boolean canVirtualize(ResolvedJavaType instanceType);

/**
* Given an unsafe access, try to find the static field that is being accessed.
*
* @param base the base object used in the access.
* @param offset the offset used in the access.
* @param accessKind the kind of data being accessed.
* @return the static field being accessed or null if this is not a static field access or if it
* can't be determined.
*/
ResolvedJavaField getStaticFieldForAccess(JavaConstant base, long offset, JavaKind accessKind);
}
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,7 @@
import jdk.vm.ci.hotspot.HotSpotCodeCacheProvider;
import jdk.vm.ci.hotspot.HotSpotConstantReflectionProvider;
import jdk.vm.ci.hotspot.HotSpotJVMCIRuntime;
import jdk.vm.ci.meta.ConstantReflectionProvider;
import jdk.vm.ci.meta.MetaAccessProvider;
import jdk.vm.ci.meta.ResolvedJavaField;
import jdk.vm.ci.meta.ResolvedJavaType;
Expand All @@ -100,8 +101,8 @@ protected HotSpotPlatformConfigurationProvider createConfigInfoProvider(GraalHot
return new HotSpotPlatformConfigurationProvider(config, barrierSet);
}

protected HotSpotMetaAccessExtensionProvider createMetaAccessExtensionProvider() {
return new HotSpotMetaAccessExtensionProvider();
protected HotSpotMetaAccessExtensionProvider createMetaAccessExtensionProvider(MetaAccessProvider metaAccess, ConstantReflectionProvider constantReflection) {
return new HotSpotMetaAccessExtensionProvider(metaAccess, constantReflection);
}

protected HotSpotReplacementsImpl createReplacements(TargetDescription target, HotSpotProviders p, BytecodeProvider bytecodeProvider) {
Expand Down Expand Up @@ -168,7 +169,7 @@ public final HotSpotBackend createBackend(HotSpotGraalRuntimeProvider graalRunti
}
HotSpotMetaAccessExtensionProvider metaAccessExtensionProvider;
try (InitTimer rt = timer("create MetaAccessExtensionProvider")) {
metaAccessExtensionProvider = createMetaAccessExtensionProvider();
metaAccessExtensionProvider = createMetaAccessExtensionProvider(metaAccess, constantReflection);
}
HotSpotStampProvider stampProvider;
try (InitTimer rt = timer("create stamp provider")) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,13 +25,25 @@
package jdk.graal.compiler.hotspot.meta;

import jdk.graal.compiler.core.common.spi.MetaAccessExtensionProvider;

import jdk.vm.ci.hotspot.HotSpotObjectConstant;
import jdk.vm.ci.meta.ConstantReflectionProvider;
import jdk.vm.ci.meta.JavaConstant;
import jdk.vm.ci.meta.JavaKind;
import jdk.vm.ci.meta.JavaType;
import jdk.vm.ci.meta.MetaAccessProvider;
import jdk.vm.ci.meta.ResolvedJavaField;
import jdk.vm.ci.meta.ResolvedJavaMethod;
import jdk.vm.ci.meta.ResolvedJavaType;

public class HotSpotMetaAccessExtensionProvider implements MetaAccessExtensionProvider {
private final ConstantReflectionProvider constantReflection;
private final ResolvedJavaType jlClassType;

public HotSpotMetaAccessExtensionProvider(MetaAccessProvider metaAccess, ConstantReflectionProvider constantReflection) {
this.constantReflection = constantReflection;
this.jlClassType = metaAccess.lookupJavaType(Class.class);
}

@Override
public JavaKind getStorageKind(JavaType type) {
return type.getJavaKind();
Expand All @@ -56,4 +68,26 @@ public boolean isGuaranteedSafepoint(ResolvedJavaMethod method, boolean isDirect
public boolean canVirtualize(ResolvedJavaType instanceType) {
return true;
}

@Override
public ResolvedJavaField getStaticFieldForAccess(JavaConstant base, long offset, JavaKind accessKind) {
if (accessKind.getSlotCount() <= 0) {
throw new IllegalArgumentException("Unexpected access kind: " + accessKind);
}
if (!(base instanceof HotSpotObjectConstant objectConstant)) {
return null;
}
ResolvedJavaType type = constantReflection.asJavaType(base);
// check that it's indeed a j.l.Class when we get a result since constant reflection will
// also return a type if the constant wraps a ResolvedJavaType
if (type == null || !objectConstant.getType().equals(jlClassType)) {
return null;
}
for (ResolvedJavaField field : type.getStaticFields()) {
if (field.getOffset() == offset && accessKind == field.getJavaKind()) {
return field;
}
}
return null;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -27,11 +27,10 @@
import static jdk.graal.compiler.nodeinfo.NodeCycles.CYCLES_2;
import static jdk.graal.compiler.nodeinfo.NodeSize.SIZE_1;

import java.nio.ByteOrder;

import org.graalvm.word.LocationIdentity;

import jdk.graal.compiler.core.common.memory.MemoryOrderMode;
import jdk.graal.compiler.core.common.spi.MetaAccessExtensionProvider;
import jdk.graal.compiler.core.common.type.Stamp;
import jdk.graal.compiler.graph.Node;
import jdk.graal.compiler.graph.NodeClass;
Expand All @@ -46,7 +45,6 @@
import jdk.graal.compiler.nodes.spi.CanonicalizerTool;
import jdk.graal.compiler.nodes.spi.TrackedUnsafeAccess;
import jdk.graal.compiler.nodes.type.StampTool;
import jdk.vm.ci.meta.ConstantReflectionProvider;
import jdk.vm.ci.meta.JavaConstant;
import jdk.vm.ci.meta.JavaKind;
import jdk.vm.ci.meta.ResolvedJavaField;
Expand Down Expand Up @@ -117,8 +115,8 @@ public Node canonical(CanonicalizerTool tool) {
ResolvedJavaType receiverType = StampTool.typeOrNull(object(), tool.getMetaAccess());
if (receiverType != null) {
ResolvedJavaField field = null;
if (offset().isConstant()) {
field = getStaticFieldUnsafeAccess(tool.getConstantReflection());
if (offset().isJavaConstant()) {
field = getStaticFieldUnsafeAccess(tool.getMetaAccessExtensionProvider());
if (field == null) {
long constantOffset = offset().asJavaConstant().asLong();
field = receiverType.findInstanceFieldWithOffset(constantOffset, accessKind());
Expand Down Expand Up @@ -164,50 +162,14 @@ public Node canonical(CanonicalizerTool tool) {
*
* @return the static field, if any, that this node is reading
*/
private ResolvedJavaField getStaticFieldUnsafeAccess(ConstantReflectionProvider constantReflection) {
private ResolvedJavaField getStaticFieldUnsafeAccess(MetaAccessExtensionProvider metaAccessExtension) {
if (!object().isJavaConstant() || !offset().isJavaConstant() ||
object().isNullConstant() || offset().isNullConstant()) {
return null;
}
JavaConstant objectConstant = object().asJavaConstant();
JavaConstant offsetConstant = offset().asJavaConstant();
assert objectConstant != null && offsetConstant != null : "Verified by the check at the beginning.";
ResolvedJavaType staticReceiverType = constantReflection.asJavaType(objectConstant);
if (staticReceiverType == null) {
// object is not of type Class so it is not a static field
return null;
}
return findStaticFieldWithOffset(staticReceiverType, offsetConstant.asLong(), accessKind);
}

public static ResolvedJavaField findStaticFieldWithOffset(ResolvedJavaType type, long offset, JavaKind expectedEntryKind) {
try {
ResolvedJavaField[] declaredFields = type.getStaticFields();
return findFieldWithOffset(offset, expectedEntryKind, declaredFields);
} catch (UnsupportedOperationException e) {
return null;
}
return metaAccessExtension.getStaticFieldForAccess(objectConstant, offsetConstant.asLong(), accessKind);
}

/**
* NOTE GR-18873: this is a copy-paste implementation derived from
* {@code jdk.vm.ci.hotspot.HotSpotResolvedObjectTypeImpl#findStaticFieldWithOffset}.
*/
private static ResolvedJavaField findFieldWithOffset(long offset, JavaKind expectedEntryKind, ResolvedJavaField[] declaredFields) {
for (ResolvedJavaField field : declaredFields) {
long resolvedFieldOffset = field.getOffset();
if (ByteOrder.nativeOrder() == ByteOrder.BIG_ENDIAN &&
expectedEntryKind.isPrimitive() &&
!expectedEntryKind.equals(JavaKind.Void) &&
field.getJavaKind().isPrimitive()) {
resolvedFieldOffset += field.getJavaKind().getByteCount() -
Math.min(field.getJavaKind().getByteCount(), 4 + expectedEntryKind.getByteCount());
}
if (resolvedFieldOffset == offset) {
return field;
}
}
return null;
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -148,7 +148,7 @@ private PointsToAnalyzer(String mainEntryClass, OptionValues options) {
AnalysisMetaAccess aMetaAccess = new StandaloneAnalysisMetaAccess(aUniverse, originalMetaAccess);
StandaloneConstantReflectionProvider aConstantReflection = new StandaloneConstantReflectionProvider(aUniverse, HotSpotJVMCIRuntime.runtime());
StandaloneConstantFieldProvider aConstantFieldProvider = new StandaloneConstantFieldProvider(aMetaAccess);
AnalysisMetaAccessExtensionProvider aMetaAccessExtensionProvider = new AnalysisMetaAccessExtensionProvider();
AnalysisMetaAccessExtensionProvider aMetaAccessExtensionProvider = new AnalysisMetaAccessExtensionProvider(aUniverse);
HostedProviders aProviders = new HostedProviders(aMetaAccess, null, aConstantReflection, aConstantFieldProvider,
originalProviders.getForeignCalls(), originalProviders.getLowerer(), originalProviders.getReplacements(),
originalProviders.getStampProvider(), snippetReflection, new WordTypes(aMetaAccess, wordKind),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,15 +25,25 @@

package com.oracle.graal.pointsto.meta;

import com.oracle.graal.pointsto.heap.ImageHeapConstant;
import com.oracle.graal.pointsto.heap.TypedConstant;
import com.oracle.graal.pointsto.util.GraalAccess;

import jdk.graal.compiler.core.common.spi.MetaAccessExtensionProvider;
import jdk.graal.compiler.debug.GraalError;

import jdk.vm.ci.meta.JavaConstant;
import jdk.vm.ci.meta.JavaKind;
import jdk.vm.ci.meta.JavaType;
import jdk.vm.ci.meta.ResolvedJavaField;
import jdk.vm.ci.meta.ResolvedJavaMethod;
import jdk.vm.ci.meta.ResolvedJavaType;

public class AnalysisMetaAccessExtensionProvider implements MetaAccessExtensionProvider {
private final AnalysisUniverse aUniverse;

public AnalysisMetaAccessExtensionProvider(AnalysisUniverse aUniverse) {
this.aUniverse = aUniverse;
}

@Override
public JavaKind getStorageKind(JavaType type) {
Expand All @@ -43,7 +53,7 @@ public JavaKind getStorageKind(JavaType type) {
@Override
public boolean canConstantFoldDynamicAllocation(ResolvedJavaType t) {
AnalysisType type = (AnalysisType) t;
if (type.universe.sealed()) {
if (aUniverse.sealed()) {
/* Static analysis has finished, e.g., we are applying static analysis results. */
return type.isInstantiated();
} else {
Expand All @@ -61,4 +71,28 @@ public boolean isGuaranteedSafepoint(ResolvedJavaMethod method, boolean isDirect
public boolean canVirtualize(ResolvedJavaType instanceType) {
return true;
}

@Override
public ResolvedJavaField getStaticFieldForAccess(JavaConstant base, long offset, JavaKind accessKind) {
JavaConstant hostedObject;
if (base instanceof ImageHeapConstant imageHeapConstant) {
hostedObject = imageHeapConstant.getHostedObject();
if (hostedObject == null) {
return null;
}
assert !(hostedObject instanceof ImageHeapConstant);
} else if (!(base instanceof TypedConstant)) {
/*
* Ideally, this path should be unreachable, i.e., we should only see TypedConstant. But
* the image heap scanning during static analysis is not implemented cleanly enough and
* invokes this method both with image heap constants and original HotSpot object
* constants. See AnalysisMetaAccess.lookupJavaType.
*/
hostedObject = base;
} else {
return null;
}
MetaAccessExtensionProvider original = GraalAccess.getOriginalProviders().getMetaAccessExtensionProvider();
return aUniverse.lookup(original.getStaticFieldForAccess(hostedObject, offset, accessKind));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -25,13 +25,14 @@

package com.oracle.svm.core.graal.code;

import jdk.graal.compiler.core.common.spi.MetaAccessExtensionProvider;

import com.oracle.svm.core.meta.SharedMethod;
import com.oracle.svm.core.meta.SharedType;

import jdk.graal.compiler.core.common.spi.MetaAccessExtensionProvider;
import jdk.vm.ci.meta.JavaConstant;
import jdk.vm.ci.meta.JavaKind;
import jdk.vm.ci.meta.JavaType;
import jdk.vm.ci.meta.ResolvedJavaField;
import jdk.vm.ci.meta.ResolvedJavaMethod;
import jdk.vm.ci.meta.ResolvedJavaType;

Expand Down Expand Up @@ -78,4 +79,14 @@ public boolean isGuaranteedSafepoint(ResolvedJavaMethod method, boolean isDirect
public boolean canVirtualize(ResolvedJavaType instanceType) {
return true;
}

@Override
public ResolvedJavaField getStaticFieldForAccess(JavaConstant base, long offset, JavaKind accessKind) {
/*
* The base of unsafe static field accesses is not constant until low tier for SVM. See
* com.oracle.svm.core.StaticFieldsSupport for details on the static field base during
* analysis, compilation, and JIT compilation.
*/
return null;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -150,6 +150,7 @@
import jdk.vm.ci.meta.JavaConstant;
import jdk.vm.ci.meta.JavaKind;
import jdk.vm.ci.meta.JavaType;
import jdk.vm.ci.meta.ResolvedJavaField;
import jdk.vm.ci.meta.ResolvedJavaMethod;
import jdk.vm.ci.meta.ResolvedJavaType;

Expand Down Expand Up @@ -1141,6 +1142,16 @@ public boolean isGuaranteedSafepoint(ResolvedJavaMethod method, boolean isDirect
public boolean canVirtualize(ResolvedJavaType instanceType) {
return true;
}

@Override
public ResolvedJavaField getStaticFieldForAccess(JavaConstant base, long offset, JavaKind accessKind) {
/*
* The base of unsafe static field accesses is not constant until low tier for SVM. See
* com.oracle.svm.core.StaticFieldsSupport for details on the static field base during
* analysis, compilation, and JIT compilation.
*/
return null;
}
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@
import com.oracle.graal.pointsto.meta.AnalysisField;
import com.oracle.graal.pointsto.meta.AnalysisMetaAccessExtensionProvider;
import com.oracle.graal.pointsto.meta.AnalysisType;
import com.oracle.graal.pointsto.meta.AnalysisUniverse;
import com.oracle.graal.pointsto.meta.PointsToAnalysisMethod;
import com.oracle.graal.pointsto.results.StrengthenGraphs;
import com.oracle.objectfile.ObjectFile;
Expand Down Expand Up @@ -248,8 +249,8 @@ public MethodTypeFlowBuilder createMethodTypeFlowBuilder(PointsToAnalysis bb, Po
return new SVMMethodTypeFlowBuilder(bb, method, flowsGraph, graphKind);
}

public MetaAccessExtensionProvider createAnalysisMetaAccessExtensionProvider() {
return new AnalysisMetaAccessExtensionProvider();
public MetaAccessExtensionProvider createAnalysisMetaAccessExtensionProvider(AnalysisUniverse aUniverse) {
return new AnalysisMetaAccessExtensionProvider(aUniverse);
}

public MetaAccessExtensionProvider createCompilationMetaAccessExtensionProvider(@SuppressWarnings("unused") MetaAccessProvider metaAccess) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1260,7 +1260,7 @@ private static HostedProviders createHostedProviders(TargetDescription target, A

HostedSnippetReflectionProvider aSnippetReflection = new HostedSnippetReflectionProvider(null, aWordTypes);

MetaAccessExtensionProvider aMetaAccessExtensionProvider = HostedConfiguration.instance().createAnalysisMetaAccessExtensionProvider();
MetaAccessExtensionProvider aMetaAccessExtensionProvider = HostedConfiguration.instance().createAnalysisMetaAccessExtensionProvider(aUniverse);

LoweringProvider aLoweringProvider = SubstrateLoweringProvider.createForHosted(aMetaAccess, null, platformConfig, aMetaAccessExtensionProvider);

Expand Down
Loading

0 comments on commit 562c03c

Please sign in to comment.