diff --git a/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/api/replacements/SnippetReflectionProvider.java b/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/api/replacements/SnippetReflectionProvider.java index 7d00b9584ed8..d7005a450e1f 100644 --- a/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/api/replacements/SnippetReflectionProvider.java +++ b/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/api/replacements/SnippetReflectionProvider.java @@ -64,15 +64,6 @@ public interface SnippetReflectionProvider { */ T asObject(Class 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. diff --git a/substratevm/src/com.oracle.svm.core.graal.aarch64/src/com/oracle/svm/core/graal/aarch64/SubstrateAArch64Backend.java b/substratevm/src/com.oracle.svm.core.graal.aarch64/src/com/oracle/svm/core/graal/aarch64/SubstrateAArch64Backend.java index 95f02749a3b1..1963fe393cd2 100755 --- a/substratevm/src/com.oracle.svm.core.graal.aarch64/src/com/oracle/svm/core/graal/aarch64/SubstrateAArch64Backend.java +++ b/substratevm/src/com.oracle.svm.core.graal.aarch64/src/com/oracle/svm/core/graal/aarch64/SubstrateAArch64Backend.java @@ -693,7 +693,7 @@ public void visitBreakpointNode(BreakpointNode node) { @Override protected DebugInfoBuilder createDebugInfoBuilder(StructuredGraph graph, NodeValueMap nodeValueMap) { - return new SubstrateDebugInfoBuilder(graph, getProviders().getSnippetReflection(), gen.getProviders().getMetaAccessExtensionProvider(), nodeValueMap); + return new SubstrateDebugInfoBuilder(graph, gen.getProviders().getMetaAccessExtensionProvider(), nodeValueMap); } private boolean getDestroysCallerSavedRegisters(ResolvedJavaMethod targetMethod) { diff --git a/substratevm/src/com.oracle.svm.core.graal.amd64/src/com/oracle/svm/core/graal/amd64/SubstrateAMD64Backend.java b/substratevm/src/com.oracle.svm.core.graal.amd64/src/com/oracle/svm/core/graal/amd64/SubstrateAMD64Backend.java index 63671ceabe69..59d825ece5fc 100644 --- a/substratevm/src/com.oracle.svm.core.graal.amd64/src/com/oracle/svm/core/graal/amd64/SubstrateAMD64Backend.java +++ b/substratevm/src/com.oracle.svm.core.graal.amd64/src/com/oracle/svm/core/graal/amd64/SubstrateAMD64Backend.java @@ -869,7 +869,7 @@ public void visitBreakpointNode(BreakpointNode node) { @Override protected DebugInfoBuilder createDebugInfoBuilder(StructuredGraph graph, NodeValueMap nodeValueMap) { - return new SubstrateDebugInfoBuilder(graph, getProviders().getSnippetReflection(), gen.getProviders().getMetaAccessExtensionProvider(), nodeValueMap); + return new SubstrateDebugInfoBuilder(graph, gen.getProviders().getMetaAccessExtensionProvider(), nodeValueMap); } @Override diff --git a/substratevm/src/com.oracle.svm.core.graal.llvm/src/com/oracle/svm/core/graal/llvm/NodeLLVMBuilder.java b/substratevm/src/com.oracle.svm.core.graal.llvm/src/com/oracle/svm/core/graal/llvm/NodeLLVMBuilder.java index 40c8f5caa550..e91c8b8ccd03 100644 --- a/substratevm/src/com.oracle.svm.core.graal.llvm/src/com/oracle/svm/core/graal/llvm/NodeLLVMBuilder.java +++ b/substratevm/src/com.oracle.svm.core.graal.llvm/src/com/oracle/svm/core/graal/llvm/NodeLLVMBuilder.java @@ -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().getSnippetReflection(), gen.getProviders().getMetaAccessExtensionProvider(), this); + this.debugInfoBuilder = new SubstrateDebugInfoBuilder(graph, gen.getProviders().getMetaAccessExtensionProvider(), this); setCompilationResultMethod(gen.getCompilationResult(), graph); for (HIRBlock block : graph.getLastSchedule().getCFG().getBlocks()) { diff --git a/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/code/CodeInfoAccess.java b/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/code/CodeInfoAccess.java index 5cb0ab8249c8..0e391a5c34e9 100644 --- a/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/code/CodeInfoAccess.java +++ b/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/code/CodeInfoAccess.java @@ -24,7 +24,6 @@ */ package com.oracle.svm.core.code; -import jdk.graal.compiler.api.replacements.Fold; import org.graalvm.nativeimage.c.function.CodePointer; import org.graalvm.nativeimage.c.struct.SizeOf; import org.graalvm.word.UnsignedWord; @@ -37,6 +36,7 @@ import com.oracle.svm.core.c.NonmovableArray; import com.oracle.svm.core.c.NonmovableArrays; import com.oracle.svm.core.c.NonmovableObjectArray; +import com.oracle.svm.core.code.FrameInfoDecoder.ConstantAccess; import com.oracle.svm.core.deopt.SubstrateInstalledCode; import com.oracle.svm.core.graal.stackvalue.UnsafeStackValue; import com.oracle.svm.core.heap.Heap; @@ -44,6 +44,8 @@ import com.oracle.svm.core.thread.VMOperation; import com.oracle.svm.core.util.VMError; +import jdk.graal.compiler.api.replacements.Fold; + /** * Provides functionality to query information about a unit of compiled code from a {@link CodeInfo} * object. This helper class is necessary to ensure that {@link CodeInfo} objects are used @@ -258,8 +260,8 @@ public static String getName(CodeInfo info) { return getObjectField(info, CodeInfoImpl.NAME_OBJFIELD); } - public static long lookupDeoptimizationEntrypoint(CodeInfo info, long method, long encodedBci, CodeInfoQueryResult codeInfo) { - return CodeInfoDecoder.lookupDeoptimizationEntrypoint(info, method, encodedBci, codeInfo); + public static long lookupDeoptimizationEntrypoint(CodeInfo info, long method, long encodedBci, CodeInfoQueryResult codeInfo, ConstantAccess constantAccess) { + return CodeInfoDecoder.lookupDeoptimizationEntrypoint(info, method, encodedBci, codeInfo, constantAccess); } @Uninterruptible(reason = "Called from uninterruptible code.", mayBeInlined = true) @@ -280,7 +282,11 @@ public static long lookupStackReferenceMapIndex(CodeInfo info, long ip) { } public static void lookupCodeInfo(CodeInfo info, long ip, CodeInfoQueryResult codeInfoQueryResult) { - CodeInfoDecoder.lookupCodeInfo(info, ip, codeInfoQueryResult); + lookupCodeInfo(info, ip, codeInfoQueryResult, FrameInfoDecoder.SubstrateConstantAccess); + } + + public static void lookupCodeInfo(CodeInfo info, long ip, CodeInfoQueryResult codeInfoQueryResult, ConstantAccess constantAccess) { + CodeInfoDecoder.lookupCodeInfo(info, ip, codeInfoQueryResult, constantAccess); } @Uninterruptible(reason = "Called from uninterruptible code.", mayBeInlined = true) diff --git a/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/code/CodeInfoDecoder.java b/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/code/CodeInfoDecoder.java index b2b870877aec..05a0963350b6 100644 --- a/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/code/CodeInfoDecoder.java +++ b/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/code/CodeInfoDecoder.java @@ -26,9 +26,6 @@ import static com.oracle.svm.core.util.VMError.shouldNotReachHereUnexpectedInput; -import jdk.graal.compiler.api.replacements.Fold; -import jdk.graal.compiler.core.common.util.TypeConversion; -import jdk.graal.compiler.options.Option; import org.graalvm.nativeimage.ImageSingletons; import org.graalvm.nativeimage.Platform; import org.graalvm.nativeimage.Platforms; @@ -37,12 +34,17 @@ import com.oracle.svm.core.AlwaysInline; import com.oracle.svm.core.Uninterruptible; import com.oracle.svm.core.c.NonmovableObjectArray; +import com.oracle.svm.core.code.FrameInfoDecoder.ConstantAccess; import com.oracle.svm.core.heap.ReferenceMapIndex; import com.oracle.svm.core.jdk.UninterruptibleUtils; import com.oracle.svm.core.option.HostedOptionKey; import com.oracle.svm.core.util.Counter; import com.oracle.svm.core.util.NonmovableByteArrayReader; +import jdk.graal.compiler.api.replacements.Fold; +import jdk.graal.compiler.core.common.util.TypeConversion; +import jdk.graal.compiler.options.Option; + /** * Decodes the metadata for compiled code. The data is an encoded byte stream to make it as compact * as possible, but still allow fast constant time access. @@ -132,7 +134,7 @@ private static long lookupCodeInfoEntryOffsetOrDefault(CodeInfo info, long ip) { } } - static void lookupCodeInfo(CodeInfo info, long ip, CodeInfoQueryResult codeInfoQueryResult) { + static void lookupCodeInfo(CodeInfo info, long ip, CodeInfoQueryResult codeInfoQueryResult, ConstantAccess constantAccess) { long sizeEncoding = initialSizeEncoding(); long entryIP = lookupEntryIP(ip); long entryOffset = loadEntryOffset(info, ip); @@ -143,7 +145,7 @@ static void lookupCodeInfo(CodeInfo info, long ip, CodeInfoQueryResult codeInfoQ codeInfoQueryResult.encodedFrameSize = sizeEncoding; codeInfoQueryResult.exceptionOffset = loadExceptionOffset(info, entryOffset, entryFlags); codeInfoQueryResult.referenceMapIndex = loadReferenceMapIndex(info, entryOffset, entryFlags); - codeInfoQueryResult.frameInfo = loadFrameInfo(info, entryOffset, entryFlags); + codeInfoQueryResult.frameInfo = loadFrameInfo(info, entryOffset, entryFlags, constantAccess); return; } @@ -181,7 +183,7 @@ static void lookupCodeInfo(CodeInfo info, long ip, SimpleCodeInfoQueryResult cod codeInfoQueryResult.setReferenceMapIndex(ReferenceMapIndex.NO_REFERENCE_MAP); } - static long lookupDeoptimizationEntrypoint(CodeInfo info, long method, long encodedBci, CodeInfoQueryResult codeInfo) { + static long lookupDeoptimizationEntrypoint(CodeInfo info, long method, long encodedBci, CodeInfoQueryResult codeInfo, ConstantAccess constantAccess) { long sizeEncoding = initialSizeEncoding(); long entryIP = lookupEntryIP(method); @@ -216,7 +218,7 @@ static long lookupDeoptimizationEntrypoint(CodeInfo info, long method, long enco codeInfo.encodedFrameSize = sizeEncoding; codeInfo.exceptionOffset = loadExceptionOffset(info, entryOffset, entryFlags); codeInfo.referenceMapIndex = loadReferenceMapIndex(info, entryOffset, entryFlags); - codeInfo.frameInfo = loadFrameInfo(info, entryOffset, entryFlags); + codeInfo.frameInfo = loadFrameInfo(info, entryOffset, entryFlags, constantAccess); assert codeInfo.frameInfo.isDeoptEntry() && codeInfo.frameInfo.getCaller() == null : "Deoptimization entry must not have inlined frames"; return entryIP; } @@ -389,7 +391,7 @@ private static boolean isDeoptEntryPoint(CodeInfo info, long entryOffset, int en } } - private static FrameInfoQueryResult loadFrameInfo(CodeInfo info, long entryOffset, int entryFlags) { + private static FrameInfoQueryResult loadFrameInfo(CodeInfo info, long entryOffset, int entryFlags, ConstantAccess constantAccess) { boolean isDeoptEntry; switch (extractFI(entryFlags)) { case FI_NO_DEOPT: @@ -405,7 +407,7 @@ private static FrameInfoQueryResult loadFrameInfo(CodeInfo info, long entryOffse throw shouldNotReachHereUnexpectedInput(entryFlags); // ExcludeFromJacocoGeneratedReport } int frameInfoIndex = NonmovableByteArrayReader.getS4(CodeInfoAccess.getCodeInfoEncodings(info), offsetFI(entryOffset, entryFlags)); - return FrameInfoDecoder.decodeFrameInfo(isDeoptEntry, new ReusableTypeReader(CodeInfoAccess.getFrameInfoEncodings(info), frameInfoIndex), info); + return FrameInfoDecoder.decodeFrameInfo(isDeoptEntry, new ReusableTypeReader(CodeInfoAccess.getFrameInfoEncodings(info), frameInfoIndex), info, constantAccess); } @AlwaysInline("Make IP-lookup loop call free") @@ -640,7 +642,8 @@ private void decodeNextEntry() { singleShotFrameInfoQueryResultAllocator.reload(); int entryFlags = loadEntryFlags(info, state.entryOffset); boolean isDeoptEntry = extractFI(entryFlags) == FI_DEOPT_ENTRY_INDEX_S4; - result = FrameInfoDecoder.decodeFrameInfo(isDeoptEntry, frameInfoReader, info, singleShotFrameInfoQueryResultAllocator, DummyValueInfoAllocator.SINGLETON, state); + result = FrameInfoDecoder.decodeFrameInfo(isDeoptEntry, frameInfoReader, info, singleShotFrameInfoQueryResultAllocator, DummyValueInfoAllocator.SINGLETON, + FrameInfoDecoder.SubstrateConstantAccess, state); if (result == null) { /* No more entries. */ canDecode = false; @@ -741,7 +744,7 @@ public FrameInfoQueryResult.ValueInfo[][] newValueInfoArrayArray(int len) { @Override @Uninterruptible(reason = "Called from uninterruptible code.", mayBeInlined = true) - public void decodeConstant(FrameInfoQueryResult.ValueInfo valueInfo, NonmovableObjectArray frameInfoObjectConstants) { + public void decodeConstant(FrameInfoQueryResult.ValueInfo valueInfo, NonmovableObjectArray frameInfoObjectConstants, ConstantAccess constantAccess) { } } } diff --git a/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/code/CodeInfoEncoder.java b/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/code/CodeInfoEncoder.java index 0234ff333afc..c58ab2d74eda 100644 --- a/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/code/CodeInfoEncoder.java +++ b/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/code/CodeInfoEncoder.java @@ -31,13 +31,6 @@ import org.graalvm.collections.EconomicSet; import org.graalvm.collections.Equivalence; -import jdk.graal.compiler.code.CompilationResult; -import jdk.graal.compiler.core.common.NumUtil; -import jdk.graal.compiler.core.common.util.FrequencyEncoder; -import jdk.graal.compiler.core.common.util.TypeConversion; -import jdk.graal.compiler.core.common.util.UnsafeArrayTypeWriter; -import jdk.graal.compiler.nodes.FrameState; -import jdk.graal.compiler.options.Option; import org.graalvm.nativeimage.ImageSingletons; import org.graalvm.word.Pointer; import org.graalvm.word.UnsignedWord; @@ -49,6 +42,7 @@ import com.oracle.svm.core.c.NonmovableArray; import com.oracle.svm.core.c.NonmovableArrays; import com.oracle.svm.core.c.NonmovableObjectArray; +import com.oracle.svm.core.code.FrameInfoDecoder.ConstantAccess; import com.oracle.svm.core.code.FrameInfoQueryResult.ValueInfo; import com.oracle.svm.core.code.FrameInfoQueryResult.ValueType; import com.oracle.svm.core.config.ConfigurationValues; @@ -64,12 +58,18 @@ import com.oracle.svm.core.meta.SharedField; import com.oracle.svm.core.meta.SharedMethod; import com.oracle.svm.core.meta.SharedType; -import com.oracle.svm.core.meta.SubstrateObjectConstant; import com.oracle.svm.core.option.HostedOptionKey; import com.oracle.svm.core.util.ByteArrayReader; import com.oracle.svm.core.util.Counter; import com.oracle.svm.core.util.VMError; +import jdk.graal.compiler.code.CompilationResult; +import jdk.graal.compiler.core.common.NumUtil; +import jdk.graal.compiler.core.common.util.FrequencyEncoder; +import jdk.graal.compiler.core.common.util.TypeConversion; +import jdk.graal.compiler.core.common.util.UnsafeArrayTypeWriter; +import jdk.graal.compiler.nodes.FrameState; +import jdk.graal.compiler.options.Option; import jdk.vm.ci.code.BytecodeFrame; import jdk.vm.ci.code.DebugInfo; import jdk.vm.ci.code.RegisterValue; @@ -159,9 +159,17 @@ static class IPData { private NonmovableArray referenceMapEncoding; public CodeInfoEncoder(FrameInfoEncoder.Customization frameInfoCustomization, Encoders encoders) { + this(frameInfoCustomization, encoders, FrameInfoDecoder.SubstrateConstantAccess); + } + + public CodeInfoEncoder(FrameInfoEncoder.Customization frameInfoCustomization, Encoders encoders, ConstantAccess constantAccess) { this.entries = new TreeMap<>(); this.encoders = encoders; - this.frameInfoEncoder = new FrameInfoEncoder(frameInfoCustomization, encoders); + this.frameInfoEncoder = new FrameInfoEncoder(frameInfoCustomization, encoders, constantAccess); + } + + public FrameInfoEncoder getFrameInfoEncoder() { + return frameInfoEncoder; } public Encoders getEncoders() { @@ -458,8 +466,9 @@ private static void writeEncodedFrameInfo(UnsafeArrayTypeWriter writeBuffer, IPD } } - public static boolean verifyMethod(SharedMethod method, CompilationResult compilation, int compilationOffset, int compilationSize, CodeInfo info) { - CodeInfoVerifier.verifyMethod(method, compilation, compilationOffset, compilationSize, info); + public static boolean verifyMethod(SharedMethod method, CompilationResult compilation, int compilationOffset, int compilationSize, CodeInfo info, ConstantAccess constantAccess) { + CodeInfoVerifier verifier = new CodeInfoVerifier(constantAccess); + verifier.verifyMethod(method, compilation, compilationOffset, compilationSize, info); return true; } @@ -470,11 +479,17 @@ public boolean verifyFrameInfo(CodeInfo info) { } class CodeInfoVerifier { - static void verifyMethod(SharedMethod method, CompilationResult compilation, int compilationOffset, int compilationSize, CodeInfo info) { + private final ConstantAccess constantAccess; + + CodeInfoVerifier(ConstantAccess constantAccess) { + this.constantAccess = constantAccess; + } + + void verifyMethod(SharedMethod method, CompilationResult compilation, int compilationOffset, int compilationSize, CodeInfo info) { CodeInfoQueryResult queryResult = new CodeInfoQueryResult(); for (int relativeIP = 0; relativeIP < compilationSize; relativeIP++) { int totalIP = relativeIP + compilationOffset; - CodeInfoAccess.lookupCodeInfo(info, totalIP, queryResult); + CodeInfoAccess.lookupCodeInfo(info, totalIP, queryResult, constantAccess); assert queryResult.isEntryPoint() == method.isEntryPoint() : queryResult; assert queryResult.hasCalleeSavedRegisters() == method.hasCalleeSavedRegisters() : queryResult; assert queryResult.getTotalFrameSize() == compilation.getTotalFrameSize() : queryResult; @@ -487,7 +502,7 @@ static void verifyMethod(SharedMethod method, CompilationResult compilation, int int offset = CodeInfoEncoder.getEntryOffset(infopoint); if (offset >= 0) { assert offset < compilationSize : infopoint; - CodeInfoAccess.lookupCodeInfo(info, offset + compilationOffset, queryResult); + CodeInfoAccess.lookupCodeInfo(info, offset + compilationOffset, queryResult, constantAccess); CollectingObjectReferenceVisitor visitor = new CollectingObjectReferenceVisitor(); CodeReferenceMapDecoder.walkOffsetsFromPointer(WordFactory.zero(), CodeInfoAccess.getStackReferenceMapEncoding(info), queryResult.getReferenceMapIndex(), visitor, null); @@ -506,7 +521,7 @@ static void verifyMethod(SharedMethod method, CompilationResult compilation, int int offset = handler.pcOffset; assert offset >= 0 && offset < compilationSize : handler; - CodeInfoAccess.lookupCodeInfo(info, offset + compilationOffset, queryResult); + CodeInfoAccess.lookupCodeInfo(info, offset + compilationOffset, queryResult, constantAccess); long actual = queryResult.getExceptionOffset(); long expected = handler.handlerPos - handler.pcOffset; assert expected != 0 : handler; @@ -514,7 +529,7 @@ static void verifyMethod(SharedMethod method, CompilationResult compilation, int } } - private static void verifyFrame(CompilationResult compilation, BytecodeFrame expectedFrame, FrameInfoQueryResult actualFrame, BitSet visitedVirtualObjects) { + private void verifyFrame(CompilationResult compilation, BytecodeFrame expectedFrame, FrameInfoQueryResult actualFrame, BitSet visitedVirtualObjects) { assert (expectedFrame == null) == (actualFrame == null) : actualFrame; if (expectedFrame == null || !actualFrame.hasLocalValueInfo()) { return; @@ -536,7 +551,7 @@ private static void verifyFrame(CompilationResult compilation, BytecodeFrame exp } } - private static void verifyValue(CompilationResult compilation, JavaValue e, ValueInfo actualValue, FrameInfoQueryResult actualFrame, BitSet visitedVirtualObjects) { + private void verifyValue(CompilationResult compilation, JavaValue e, ValueInfo actualValue, FrameInfoQueryResult actualFrame, BitSet visitedVirtualObjects) { JavaValue expectedValue = e; if (expectedValue instanceof StackLockValue) { @@ -589,7 +604,7 @@ private static void verifyValue(CompilationResult compilation, JavaValue e, Valu } } - private static void verifyVirtualObject(CompilationResult compilation, VirtualObject expectedObject, ValueInfo[] actualObject, FrameInfoQueryResult actualFrame, BitSet visitedVirtualObjects) { + private void verifyVirtualObject(CompilationResult compilation, VirtualObject expectedObject, ValueInfo[] actualObject, FrameInfoQueryResult actualFrame, BitSet visitedVirtualObjects) { if (visitedVirtualObjects.get(expectedObject.getId())) { return; } @@ -656,15 +671,15 @@ private static void verifyVirtualObject(CompilationResult compilation, VirtualOb } } - private static ValueInfo findActualArrayElement(ValueInfo[] actualObject, UnsignedWord expectedOffset) { - DynamicHub hub = (DynamicHub) SubstrateObjectConstant.asObject(actualObject[0].getValue()); + private ValueInfo findActualArrayElement(ValueInfo[] actualObject, UnsignedWord expectedOffset) { + DynamicHub hub = (DynamicHub) constantAccess.asObject(actualObject[0].getValue()); ObjectLayout objectLayout = ConfigurationValues.getObjectLayout(); assert LayoutEncoding.isArray(hub.getLayoutEncoding()) : hub; return findActualValue(actualObject, expectedOffset, objectLayout, LayoutEncoding.getArrayBaseOffset(hub.getLayoutEncoding()), 2); } - private static ValueInfo findActualField(ValueInfo[] actualObject, UnsignedWord expectedOffset) { - DynamicHub hub = (DynamicHub) SubstrateObjectConstant.asObject(actualObject[0].getValue()); + private ValueInfo findActualField(ValueInfo[] actualObject, UnsignedWord expectedOffset) { + DynamicHub hub = (DynamicHub) constantAccess.asObject(actualObject[0].getValue()); ObjectLayout objectLayout = ConfigurationValues.getObjectLayout(); assert LayoutEncoding.isPureInstance(hub.getLayoutEncoding()) : hub; return findActualValue(actualObject, expectedOffset, objectLayout, WordFactory.unsigned(objectLayout.getFirstFieldOffset()), 1); diff --git a/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/code/CodeInfoTable.java b/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/code/CodeInfoTable.java index de6af4e6540a..87b821c755d9 100644 --- a/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/code/CodeInfoTable.java +++ b/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/code/CodeInfoTable.java @@ -29,8 +29,6 @@ import java.util.Arrays; import java.util.List; -import jdk.graal.compiler.api.replacements.Fold; -import jdk.graal.compiler.options.Option; import org.graalvm.nativeimage.ImageSingletons; import org.graalvm.nativeimage.c.function.CodePointer; import org.graalvm.nativeimage.hosted.Feature; @@ -59,6 +57,8 @@ import com.oracle.svm.core.util.CounterFeature; import com.oracle.svm.core.util.VMError; +import jdk.graal.compiler.api.replacements.Fold; +import jdk.graal.compiler.options.Option; import jdk.vm.ci.code.InstalledCode; /** @@ -118,7 +118,7 @@ public static CodeInfoQueryResult lookupDeoptimizationEntrypoint(int deoptOffset /* Deoptimization entry points are always in the image, i.e., never compiled at run time. */ CodeInfo info = getImageCodeInfo(); CodeInfoQueryResult result = new CodeInfoQueryResult(); - long relativeIP = CodeInfoAccess.lookupDeoptimizationEntrypoint(info, deoptOffsetInImage, encodedBci, result); + long relativeIP = CodeInfoAccess.lookupDeoptimizationEntrypoint(info, deoptOffsetInImage, encodedBci, result, FrameInfoDecoder.SubstrateConstantAccess); if (relativeIP < 0) { return null; } diff --git a/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/code/FrameInfoDecoder.java b/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/code/FrameInfoDecoder.java index 1a20fbc4bbc3..9635ce183f0d 100644 --- a/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/code/FrameInfoDecoder.java +++ b/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/code/FrameInfoDecoder.java @@ -28,9 +28,6 @@ import java.util.Arrays; -import jdk.graal.compiler.core.common.util.TypeConversion; -import jdk.graal.compiler.nodes.FrameState; - import com.oracle.svm.core.Uninterruptible; import com.oracle.svm.core.c.NonmovableArray; import com.oracle.svm.core.c.NonmovableArrays; @@ -46,6 +43,8 @@ import com.oracle.svm.core.util.NonmovableByteArrayTypeReader; import com.oracle.svm.core.util.VMError; +import jdk.graal.compiler.core.common.util.TypeConversion; +import jdk.graal.compiler.nodes.FrameState; import jdk.vm.ci.code.BytecodeFrame; import jdk.vm.ci.meta.JavaConstant; import jdk.vm.ci.meta.JavaKind; @@ -125,6 +124,18 @@ public FrameInfoQueryResult newFrameInfoQueryResult() { } } + public static final ConstantAccess SubstrateConstantAccess = new ConstantAccess(); + + public static class ConstantAccess { + public JavaConstant forObject(Object object, boolean isCompressedReference) { + return SubstrateObjectConstant.forObject(object, isCompressedReference); + } + + public Object asObject(JavaConstant constant) { + return SubstrateObjectConstant.asObject(constant); + } + } + static final HeapBasedFrameInfoQueryResultAllocator HeapBasedFrameInfoQueryResultAllocator = new HeapBasedFrameInfoQueryResultAllocator(); public interface ValueInfoAllocator { @@ -134,7 +145,7 @@ public interface ValueInfoAllocator { ValueInfo[][] newValueInfoArrayArray(int len); - void decodeConstant(ValueInfo valueInfo, NonmovableObjectArray frameInfoObjectConstants); + void decodeConstant(ValueInfo valueInfo, NonmovableObjectArray frameInfoObjectConstants, ConstantAccess constantAccess); } static class HeapBasedValueInfoAllocator implements ValueInfoAllocator { @@ -158,12 +169,12 @@ public ValueInfo[][] newValueInfoArrayArray(int len) { @Override @RestrictHeapAccess(reason = "Whitelisted because some implementations can allocate.", access = RestrictHeapAccess.Access.UNRESTRICTED) - public void decodeConstant(ValueInfo valueInfo, NonmovableObjectArray frameInfoObjectConstants) { + public void decodeConstant(ValueInfo valueInfo, NonmovableObjectArray frameInfoObjectConstants, ConstantAccess constantAccess) { switch (valueInfo.type) { case DefaultConstant: switch (valueInfo.kind) { case Object: - valueInfo.value = SubstrateObjectConstant.forObject(null, valueInfo.isCompressedReference); + valueInfo.value = constantAccess.forObject(null, valueInfo.isCompressedReference); assert valueInfo.value.isDefaultForKind() : valueInfo; break; default: @@ -173,7 +184,7 @@ public void decodeConstant(ValueInfo valueInfo, NonmovableObjectArray frameIn case Constant: switch (valueInfo.kind) { case Object: - valueInfo.value = SubstrateObjectConstant.forObject(NonmovableArrays.getObject(frameInfoObjectConstants, TypeConversion.asS4(valueInfo.data)), + valueInfo.value = constantAccess.forObject(NonmovableArrays.getObject(frameInfoObjectConstants, TypeConversion.asS4(valueInfo.data)), valueInfo.isCompressedReference); break; case Float: @@ -264,12 +275,17 @@ private static int decodeSourceLineNumber(int sourceLineNumber) { } protected static FrameInfoQueryResult decodeFrameInfo(boolean isDeoptEntry, ReusableTypeReader readBuffer, CodeInfo info) { - return decodeFrameInfo(isDeoptEntry, readBuffer, info, FrameInfoDecoder.HeapBasedFrameInfoQueryResultAllocator, FrameInfoDecoder.HeapBasedValueInfoAllocator, new FrameInfoState()); + return decodeFrameInfo(isDeoptEntry, readBuffer, info, FrameInfoDecoder.SubstrateConstantAccess); + } + + protected static FrameInfoQueryResult decodeFrameInfo(boolean isDeoptEntry, ReusableTypeReader readBuffer, CodeInfo info, ConstantAccess constantAccess) { + return decodeFrameInfo(isDeoptEntry, readBuffer, info, FrameInfoDecoder.HeapBasedFrameInfoQueryResultAllocator, FrameInfoDecoder.HeapBasedValueInfoAllocator, + constantAccess, new FrameInfoState()); } @Uninterruptible(reason = "Called from uninterruptible code.", mayBeInlined = true) protected static FrameInfoQueryResult decodeFrameInfo(boolean isDeoptEntry, ReusableTypeReader readBuffer, CodeInfo info, - FrameInfoQueryResultAllocator resultAllocator, ValueInfoAllocator valueInfoAllocator, FrameInfoState state) { + FrameInfoQueryResultAllocator resultAllocator, ValueInfoAllocator valueInfoAllocator, ConstantAccess constantAccess, FrameInfoState state) { if (state.isFirstFrame) { state.firstValue = readBuffer.getSVInt(); } @@ -278,7 +294,7 @@ protected static FrameInfoQueryResult decodeFrameInfo(boolean isDeoptEntry, Reus if (CompressedFrameDecoderHelper.isCompressedFrameSlice(state.firstValue)) { result = decodeCompressedFrameInfo(isDeoptEntry, readBuffer, info, resultAllocator, state); } else { - result = decodeUncompressedFrameInfo(isDeoptEntry, readBuffer, info, resultAllocator, valueInfoAllocator, state); + result = decodeUncompressedFrameInfo(isDeoptEntry, readBuffer, info, resultAllocator, valueInfoAllocator, constantAccess, state); } state.isFirstFrame = false; @@ -392,7 +408,7 @@ private static void decodeCompressedFrameData(ReusableTypeReader readBuffer, Cod @Uninterruptible(reason = "Called from uninterruptible code.", mayBeInlined = true) private static FrameInfoQueryResult decodeUncompressedFrameInfo(boolean isDeoptEntry, ReusableTypeReader readBuffer, CodeInfo info, - FrameInfoQueryResultAllocator resultAllocator, ValueInfoAllocator valueInfoAllocator, FrameInfoState state) { + FrameInfoQueryResultAllocator resultAllocator, ValueInfoAllocator valueInfoAllocator, ConstantAccess constantAccess, FrameInfoState state) { FrameInfoQueryResult result = null; FrameInfoQueryResult prev = null; ValueInfo[][] virtualObjects = null; @@ -436,7 +452,7 @@ private static FrameInfoQueryResult decodeUncompressedFrameInfo(boolean isDeoptE } int curValueInfosLength = readBuffer.getUVInt(); - cur.valueInfos = decodeValues(valueInfoAllocator, curValueInfosLength, readBuffer, CodeInfoAccess.getFrameInfoObjectConstants(info)); + cur.valueInfos = decodeValues(valueInfoAllocator, constantAccess, curValueInfosLength, readBuffer, CodeInfoAccess.getFrameInfoObjectConstants(info)); if (state.isFirstFrame) { /* This is the first frame, i.e., the top frame that will be returned. */ @@ -444,7 +460,7 @@ private static FrameInfoQueryResult decodeUncompressedFrameInfo(boolean isDeoptE virtualObjects = newValueInfoArrayArray(valueInfoAllocator, numVirtualObjects); for (int i = 0; i < numVirtualObjects; i++) { int numValues = readBuffer.getUVInt(); - ValueInfo[] decodedValues = decodeValues(valueInfoAllocator, numValues, readBuffer, CodeInfoAccess.getFrameInfoObjectConstants(info)); + ValueInfo[] decodedValues = decodeValues(valueInfoAllocator, constantAccess, numValues, readBuffer, CodeInfoAccess.getFrameInfoObjectConstants(info)); if (virtualObjects != null) { virtualObjects[i] = decodedValues; } @@ -485,7 +501,8 @@ private static ValueInfo[][] newValueInfoArrayArray(ValueInfoAllocator valueInfo } @Uninterruptible(reason = "Called from uninterruptible code.", mayBeInlined = true) - private static ValueInfo[] decodeValues(ValueInfoAllocator valueInfoAllocator, int numValues, ReusableTypeReader readBuffer, NonmovableObjectArray frameInfoObjectConstants) { + private static ValueInfo[] decodeValues(ValueInfoAllocator valueInfoAllocator, ConstantAccess constantAccess, int numValues, ReusableTypeReader readBuffer, + NonmovableObjectArray frameInfoObjectConstants) { ValueInfo[] valueInfos = newValueInfoArray(valueInfoAllocator, numValues); for (int i = 0; i < numValues; i++) { @@ -508,14 +525,14 @@ private static ValueInfo[] decodeValues(ValueInfoAllocator valueInfoAllocator, i valueInfo.data = valueInfoData; } } - decodeConstant(valueInfoAllocator, frameInfoObjectConstants, valueInfo); + decodeConstant(valueInfoAllocator, constantAccess, frameInfoObjectConstants, valueInfo); } return valueInfos; } @Uninterruptible(reason = "Some allocators are interruptible.", calleeMustBe = false) - private static void decodeConstant(ValueInfoAllocator valueInfoAllocator, NonmovableObjectArray frameInfoObjectConstants, ValueInfo valueInfo) { - valueInfoAllocator.decodeConstant(valueInfo, frameInfoObjectConstants); + private static void decodeConstant(ValueInfoAllocator valueInfoAllocator, ConstantAccess constantAccess, NonmovableObjectArray frameInfoObjectConstants, ValueInfo valueInfo) { + valueInfoAllocator.decodeConstant(valueInfo, frameInfoObjectConstants, constantAccess); } @Uninterruptible(reason = "Some allocators are interruptible.", calleeMustBe = false) diff --git a/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/code/FrameInfoEncoder.java b/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/code/FrameInfoEncoder.java index f5cff698a694..5e06b89ba6ca 100644 --- a/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/code/FrameInfoEncoder.java +++ b/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/code/FrameInfoEncoder.java @@ -38,14 +38,6 @@ import org.graalvm.collections.EconomicMap; import org.graalvm.collections.Equivalence; -import jdk.graal.compiler.code.CompilationResult; -import jdk.graal.compiler.core.common.LIRKind; -import jdk.graal.compiler.core.common.NumUtil; -import jdk.graal.compiler.core.common.type.CompressibleConstant; -import jdk.graal.compiler.core.common.util.FrequencyEncoder; -import jdk.graal.compiler.core.common.util.TypeConversion; -import jdk.graal.compiler.core.common.util.UnsafeArrayTypeWriter; -import jdk.graal.compiler.nodes.FrameState; import org.graalvm.nativeimage.ImageSingletons; import com.oracle.svm.core.CalleeSavedRegisters; @@ -55,6 +47,7 @@ import com.oracle.svm.core.c.NonmovableArrays; import com.oracle.svm.core.code.CodeInfoEncoder.Counters; import com.oracle.svm.core.code.CodeInfoEncoder.Encoders; +import com.oracle.svm.core.code.FrameInfoDecoder.ConstantAccess; import com.oracle.svm.core.code.FrameInfoQueryResult.ValueInfo; import com.oracle.svm.core.code.FrameInfoQueryResult.ValueType; import com.oracle.svm.core.config.ConfigurationValues; @@ -63,13 +56,20 @@ import com.oracle.svm.core.meta.SharedField; import com.oracle.svm.core.meta.SharedMethod; import com.oracle.svm.core.meta.SharedType; -import com.oracle.svm.core.meta.SubstrateObjectConstant; import com.oracle.svm.core.sampler.CallStackFrameMethodData; import com.oracle.svm.core.sampler.CallStackFrameMethodInfo; import com.oracle.svm.core.util.ByteArrayReader; import com.oracle.svm.core.util.HostedStringDeduplication; import com.oracle.svm.core.util.VMError; +import jdk.graal.compiler.code.CompilationResult; +import jdk.graal.compiler.core.common.LIRKind; +import jdk.graal.compiler.core.common.NumUtil; +import jdk.graal.compiler.core.common.type.CompressibleConstant; +import jdk.graal.compiler.core.common.util.FrequencyEncoder; +import jdk.graal.compiler.core.common.util.TypeConversion; +import jdk.graal.compiler.core.common.util.UnsafeArrayTypeWriter; +import jdk.graal.compiler.nodes.FrameState; import jdk.vm.ci.code.BytecodeFrame; import jdk.vm.ci.code.DebugInfo; import jdk.vm.ci.code.Register; @@ -444,14 +444,16 @@ boolean writeFrameVerificationInfo(FrameData data, Encoders encoders) { private final List allDebugInfos; private final Encoders encoders; private final CompressedFrameInfoEncodingMetadata frameMetadata; + private final ConstantAccess constantAccess; private final CalleeSavedRegisters calleeSavedRegisters; - protected FrameInfoEncoder(Customization customization, Encoders encoders) { + protected FrameInfoEncoder(Customization customization, Encoders encoders, ConstantAccess constantAccess) { this.customization = customization; this.encoders = encoders; this.allDebugInfos = new ArrayList<>(); this.frameMetadata = new CompressedFrameInfoEncodingMetadata(); + this.constantAccess = constantAccess; if (CalleeSavedRegisters.supportedByPlatform()) { calleeSavedRegisters = CalleeSavedRegisters.singleton(); @@ -460,6 +462,10 @@ protected FrameInfoEncoder(Customization customization, Encoders encoders) { } } + public ConstantAccess getConstantAccess() { + return constantAccess; + } + protected FrameData addDebugInfo(ResolvedJavaMethod method, CompilationResult compilation, Infopoint infopoint, int totalFrameSize) { boolean isDeoptEntry = customization.isDeoptEntry(method, compilation, infopoint); customization.recordFrame(method, infopoint, isDeoptEntry); @@ -564,7 +570,7 @@ private void initializeFrameInfo(FrameInfoQueryResult frameInfo, FrameData data, if (needLocalValues) { if (customization.storeDeoptTargetMethod()) { frameInfo.deoptMethod = method; - encoders.objectConstants.addObject(SubstrateObjectConstant.forObject(method)); + encoders.objectConstants.addObject(constantAccess.forObject(method, false)); } frameInfo.deoptMethodOffset = method.getDeoptOffsetInImage(); @@ -714,7 +720,7 @@ private void makeVirtualObject(FrameData data, VirtualObject virtualObject, bool ArrayList valueList = new ArrayList<>(virtualObject.getValues().length + 4); SharedType type = (SharedType) virtualObject.getType(); /* The first element is the hub of the virtual object. */ - valueList.add(makeValueInfo(data, JavaKind.Object, SubstrateObjectConstant.forObject(type.getHub()), isDeoptEntry)); + valueList.add(makeValueInfo(data, JavaKind.Object, constantAccess.forObject(type.getHub(), false), isDeoptEntry)); ObjectLayout objectLayout = ConfigurationValues.getObjectLayout(); assert type.isArray() == LayoutEncoding.isArray(type.getHub().getLayoutEncoding()) : "deoptimization code uses layout encoding to determine if type is an array"; @@ -923,7 +929,7 @@ private void encodeUncompressedFrameData(FrameData data, UnsafeArrayTypeWriter e int deoptMethodIndex; if (cur.deoptMethod != null) { - deoptMethodIndex = -1 - encoders.objectConstants.getIndex(SubstrateObjectConstant.forObject(cur.deoptMethod)); + deoptMethodIndex = -1 - encoders.objectConstants.getIndex(constantAccess.forObject(cur.deoptMethod, false)); assert deoptMethodIndex < 0 : cur; assert cur.getDeoptMethodOffset() == cur.deoptMethod.getDeoptOffsetInImage() : cur; } else { @@ -1046,7 +1052,7 @@ private static int encodeCompressedSourceLineNumber(int sourceLineNumber, boolea void verifyEncoding(CodeInfo info) { for (FrameData expectedData : allDebugInfos) { ReusableTypeReader reader = new ReusableTypeReader(CodeInfoAccess.getFrameInfoEncodings(info), expectedData.encodedFrameInfoIndex); - FrameInfoQueryResult actualFrame = FrameInfoDecoder.decodeFrameInfo(expectedData.frame.isDeoptEntry, reader, info); + FrameInfoQueryResult actualFrame = FrameInfoDecoder.decodeFrameInfo(expectedData.frame.isDeoptEntry, reader, info, constantAccess); FrameInfoVerifier.verifyFrames(expectedData, expectedData.frame, actualFrame); } } diff --git a/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/graal/code/SubstrateDebugInfoBuilder.java b/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/graal/code/SubstrateDebugInfoBuilder.java index 4c9057f1103f..9a7283bd1fed 100644 --- a/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/graal/code/SubstrateDebugInfoBuilder.java +++ b/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/graal/code/SubstrateDebugInfoBuilder.java @@ -24,21 +24,17 @@ */ package com.oracle.svm.core.graal.code; -import jdk.graal.compiler.api.replacements.SnippetReflectionProvider; +import com.oracle.svm.core.meta.SharedMethod; +import com.oracle.svm.core.meta.SharedType; +import com.oracle.svm.core.util.VMError; + import jdk.graal.compiler.core.common.spi.MetaAccessExtensionProvider; import jdk.graal.compiler.core.gen.DebugInfoBuilder; import jdk.graal.compiler.nodes.FrameState; import jdk.graal.compiler.nodes.StructuredGraph; -import jdk.graal.compiler.nodes.ValueNode; import jdk.graal.compiler.nodes.spi.NodeValueMap; - -import com.oracle.svm.core.meta.SharedMethod; -import com.oracle.svm.core.meta.SharedType; -import com.oracle.svm.core.util.VMError; - import jdk.vm.ci.code.StackLockValue; import jdk.vm.ci.code.VirtualObject; -import jdk.vm.ci.meta.JavaConstant; import jdk.vm.ci.meta.JavaKind; import jdk.vm.ci.meta.JavaType; import jdk.vm.ci.meta.JavaValue; @@ -47,12 +43,10 @@ public final class SubstrateDebugInfoBuilder extends DebugInfoBuilder { private final SharedMethod method; - private final SnippetReflectionProvider snippetReflection; - public SubstrateDebugInfoBuilder(StructuredGraph graph, SnippetReflectionProvider snippetReflection, MetaAccessExtensionProvider metaAccessExtensionProvider, NodeValueMap nodeValueMap) { + public SubstrateDebugInfoBuilder(StructuredGraph graph, MetaAccessExtensionProvider metaAccessExtensionProvider, NodeValueMap nodeValueMap) { super(nodeValueMap, metaAccessExtensionProvider, graph.getDebug()); this.method = (SharedMethod) graph.method(); - this.snippetReflection = snippetReflection; } @Override @@ -60,15 +54,6 @@ protected JavaKind storageKind(JavaType type) { return ((SharedType) type).getStorageKind(); } - @Override - protected JavaValue toJavaValue(ValueNode valueNode) { - JavaValue value = super.toJavaValue(valueNode); - if (value instanceof JavaConstant constant) { - return snippetReflection.unwrapConstant(constant); - } - return value; - } - @Override protected JavaValue computeLockValue(FrameState state, int lockIndex) { JavaValue object = toJavaValue(state.lockAt(lockIndex)); diff --git a/substratevm/src/com.oracle.svm.graal/src/com/oracle/svm/graal/hosted/GraalGraphObjectReplacer.java b/substratevm/src/com.oracle.svm.graal/src/com/oracle/svm/graal/hosted/GraalGraphObjectReplacer.java index a630ab7bb8d4..a9e45602485b 100644 --- a/substratevm/src/com.oracle.svm.graal/src/com/oracle/svm/graal/hosted/GraalGraphObjectReplacer.java +++ b/substratevm/src/com.oracle.svm.graal/src/com/oracle/svm/graal/hosted/GraalGraphObjectReplacer.java @@ -45,8 +45,8 @@ import com.oracle.svm.core.util.HostedStringDeduplication; import com.oracle.svm.core.util.ObservableImageHeapMapProvider; import com.oracle.svm.core.util.VMError; -import com.oracle.svm.graal.TruffleRuntimeCompilationSupport; import com.oracle.svm.graal.SubstrateGraalRuntime; +import com.oracle.svm.graal.TruffleRuntimeCompilationSupport; import com.oracle.svm.graal.meta.SubstrateField; import com.oracle.svm.graal.meta.SubstrateMethod; import com.oracle.svm.graal.meta.SubstrateSignature; @@ -460,11 +460,19 @@ public void updateSubstrateDataAfterCompilation(HostedUniverse hUniverse, Provid JavaConstant constantValue = hField.isStatic() && ((HostedConstantFieldProvider) providers.getConstantFieldProvider()).isFinalField(hField, null) ? providers.getConstantReflection().readFieldValue(hField, null) : null; - constantValue = providers.getSnippetReflection().unwrapConstant(constantValue); + constantValue = unwrapConstant(constantValue); sField.setSubstrateData(hField.getLocation(), hField.isAccessed(), hField.isWritten() || !hField.isValueAvailable(), constantValue); } } + static JavaConstant unwrapConstant(JavaConstant constant) { + if (constant instanceof ImageHeapConstant heapConstant) { + VMError.guarantee(heapConstant.isBackedByHostedObject(), "Expected to find a heap object backed by a hosted object, found %s", heapConstant); + return heapConstant.getHostedObject(); + } + return constant; + } + public void updateSubstrateDataAfterHeapLayout(HostedUniverse hUniverse) { for (Map.Entry entry : methods.entrySet()) { AnalysisMethod aMethod = entry.getKey(); diff --git a/substratevm/src/com.oracle.svm.graal/src/com/oracle/svm/graal/meta/RuntimeCodeInstaller.java b/substratevm/src/com.oracle.svm.graal/src/com/oracle/svm/graal/meta/RuntimeCodeInstaller.java index 0804bd248381..3a0f1a133461 100644 --- a/substratevm/src/com.oracle.svm.graal/src/com/oracle/svm/graal/meta/RuntimeCodeInstaller.java +++ b/substratevm/src/com.oracle.svm.graal/src/com/oracle/svm/graal/meta/RuntimeCodeInstaller.java @@ -29,13 +29,6 @@ import java.util.HashSet; import java.util.Map; -import jdk.graal.compiler.code.CompilationResult; -import jdk.graal.compiler.code.CompilationResult.CodeAnnotation; -import jdk.graal.compiler.core.common.NumUtil; -import jdk.graal.compiler.core.common.type.CompressibleConstant; -import jdk.graal.compiler.debug.DebugContext; -import jdk.graal.compiler.debug.Indent; -import jdk.graal.compiler.truffle.TruffleCompilerImpl; import org.graalvm.nativeimage.ImageSingletons; import org.graalvm.nativeimage.c.type.CTypeConversion; import org.graalvm.word.Pointer; @@ -50,6 +43,7 @@ import com.oracle.svm.core.code.CodeInfoAccess; import com.oracle.svm.core.code.CodeInfoEncoder; import com.oracle.svm.core.code.DeoptimizationSourcePositionEncoder; +import com.oracle.svm.core.code.FrameInfoDecoder; import com.oracle.svm.core.code.FrameInfoEncoder; import com.oracle.svm.core.code.InstalledCodeObserver; import com.oracle.svm.core.code.InstalledCodeObserver.InstalledCodeObserverHandle; @@ -74,6 +68,13 @@ import com.oracle.svm.core.util.UnsignedUtils; import com.oracle.svm.core.util.VMError; +import jdk.graal.compiler.code.CompilationResult; +import jdk.graal.compiler.code.CompilationResult.CodeAnnotation; +import jdk.graal.compiler.core.common.NumUtil; +import jdk.graal.compiler.core.common.type.CompressibleConstant; +import jdk.graal.compiler.debug.DebugContext; +import jdk.graal.compiler.debug.Indent; +import jdk.graal.compiler.truffle.TruffleCompilerImpl; import jdk.vm.ci.code.TargetDescription; import jdk.vm.ci.code.site.Call; import jdk.vm.ci.code.site.ConstantReference; @@ -269,7 +270,7 @@ private void createCodeChunkInfos(CodeInfo runtimeMethodInfo, ReferenceAdjuster codeInfoEncoder.addMethod(method, compilation, 0, compilation.getTargetCodeSize()); codeInfoEncoder.encodeAllAndInstall(runtimeMethodInfo, adjuster); - assert !adjuster.isFinished() || CodeInfoEncoder.verifyMethod(method, compilation, 0, compilation.getTargetCodeSize(), runtimeMethodInfo); + assert !adjuster.isFinished() || CodeInfoEncoder.verifyMethod(method, compilation, 0, compilation.getTargetCodeSize(), runtimeMethodInfo, FrameInfoDecoder.SubstrateConstantAccess); assert !adjuster.isFinished() || codeInfoEncoder.verifyFrameInfo(runtimeMethodInfo); DeoptimizationSourcePositionEncoder sourcePositionEncoder = new DeoptimizationSourcePositionEncoder(); diff --git a/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/annotation/AnnotationExceptionProxyValue.java b/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/annotation/AnnotationExceptionProxyValue.java index 9cabd2355d21..69131fea0d66 100644 --- a/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/annotation/AnnotationExceptionProxyValue.java +++ b/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/annotation/AnnotationExceptionProxyValue.java @@ -63,7 +63,7 @@ public List> getTypes() { @Override public List getExceptionProxies(SnippetReflectionProvider snippetReflection) { if (objectConstant == null) { - objectConstant = snippetReflection.unwrapConstant(snippetReflection.forObject(exceptionProxy)); + objectConstant = snippetReflection.forObject(exceptionProxy); } return Collections.singletonList(objectConstant); } diff --git a/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/image/NativeImageCodeCache.java b/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/image/NativeImageCodeCache.java index 2dc425594da7..25ec320949e5 100644 --- a/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/image/NativeImageCodeCache.java +++ b/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/image/NativeImageCodeCache.java @@ -48,13 +48,7 @@ import java.util.Set; import java.util.stream.Collectors; -import com.oracle.svm.hosted.DeadlockWatchdog; import org.graalvm.collections.Pair; -import jdk.graal.compiler.api.replacements.SnippetReflectionProvider; -import jdk.graal.compiler.code.CompilationResult; -import jdk.graal.compiler.code.DataSection; -import jdk.graal.compiler.debug.DebugContext; -import jdk.graal.compiler.options.Option; import org.graalvm.nativeimage.ImageSingletons; import org.graalvm.nativeimage.Platform; import org.graalvm.nativeimage.c.function.CFunctionPointer; @@ -77,6 +71,7 @@ import com.oracle.svm.core.code.CodeInfoQueryResult; import com.oracle.svm.core.code.CodeInfoTable; import com.oracle.svm.core.code.FrameInfoDecoder; +import com.oracle.svm.core.code.FrameInfoDecoder.ConstantAccess; import com.oracle.svm.core.code.FrameInfoEncoder; import com.oracle.svm.core.code.FrameInfoQueryResult; import com.oracle.svm.core.code.ImageCodeInfo.HostedImageCodeInfo; @@ -90,6 +85,7 @@ import com.oracle.svm.core.reflect.target.EncodedReflectionMetadataSupplier; import com.oracle.svm.core.util.Counter; import com.oracle.svm.core.util.VMError; +import com.oracle.svm.hosted.DeadlockWatchdog; import com.oracle.svm.hosted.NativeImageOptions; import com.oracle.svm.hosted.code.DeoptimizationUtils; import com.oracle.svm.hosted.code.HostedImageHeapConstantPatch; @@ -104,6 +100,12 @@ import com.oracle.svm.hosted.reflect.ReflectionHostedSupport; import com.oracle.svm.util.ReflectionUtil; +import jdk.graal.compiler.api.replacements.SnippetReflectionProvider; +import jdk.graal.compiler.code.CompilationResult; +import jdk.graal.compiler.code.DataSection; +import jdk.graal.compiler.core.common.type.CompressibleConstant; +import jdk.graal.compiler.debug.DebugContext; +import jdk.graal.compiler.options.Option; import jdk.vm.ci.code.BytecodeFrame; import jdk.vm.ci.code.site.Call; import jdk.vm.ci.code.site.ConstantReference; @@ -266,11 +268,34 @@ public void buildRuntimeMetadata(DebugContext debug, SnippetReflectionProvider s buildRuntimeMetadata(debug, snippetReflectionProvider, new MethodPointer(getFirstCompilation().getLeft(), true), WordFactory.signed(getCodeAreaSize())); } + static class HostedConstantAccess extends ConstantAccess { + private final SnippetReflectionProvider snippetReflection; + + HostedConstantAccess(SnippetReflectionProvider snippetReflection) { + this.snippetReflection = snippetReflection; + } + + @Override + public JavaConstant forObject(Object object, boolean isCompressedReference) { + JavaConstant constant = snippetReflection.forObject(object); + if (constant instanceof CompressibleConstant compressible && isCompressedReference != compressible.isCompressed()) { + return isCompressedReference ? compressible.compress() : compressible.uncompress(); + } + return constant; + } + + @Override + public Object asObject(JavaConstant constant) { + return snippetReflection.asObject(Object.class, constant); + } + } + protected void buildRuntimeMetadata(DebugContext debug, SnippetReflectionProvider snippetReflection, CFunctionPointer firstMethod, UnsignedWord codeSize) { // Build run-time metadata. HostedFrameInfoCustomization frameInfoCustomization = new HostedFrameInfoCustomization(); CodeInfoEncoder.Encoders encoders = new CodeInfoEncoder.Encoders(); - CodeInfoEncoder codeInfoEncoder = new CodeInfoEncoder(frameInfoCustomization, encoders); + HostedConstantAccess hostedConstantAccess = new HostedConstantAccess(snippetReflection); + CodeInfoEncoder codeInfoEncoder = new CodeInfoEncoder(frameInfoCustomization, encoders, hostedConstantAccess); DeadlockWatchdog watchdog = ImageSingletons.lookup(DeadlockWatchdog.class); for (Pair pair : getOrderedCompilations()) { encodeMethod(codeInfoEncoder, pair); @@ -421,10 +446,10 @@ protected void buildRuntimeMetadata(DebugContext debug, SnippetReflectionProvide * Missing deoptimization entry points lead to hard-to-debug transient failures, so we * want the verification on all the time and not just when assertions are on. */ - verifyDeoptEntries(imageCodeInfo); + verifyDeoptEntries(imageCodeInfo, hostedConstantAccess); } - assert verifyMethods(debug, hUniverse, codeInfoEncoder, imageCodeInfo); + assert verifyMethods(debug, hUniverse, codeInfoEncoder, imageCodeInfo, hostedConstantAccess); } protected HostedImageCodeInfo installCodeInfo(SnippetReflectionProvider snippetReflection, CFunctionPointer firstMethod, UnsignedWord codeSize, CodeInfoEncoder codeInfoEncoder, @@ -446,7 +471,7 @@ protected void encodeMethod(CodeInfoEncoder codeInfoEncoder, Pair>> deoptEntries = new ArrayList<>(SubstrateCompilationDirectives.singleton().getDeoptEntries().entrySet()); deoptEntries.sort(Comparator.comparing(e -> e.getKey().format("%H.%n(%p)"))); @@ -463,7 +488,7 @@ private void verifyDeoptEntries(CodeInfo codeInfo) { sourceFrameInfos.sort(Comparator.comparingLong(Entry::getKey)); for (Entry sourceFrameInfo : sourceFrameInfos) { - hasError = verifyDeoptEntry(codeInfo, method, sourceFrameInfo) || hasError; + hasError = verifyDeoptEntry(codeInfo, method, sourceFrameInfo, constantAccess) || hasError; } } if (hasError) { @@ -471,7 +496,7 @@ private void verifyDeoptEntries(CodeInfo codeInfo) { } } - private static boolean verifyDeoptEntry(CodeInfo codeInfo, HostedMethod method, Entry sourceFrameInfo) { + private static boolean verifyDeoptEntry(CodeInfo codeInfo, HostedMethod method, Entry sourceFrameInfo, ConstantAccess constantAccess) { int deoptOffsetInImage = method.getDeoptOffsetInImage(); long encodedBci = sourceFrameInfo.getKey(); @@ -484,7 +509,7 @@ private static boolean verifyDeoptEntry(CodeInfo codeInfo, HostedMethod method, } CodeInfoQueryResult result = new CodeInfoQueryResult(); - long relativeIP = CodeInfoAccess.lookupDeoptimizationEntrypoint(codeInfo, deoptOffsetInImage, encodedBci, result); + long relativeIP = CodeInfoAccess.lookupDeoptimizationEntrypoint(codeInfo, deoptOffsetInImage, encodedBci, result, constantAccess); if (relativeIP < 0) { return error(method, encodedBci, "entry point not found"); } @@ -567,7 +592,7 @@ private static boolean error(HostedMethod method, long encodedBci, String msg) { return true; } - protected boolean verifyMethods(DebugContext debug, HostedUniverse hUniverse, CodeInfoEncoder codeInfoEncoder, CodeInfo codeInfo) { + protected boolean verifyMethods(DebugContext debug, HostedUniverse hUniverse, CodeInfoEncoder codeInfoEncoder, CodeInfo codeInfo, ConstantAccess constantAccess) { /* * Run method verification in parallel to reduce computation time. */ @@ -578,7 +603,7 @@ protected boolean verifyMethods(DebugContext debug, HostedUniverse hUniverse, Co executor.start(); for (Pair pair : getOrderedCompilations()) { HostedMethod method = pair.getLeft(); - executor.execute(ignore -> CodeInfoEncoder.verifyMethod(method, pair.getRight(), method.getCodeAddressOffset(), codeSizeFor(method), codeInfo)); + executor.execute(ignore -> CodeInfoEncoder.verifyMethod(method, pair.getRight(), method.getCodeAddressOffset(), codeSizeFor(method), codeInfo, constantAccess)); } executor.complete(); } catch (InterruptedException e) { diff --git a/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/image/NativeImageHeap.java b/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/image/NativeImageHeap.java index ae7317b76bec..e8912d28be12 100644 --- a/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/image/NativeImageHeap.java +++ b/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/image/NativeImageHeap.java @@ -163,12 +163,13 @@ public int getObjectCount() { public ObjectInfo getObjectInfo(Object obj) { JavaConstant constant = hUniverse.getSnippetReflection().forObject(obj); - /* Must unwrap since objects use the SubstrateObjectConstant hosted objects as keys. */ - return objects.get(maybeUnwrap(constant)); + VMError.guarantee(constant instanceof ImageHeapConstant, "Expected an ImageHeapConstant, found %s", constant); + return objects.get(uncompress(constant)); } public ObjectInfo getConstantInfo(JavaConstant constant) { - return objects.get(maybeUnwrap(uncompress(constant))); + VMError.guarantee(constant instanceof ImageHeapConstant, "Expected an ImageHeapConstant, found %s", constant); + return objects.get(uncompress(constant)); } protected HybridLayout getHybridLayout(HostedClass clazz) { @@ -351,7 +352,7 @@ public void addConstant(final JavaConstant constant, boolean immutableFromParent handleImageString(stringConstant); } - final ObjectInfo existing = objects.get(maybeUnwrap(uncompressed)); + final ObjectInfo existing = getConstantInfo(uncompressed); if (existing == null) { addObjectToImageHeap(uncompressed, immutableFromParent, identityHashCode, reason); } else if (objectReachabilityInfo != null) { @@ -359,27 +360,13 @@ public void addConstant(final JavaConstant constant, boolean immutableFromParent } } - /** - * When an object is represented as an {@link ImageHeapConstant} we unwrap it before using it as - * a key for {@link NativeImageHeap#objects}. This is necessary to avoid duplication of - * {@link ObjectInfo} for the same object. Eventually, there will be a complete shadow heap with - * only {@link ImageHeapConstant} and this code will be removed. - */ - private static JavaConstant maybeUnwrap(JavaConstant constant) { - if (constant instanceof ImageHeapConstant ihc && ihc.getHostedObject() != null) { - return uncompress(ihc.getHostedObject()); - } - return constant; - } - /** * The constants stored in the image heap, i.g., the {@link #objects} map, are always * uncompressed. The same object info is returned whenever the map is queried regardless of the * compressed flag value. */ private static JavaConstant uncompress(JavaConstant constant) { - if (constant instanceof CompressibleConstant) { - CompressibleConstant compressible = (CompressibleConstant) constant; + if (constant instanceof CompressibleConstant compressible) { if (compressible.isCompressed()) { return compressible.uncompress(); } @@ -388,8 +375,7 @@ private static JavaConstant uncompress(JavaConstant constant) { } private static boolean isCompressed(JavaConstant constant) { - if (constant instanceof CompressibleConstant) { - CompressibleConstant compressible = (CompressibleConstant) constant; + if (constant instanceof CompressibleConstant compressible) { return compressible.isCompressed(); } return false; @@ -647,11 +633,11 @@ private ObjectInfo addToImageHeap(Object object, HostedClass clazz, long size, i } private ObjectInfo addToImageHeap(JavaConstant add, HostedClass clazz, long size, int identityHashCode, Object reason) { - assert !isCompressed(add); + VMError.guarantee(add instanceof ImageHeapConstant, "Expected an ImageHeapConstant, found %s", add); + VMError.guarantee(!isCompressed(add), "Constants added to the image heap must be uncompressed."); ObjectInfo info = new ObjectInfo(add, size, clazz, identityHashCode, reason); - JavaConstant constant = maybeUnwrap(add); - assert !objects.containsKey(constant); - objects.put(constant, info); + ObjectInfo previous = objects.putIfAbsent(add, info); + VMError.guarantee(previous == null, "Found an existing object info associated to constant %s", add); return info; } diff --git a/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/meta/HostedSnippetReflectionProvider.java b/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/meta/HostedSnippetReflectionProvider.java index 1d745dfd0efe..148b70a1b78c 100644 --- a/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/meta/HostedSnippetReflectionProvider.java +++ b/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/meta/HostedSnippetReflectionProvider.java @@ -73,14 +73,6 @@ public JavaConstant forBoxed(JavaKind kind, Object value) { return JavaConstant.forBoxedPrimitive(value); } - @Override - public JavaConstant unwrapConstant(JavaConstant constant) { - if (constant instanceof ImageHeapConstant heapConstant && heapConstant.getHostedObject() != null) { - return heapConstant.getHostedObject(); - } - return constant; - } - @Override public T asObject(Class type, JavaConstant c) { JavaConstant constant = c; diff --git a/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/reflect/ReflectionMetadataEncoderImpl.java b/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/reflect/ReflectionMetadataEncoderImpl.java index 718e85e5d938..91489bb66f24 100644 --- a/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/reflect/ReflectionMetadataEncoderImpl.java +++ b/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/reflect/ReflectionMetadataEncoderImpl.java @@ -66,14 +66,10 @@ import java.util.function.Consumer; import org.graalvm.collections.Pair; -import jdk.graal.compiler.api.replacements.SnippetReflectionProvider; -import jdk.graal.compiler.core.common.util.TypeConversion; -import jdk.graal.compiler.core.common.util.UnsafeArrayTypeWriter; import org.graalvm.nativeimage.AnnotationAccess; import org.graalvm.nativeimage.ImageSingletons; import org.graalvm.nativeimage.impl.RuntimeReflectionSupport; -import com.oracle.graal.pointsto.heap.ImageHeapConstant; import com.oracle.graal.pointsto.infrastructure.WrappedElement; import com.oracle.graal.pointsto.meta.AnalysisField; import com.oracle.graal.pointsto.meta.AnalysisMethod; @@ -102,6 +98,9 @@ import com.oracle.svm.hosted.substitute.DeletedElementException; import com.oracle.svm.util.ReflectionUtil; +import jdk.graal.compiler.api.replacements.SnippetReflectionProvider; +import jdk.graal.compiler.core.common.util.TypeConversion; +import jdk.graal.compiler.core.common.util.UnsafeArrayTypeWriter; import jdk.internal.reflect.Reflection; import jdk.vm.ci.meta.JavaConstant; import jdk.vm.ci.meta.MetaAccessProvider; @@ -282,7 +281,7 @@ public void addClassMetadata(MetaAccessProvider metaAccess, HostedType type, Cla if (signers != null) { signerConstants = new JavaConstant[signers.length]; for (int i = 0; i < signers.length; ++i) { - signerConstants[i] = snippetReflection.unwrapConstant(snippetReflection.forObject(signers[i])); + signerConstants[i] = snippetReflection.forObject(signers[i]); addConstantObject(signerConstants[i]); } } @@ -294,12 +293,11 @@ public void addClassMetadata(MetaAccessProvider metaAccess, HostedType type, Cla } private void addConstantObject(JavaConstant constant) { - assert !(constant instanceof ImageHeapConstant); encoders.objectConstants.addObject(constant); } private void registerError(Throwable error) { - addConstantObject(snippetReflection.unwrapConstant(snippetReflection.forObject(error))); + addConstantObject(snippetReflection.forObject(error)); } private static final Method getEnclosingMethod0 = ReflectionUtil.lookupMethod(Class.class, "getEnclosingMethod0"); @@ -422,7 +420,7 @@ public void addReflectionExecutableMetadata(MetaAccessProvider metaAccess, Hoste ReflectParameterMetadata[] reflectParameters = registerReflectParameters(reflectMethod); JavaConstant accessorConstant = null; if (accessor != null) { - accessorConstant = snippetReflection.unwrapConstant(snippetReflection.forObject(accessor)); + accessorConstant = snippetReflection.forObject(accessor); addConstantObject(accessorConstant); } @@ -458,7 +456,7 @@ public void addHeapAccessibleObjectMetadata(MetaAccessProvider metaAccess, Wrapp AnnotationMemberValue annotationDefault = isMethod ? registerAnnotationDefaultValues((AnalysisMethod) analysisObject) : null; ReflectParameterMetadata[] reflectParameters = isExecutable ? registerReflectParameters((Executable) object) : null; AccessibleObject holder = ReflectionMetadataEncoder.getHolder(object); - JavaConstant heapObjectConstant = snippetReflection.unwrapConstant(snippetReflection.forObject(holder)); + JavaConstant heapObjectConstant = snippetReflection.forObject(holder); addConstantObject(heapObjectConstant); AccessibleObjectMetadata metadata; @@ -534,7 +532,7 @@ private void registerValues(AnnotationMemberValue annotationValue) { encoders.sourceMethodNames.addObject(string); } for (JavaConstant proxy : annotationValue.getExceptionProxies(snippetReflection)) { - addConstantObject(snippetReflection.unwrapConstant(proxy)); + addConstantObject(proxy); } } @@ -743,7 +741,7 @@ public void encodeAllAndInstall() { } private int encodeErrorIndex(Throwable error) { - int index = encoders.objectConstants.getIndex(snippetReflection.unwrapConstant(snippetReflection.forObject(error))); + int index = encoders.objectConstants.getIndex(snippetReflection.forObject(error)); int encodedIndex = FIRST_ERROR_INDEX - index; VMError.guarantee(ReflectionMetadataDecoderImpl.isErrorIndex(encodedIndex)); return encodedIndex;