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 @@ -703,6 +703,10 @@ public void rescanRoot(Field reflectionField, ScanReason rescanReason) {
});
}

public void rescanField(Object receiver, Field reflectionField, ScanReason reason) {
rescanField(receiver, metaAccess.lookupJavaField(reflectionField), reason);
}

/**
* Trigger rescanning of an instance field. If the receiver value or field value were not
* scanned before they will first be scanned and added to the shadow heap, then the value will
Expand All @@ -711,11 +715,10 @@ public void rescanRoot(Field reflectionField, ScanReason rescanReason) {
* type ({@code Object[]}, {{@link Collection}, {@link Map} or {@link EconomicMap}} then its
* elements will be rescanned too.
*/
public void rescanField(Object receiver, Field reflectionField, ScanReason reason) {
public void rescanField(Object receiver, AnalysisField field, ScanReason reason) {
maybeRunInExecutor(unused -> {
AnalysisType type = metaAccess.lookupJavaType(reflectionField.getDeclaringClass());
AnalysisType type = field.getType();
if (type.isReachable()) {
AnalysisField field = metaAccess.lookupJavaField(reflectionField);
assert !field.isStatic() : field;
if (!field.isReachable()) {
return;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,8 +30,6 @@
import java.util.Set;
import java.util.TreeMap;

import jdk.graal.compiler.core.common.NumUtil;

import com.oracle.objectfile.BuildDependency;
import com.oracle.objectfile.LayoutDecisionMap;
import com.oracle.objectfile.ObjectFile;
Expand All @@ -45,6 +43,8 @@
import com.oracle.objectfile.io.OutputAssembler;
import com.oracle.objectfile.macho.MachOObjectFile.MachOSection;
import com.oracle.objectfile.macho.MachOObjectFile.Segment64Command;

import jdk.graal.compiler.core.common.NumUtil;
import jdk.graal.compiler.debug.GraalError;

class MachORelocationElement extends MachOObjectFile.LinkEditElement {
Expand Down Expand Up @@ -268,7 +268,9 @@ private MachORelocationInfo(MachORelocationElement containingElement, MachOSecti
// FIXME: also allow section numbers here, for non-extern symbols
// FIXME: encode R_ABS symbol number
this.sym = symtab.getSymbol(symbolName);
assert this.sym != null : "could not find symbol " + symbolName;
if (this.sym == null) {
throw new IllegalArgumentException("Could not find symbol " + symbolName);
}
// if the symbol is defined in the same file, i.e. locally, we have a target section
assert !asLocalReloc || this.sym.isDefined();
this.targetSection = asLocalReloc ? (MachOSection) this.sym.getDefinedSection() : null;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,14 +43,14 @@
import com.oracle.svm.core.graal.meta.SubstrateRegisterConfig;
import com.oracle.svm.core.util.VMError;
import com.oracle.svm.hosted.image.NativeImage;
import com.oracle.svm.hosted.meta.HostedMethod;
import com.oracle.svm.interpreter.metadata.InterpreterResolvedJavaMethod;

import jdk.graal.compiler.asm.Assembler;
import jdk.graal.compiler.asm.Label;
import jdk.graal.compiler.asm.aarch64.AArch64MacroAssembler;
import jdk.graal.compiler.core.common.LIRKind;
import jdk.vm.ci.code.Register;
import jdk.vm.ci.meta.ResolvedJavaMethod;

public class AArch64InterpreterStubSection extends InterpreterStubSection {
public AArch64InterpreterStubSection() {
Expand Down Expand Up @@ -159,7 +159,7 @@ private void recordEnterStubForPatching(Assembler.CodeAnnotation a) {

@Platforms(Platform.HOSTED_ONLY.class)
@Override
protected void markEnterStubPatch(ObjectFile.ProgbitsSectionImpl pltBuffer, ResolvedJavaMethod enterStub) {
protected void markEnterStubPatch(ObjectFile.ProgbitsSectionImpl pltBuffer, HostedMethod enterStub) {
pltBuffer.markRelocationSite(resolverPatchOffset, AARCH64_R_AARCH64_ADR_PREL_PG_HI21, NativeImage.localSymbolNameForMethod(enterStub), 0);
pltBuffer.markRelocationSite(resolverPatchOffset + 4, AARCH64_R_AARCH64_ADD_ABS_LO12_NC, NativeImage.localSymbolNameForMethod(enterStub), 0);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@
import com.oracle.svm.core.graal.meta.SubstrateRegisterConfig;
import com.oracle.svm.core.util.VMError;
import com.oracle.svm.hosted.image.NativeImage;
import com.oracle.svm.hosted.meta.HostedMethod;
import com.oracle.svm.interpreter.metadata.InterpreterResolvedJavaMethod;

import jdk.graal.compiler.asm.Assembler;
Expand All @@ -48,7 +49,6 @@
import jdk.graal.compiler.asm.amd64.AMD64MacroAssembler;
import jdk.graal.compiler.core.common.LIRKind;
import jdk.graal.compiler.core.common.NumUtil;
import jdk.vm.ci.meta.ResolvedJavaMethod;

public class AMD64InterpreterStubSection extends InterpreterStubSection {
public AMD64InterpreterStubSection() {
Expand Down Expand Up @@ -144,7 +144,7 @@ private void recordEnterStubForPatching(Assembler.CodeAnnotation a) {

@Platforms(Platform.HOSTED_ONLY.class)
@Override
protected void markEnterStubPatch(ObjectFile.ProgbitsSectionImpl pltBuffer, ResolvedJavaMethod enterStub) {
protected void markEnterStubPatch(ObjectFile.ProgbitsSectionImpl pltBuffer, HostedMethod enterStub) {
pltBuffer.markRelocationSite(resolverPatchOffset, resolverPatchRelocationKind, NativeImage.localSymbolNameForMethod(enterStub), resolverKindAddend);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -36,9 +36,6 @@
import static com.oracle.svm.interpreter.metadata.InterpreterUniverseImpl.toHexString;

import java.io.IOException;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.nio.charset.StandardCharsets;
import java.nio.file.FileSystems;
Expand Down Expand Up @@ -67,8 +64,8 @@
import com.oracle.graal.pointsto.ObjectScanner.ScanReason;
import com.oracle.graal.pointsto.constraints.UnsupportedFeatureException;
import com.oracle.graal.pointsto.heap.ImageHeapConstant;
import com.oracle.svm.util.OriginalClassProvider;
import com.oracle.graal.pointsto.meta.AnalysisField;
import com.oracle.graal.pointsto.meta.AnalysisMetaAccess;
import com.oracle.graal.pointsto.meta.AnalysisMethod;
import com.oracle.graal.pointsto.meta.AnalysisType;
import com.oracle.svm.core.BuildArtifacts;
Expand Down Expand Up @@ -111,7 +108,7 @@
import com.oracle.svm.interpreter.metadata.ReferenceConstant;
import com.oracle.svm.interpreter.metadata.serialization.SerializationContext;
import com.oracle.svm.interpreter.metadata.serialization.Serializers;
import com.oracle.svm.util.ReflectionUtil;
import com.oracle.svm.util.JVMCIReflectionUtil;

import jdk.graal.compiler.api.replacements.SnippetReflectionProvider;
import jdk.graal.compiler.core.common.SuppressFBWarnings;
Expand All @@ -130,6 +127,7 @@
import jdk.vm.ci.meta.PrimitiveConstant;
import jdk.vm.ci.meta.ResolvedJavaField;
import jdk.vm.ci.meta.ResolvedJavaMethod;
import jdk.vm.ci.meta.ResolvedJavaType;
import jdk.vm.ci.meta.UnresolvedJavaMethod;

/**
Expand All @@ -144,9 +142,9 @@
@Platforms(Platform.HOSTED_ONLY.class)
@AutomaticallyRegisteredFeature
public class DebuggerFeature implements InternalFeature {
private Method enterInterpreterMethod;
private AnalysisMethod enterInterpreterMethod;
private InterpreterStubTable enterStubTable = null;
private final List<Class<?>> classesUsedByInterpreter = new ArrayList<>();
private final List<ResolvedJavaType> classesUsedByInterpreter = new ArrayList<>();
private Set<AnalysisMethod> methodsProcessedDuringAnalysis;
private InvocationPlugins invocationPlugins;
private static final String SYNTHETIC_ASSERTIONS_DISABLED_FIELD_NAME = "$assertionsDisabled";
Expand All @@ -165,9 +163,9 @@ public List<Class<? extends Feature>> getRequiredFeatures() {
SymbolsFeature.class);
}

private static Class<?> getArgumentClass(GraphBuilderContext b, ResolvedJavaMethod targetMethod, int parameterIndex, ValueNode arg) {
private static ResolvedJavaType getArgumentType(GraphBuilderContext b, ResolvedJavaMethod targetMethod, int parameterIndex, ValueNode arg) {
SubstrateGraphBuilderPlugins.checkParameterUsage(arg.isConstant(), b, targetMethod, parameterIndex, "parameter is not a compile time constant");
return OriginalClassProvider.getJavaClass(b.getConstantReflection().asJavaType(arg.asJavaConstant()));
return b.getConstantReflection().asJavaType(arg.asJavaConstant());
}

@Override
Expand All @@ -178,9 +176,9 @@ public void registerInvocationPlugins(Providers providers, GraphBuilderConfigura
r.register(new InvocationPlugin.RequiredInvocationPlugin("markKlass", Class.class) {
@Override
public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver receiver, ValueNode arg1) {
Class<?> targetKlass = getArgumentClass(b, targetMethod, 1, arg1);
InterpreterUtil.log("[invocation plugin] Adding %s", targetKlass);
classesUsedByInterpreter.add(targetKlass);
ResolvedJavaType targetType = getArgumentType(b, targetMethod, 1, arg1);
InterpreterUtil.log("[invocation plugin] Adding %s", targetType.getUnqualifiedName());
classesUsedByInterpreter.add(targetType);

/* no-op in compiled code */
return true;
Expand All @@ -198,33 +196,32 @@ public void afterRegistration(AfterRegistrationAccess access) {
@Override
public void beforeAnalysis(BeforeAnalysisAccess access) {
FeatureImpl.BeforeAnalysisAccessImpl accessImpl = (FeatureImpl.BeforeAnalysisAccessImpl) access;
AnalysisMetaAccess metaAccess = accessImpl.getMetaAccess();

try {
enterInterpreterMethod = InterpreterStubSection.class.getMethod("enterMethodInterpreterStub", int.class, Pointer.class);
accessImpl.registerAsRoot(enterInterpreterMethod, true, "stub for interpreter");
AnalysisType aInterpreterStubSection = metaAccess.lookupJavaType(InterpreterStubSection.class);
enterInterpreterMethod = (AnalysisMethod) JVMCIReflectionUtil.getDeclaredMethod(metaAccess, aInterpreterStubSection, "enterMethodInterpreterStub", int.class, Pointer.class);
accessImpl.registerAsRoot(enterInterpreterMethod, true, "stub for interpreter");

// Holds references that must be kept alive in the image heap.
access.registerAsAccessed(DebuggerSupport.class.getDeclaredField("referencesInImage"));
access.registerAsAccessed(DebuggerSupport.class.getDeclaredField("methodPointersInImage"));
// Holds references that must be kept alive in the image heap.
AnalysisType aDebuggerSupport = metaAccess.lookupJavaType(DebuggerSupport.class);
accessImpl.registerAsAccessed((AnalysisField) JVMCIReflectionUtil.getDeclaredField(aDebuggerSupport, "referencesInImage"),
"Holds references that must be kept alive in the image heap.");
accessImpl.registerAsAccessed((AnalysisField) JVMCIReflectionUtil.getDeclaredField(aDebuggerSupport, "methodPointersInImage"),
"Holds references that must be kept alive in the image heap.");

accessImpl.registerAsRoot(System.class.getDeclaredMethod("arraycopy", Object.class, int.class, Object.class, int.class, int.class), true,
"Allow interpreting methods that call System.arraycopy");
} catch (NoSuchMethodException | NoSuchFieldException e) {
throw VMError.shouldNotReachHere(e);
}
AnalysisType aSystem = metaAccess.lookupJavaType(System.class);
accessImpl.registerAsRoot((AnalysisMethod) JVMCIReflectionUtil.getDeclaredMethod(metaAccess, aSystem, "arraycopy", Object.class, int.class, Object.class, int.class, int.class),
true, "Allow interpreting methods that call System.arraycopy");

registerStringConcatenation(accessImpl);

// GR-53734: Known issues around reachability
try {
// JDK code introduced a new optional intrinsic:
// https://github.com/openjdk/jdk22u/commit/a4e9168bab1c2872ce2dbc7971a45c259270271f
// consider DualPivotQuicksort.java:268, int.class is not needed if the sort helper
// is inlined, therefore it's not needed. Still needed for interpreter execution.
access.registerAsAccessed(Integer.class.getField("TYPE"));
} catch (NoSuchFieldException e) {
throw VMError.shouldNotReachHere(e);
}
// JDK code introduced a new optional intrinsic:
// https://github.com/openjdk/jdk22u/commit/a4e9168bab1c2872ce2dbc7971a45c259270271f
// consider DualPivotQuicksort.java:268, int.class is not needed if the sort helper
// is inlined, therefore it's not needed. Still needed for interpreter execution.
AnalysisType aInteger = metaAccess.lookupJavaType(Integer.class);
accessImpl.registerAsAccessed((AnalysisField) JVMCIReflectionUtil.getDeclaredField(aInteger, "TYPE"), "Read by the interpreter");

methodsProcessedDuringAnalysis = new HashSet<>();

Expand All @@ -247,20 +244,18 @@ private static void registerStringConcatenation(FeatureImpl.BeforeAnalysisAccess
* These registrations enable the interpreter to "interpret" StringBuilder-based String
* concatenation optimized away by the compiler.
*/
try {
List<Method> appendMethods = Arrays.stream(StringBuilder.class.getDeclaredMethods())
.filter(m -> "append".equals(m.getName()))
.collect(Collectors.toList());
for (Method m : appendMethods) {
accessImpl.registerAsRoot(m, false, "string concat in interpreter");
}
for (Constructor<?> c : StringBuilder.class.getDeclaredConstructors()) {
accessImpl.registerAsRoot(c, true, "string concat in interpreter");
}
accessImpl.registerAsRoot(StringBuilder.class.getConstructor(), true, "string concat in interpreter");
} catch (NoSuchMethodException e) {
throw new RuntimeException(e);
AnalysisMetaAccess metaAccess = accessImpl.getMetaAccess();
AnalysisType aStringBuilder = metaAccess.lookupJavaType(StringBuilder.class);
List<AnalysisMethod> appendMethods = Arrays.stream(aStringBuilder.getDeclaredMethods(false))
.filter(m -> "append".equals(m.getName())).toList();
for (AnalysisMethod m : appendMethods) {
accessImpl.registerAsRoot(m, false, "string concat in interpreter");
}
for (AnalysisMethod c : aStringBuilder.getDeclaredConstructors(false)) {
accessImpl.registerAsRoot(c, true, "string concat in interpreter");
}
AnalysisMethod aMethod = (AnalysisMethod) JVMCIReflectionUtil.getDeclaredConstructor(metaAccess, aStringBuilder);
accessImpl.registerAsRoot(aMethod, true, "string concat in interpreter");
}

static boolean isReachable(AnalysisMethod m) {
Expand Down Expand Up @@ -299,13 +294,13 @@ public void duringAnalysis(DuringAnalysisAccess access) {

if (!classesUsedByInterpreter.isEmpty()) {
access.requireAnalysisIteration();
for (Class<?> k : classesUsedByInterpreter) {
accessImpl.registerAsUsed(k);
Arrays.stream(k.getDeclaredMethods()).filter(m -> m.getName().startsWith("test")).forEach(m -> {
AnalysisMethod aMethod = accessImpl.getMetaAccess().lookupJavaMethod(m);
for (ResolvedJavaType k : classesUsedByInterpreter) {
AnalysisType aType = k instanceof AnalysisType analysisType ? analysisType : accessImpl.getUniverse().lookup(k);
accessImpl.registerAsUsed(aType, "used by interpreter");
Arrays.stream(aType.getDeclaredMethods(false)).filter(m -> m.getName().startsWith("test")).forEach(aMethod -> {
VMError.guarantee(!aMethod.isConstructor());
accessImpl.registerAsRoot(aMethod, aMethod.isConstructor(), "reached due to interpreter directive");
InterpreterUtil.log("[during analysis] Adding method %s", m);
InterpreterUtil.log("[during analysis] Adding method %s", aMethod);
});
}
classesUsedByInterpreter.clear();
Expand Down Expand Up @@ -440,7 +435,7 @@ public void beforeCompilation(BeforeCompilationAccess access) {
FeatureImpl.BeforeCompilationAccessImpl accessImpl = (FeatureImpl.BeforeCompilationAccessImpl) access;
HostedUniverse hUniverse = accessImpl.getUniverse();
HostedMetaAccess hMetaAccess = accessImpl.getMetaAccess();
MetaAccessProvider aMetaAccess = hMetaAccess.getWrapped();
AnalysisMetaAccess aMetaAccess = (AnalysisMetaAccess) hMetaAccess.getWrapped();
BuildTimeInterpreterUniverse iUniverse = BuildTimeInterpreterUniverse.singleton();

for (HostedType hType : hUniverse.getTypes()) {
Expand Down Expand Up @@ -501,20 +496,18 @@ public void beforeCompilation(BeforeCompilationAccess access) {

iUniverse.purgeUnreachable(hMetaAccess);

Field vtableHolderField = ReflectionUtil.lookupField(InterpreterResolvedObjectType.class, "vtableHolder");
AnalysisField vtableHolderField = (AnalysisField) JVMCIReflectionUtil.getDeclaredField(aMetaAccess.lookupJavaType(InterpreterResolvedObjectType.class), "vtableHolder");
ScanReason reason = new OtherReason("Manual rescan triggered before compilation from " + DebuggerFeature.class);
for (HostedType hostedType : hUniverse.getTypes()) {
iUniverse.mirrorSVMVTable(hostedType, objectType -> accessImpl.getHeapScanner().rescanField(objectType, vtableHolderField, reason));
}

// Allow methods that call System.arraycopy to be interpreted.
try {
HostedMethod arraycopy = hMetaAccess.lookupJavaMethod(
System.class.getDeclaredMethod("arraycopy", Object.class, int.class, Object.class, int.class, int.class));
SubstrateCompilationDirectives.singleton().registerForcedCompilation(arraycopy);
} catch (NoSuchMethodException e) {
throw new RuntimeException(e);
}

HostedType systemClass = hMetaAccess.lookupJavaType(System.class);
AnalysisMethod arraycopy = (AnalysisMethod) JVMCIReflectionUtil.getDeclaredMethod(aMetaAccess,
systemClass.getWrapped(), "arraycopy", Object.class, int.class, Object.class, int.class, int.class);
SubstrateCompilationDirectives.singleton().registerForcedCompilation(arraycopy);
}

@Override
Expand Down Expand Up @@ -768,7 +761,7 @@ public void beforeImageWrite(BeforeImageWriteAccess access) {

InterpreterStubSection stubSection = ImageSingletons.lookup(InterpreterStubSection.class);

stubSection.markEnterStubPatch(accessImpl.getHostedMetaAccess().lookupJavaMethod(enterInterpreterMethod));
stubSection.markEnterStubPatch(accessImpl.getHostedUniverse().lookup(enterInterpreterMethod));
enterStubTable.writeMetadataHashString(hashString.getBytes(StandardCharsets.UTF_8));
}

Expand Down
Loading