From 6f58dcb118e011c0266ca69a5ddfb168f1888918 Mon Sep 17 00:00:00 2001 From: Christian Haeubl Date: Mon, 16 Oct 2023 10:04:31 +0200 Subject: [PATCH 01/34] Add stack walking heuristic to Native Image crash log. --- .../oracle/svm/core/SubstrateDiagnostics.java | 42 +++++++++++++++---- 1 file changed, 34 insertions(+), 8 deletions(-) diff --git a/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/SubstrateDiagnostics.java b/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/SubstrateDiagnostics.java index 8abd5b7692ec6..a0840126a6df8 100644 --- a/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/SubstrateDiagnostics.java +++ b/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/SubstrateDiagnostics.java @@ -868,23 +868,49 @@ public void printDiagnostics(Log log, ErrorContext context, int maxDiagnosticLev if (!success && DiagnosticLevel.unsafeOperationsAllowed(maxDiagnosticLevel)) { /* * If the stack pointer is not sufficiently aligned, then we might be in the middle - * of a call (i.e., only the return address and the arguments are on the stack). In - * that case, we can read the return address from the top of the stack, align the - * stack pointer, and start a stack walk in the caller. + * of a call (i.e., only the arguments and the return address are on the stack). */ int expectedStackAlignment = ConfigurationValues.getTarget().stackAlignment; if (sp.unsignedRemainder(expectedStackAlignment).notEqual(0) && sp.unsignedRemainder(ConfigurationValues.getTarget().wordSize).equal(0)) { log.newline(); - log.string("WARNING: stack pointer is NOT aligned to ").signed(expectedStackAlignment).string(" bytes. Starting a stack walk in the most likely caller instead.").newline(); - ip = sp.readWord(0); - sp = sp.add(ConfigurationValues.getTarget().wordSize); - - ThreadStackPrinter.printStacktrace(sp, ip, printVisitors[invocationCount - 1].reset(), log); + // Checkstyle: Allow raw info or warning printing - begin + log.string("Warning: stack pointer is not aligned to ").signed(expectedStackAlignment).string(" bytes.").newline(); + // Checkstyle: Allow raw info or warning printing - end } + + startStackWalkInMostLikelyCaller(log, invocationCount, sp); } log.indent(false); } + + private static void startStackWalkInMostLikelyCaller(Log log, int invocationCount, Pointer originalSp) { + UnsignedWord stackBase = VMThreads.StackBase.get(); + if (stackBase.equal(0)) { + /* We don't know the stack boundaries, so only search within 32 bytes. */ + stackBase = originalSp.add(32); + } + + /* Search until we find a valid return address. We may encounter false-positives. */ + int wordSize = ConfigurationValues.getTarget().wordSize; + Pointer pos = originalSp; + while (pos.belowThan(stackBase)) { + CodePointer possibleIp = pos.readWord(0); + if (pointsIntoNativeImageCode(possibleIp)) { + Pointer sp = pos.add(wordSize); + log.newline(); + log.string("Starting the stack walk in a possible caller:").newline(); + ThreadStackPrinter.printStacktrace(sp, possibleIp, printVisitors[invocationCount - 1].reset(), log); + break; + } + pos = pos.add(wordSize); + } + } + + @Uninterruptible(reason = "Prevent the GC from freeing the CodeInfo.") + private static boolean pointsIntoNativeImageCode(CodePointer possibleIp) { + return CodeInfoTable.lookupCodeInfo(possibleIp).isNonNull(); + } } private static class DumpOtherStackTraces extends DiagnosticThunk { From de1fe97f5d162efcc3073948ec3434e4801f7e1c Mon Sep 17 00:00:00 2001 From: Anas El korchi Date: Fri, 20 Oct 2023 15:02:03 +0100 Subject: [PATCH 02/34] [GS-5266] New dev cycle GraalVM 23.0.3 --- compiler/mx.compiler/suite.py | 4 ++-- espresso/mx.espresso/suite.py | 4 ++-- regex/mx.regex/suite.py | 4 ++-- sdk/mx.sdk/suite.py | 4 ++-- substratevm/mx.substratevm/suite.py | 4 ++-- tools/mx.tools/suite.py | 4 ++-- truffle/external_repos/simplelanguage/pom.xml | 2 +- truffle/external_repos/simplelanguage/sl | 2 +- truffle/external_repos/simpletool/pom.xml | 2 +- truffle/mx.truffle/suite.py | 4 ++-- vm/mx.vm/suite.py | 10 +++++----- wasm/mx.wasm/suite.py | 2 +- 12 files changed, 23 insertions(+), 23 deletions(-) diff --git a/compiler/mx.compiler/suite.py b/compiler/mx.compiler/suite.py index aa0c8be23a45e..d1ab5453108e8 100644 --- a/compiler/mx.compiler/suite.py +++ b/compiler/mx.compiler/suite.py @@ -4,8 +4,8 @@ "sourceinprojectwhitelist" : [], "groupId" : "org.graalvm.compiler", - "version" : "23.0.2", - "release" : True, + "version" : "23.0.3", + "release" : False, "url" : "http://www.graalvm.org/", "developer" : { "name" : "GraalVM Development", diff --git a/espresso/mx.espresso/suite.py b/espresso/mx.espresso/suite.py index 29f4907026da3..ffee0da993090 100644 --- a/espresso/mx.espresso/suite.py +++ b/espresso/mx.espresso/suite.py @@ -23,8 +23,8 @@ suite = { "mxversion": "6.17.0", "name": "espresso", - "version" : "23.0.2", - "release" : True, + "version" : "23.0.3", + "release" : False, "groupId" : "org.graalvm.espresso", "url" : "https://www.graalvm.org/reference-manual/java-on-truffle/", "developer" : { diff --git a/regex/mx.regex/suite.py b/regex/mx.regex/suite.py index 0458eb0248a34..eb6708ef73fb2 100644 --- a/regex/mx.regex/suite.py +++ b/regex/mx.regex/suite.py @@ -43,8 +43,8 @@ "name" : "regex", - "version" : "23.0.2", - "release" : True, + "version" : "23.0.3", + "release" : False, "groupId" : "org.graalvm.regex", "url" : "http://www.graalvm.org/", "developer" : { diff --git a/sdk/mx.sdk/suite.py b/sdk/mx.sdk/suite.py index d03c522ec90ad..e439a961b5395 100644 --- a/sdk/mx.sdk/suite.py +++ b/sdk/mx.sdk/suite.py @@ -41,8 +41,8 @@ suite = { "mxversion": "6.17.0", "name" : "sdk", - "version" : "23.0.2", - "release" : True, + "version" : "23.0.3", + "release" : False, "sourceinprojectwhitelist" : [], "url" : "https://github.com/oracle/graal", "groupId" : "org.graalvm.sdk", diff --git a/substratevm/mx.substratevm/suite.py b/substratevm/mx.substratevm/suite.py index 5f6a716a6573e..23def5c140a9a 100644 --- a/substratevm/mx.substratevm/suite.py +++ b/substratevm/mx.substratevm/suite.py @@ -2,8 +2,8 @@ suite = { "mxversion": "6.17.0", "name": "substratevm", - "version" : "23.0.2", - "release" : True, + "version" : "23.0.3", + "release" : False, "url" : "https://github.com/oracle/graal/tree/master/substratevm", "groupId" : "org.graalvm.nativeimage", diff --git a/tools/mx.tools/suite.py b/tools/mx.tools/suite.py index ca54994acd706..ccf357c06f191 100644 --- a/tools/mx.tools/suite.py +++ b/tools/mx.tools/suite.py @@ -26,8 +26,8 @@ "defaultLicense" : "GPLv2-CPE", "groupId" : "org.graalvm.tools", - "version" : "23.0.2", - "release" : True, + "version" : "23.0.3", + "release" : False, "url" : "http://openjdk.java.net/projects/graal", "developer" : { "name" : "GraalVM Development", diff --git a/truffle/external_repos/simplelanguage/pom.xml b/truffle/external_repos/simplelanguage/pom.xml index f69af02232338..00435368d5de0 100644 --- a/truffle/external_repos/simplelanguage/pom.xml +++ b/truffle/external_repos/simplelanguage/pom.xml @@ -48,7 +48,7 @@ UTF-8 jdt_apt - 23.0.2-dev + 23.0.3-dev 11 11 diff --git a/truffle/external_repos/simplelanguage/sl b/truffle/external_repos/simplelanguage/sl index 285dd3f401689..c9f8cb3fab34d 100755 --- a/truffle/external_repos/simplelanguage/sl +++ b/truffle/external_repos/simplelanguage/sl @@ -41,7 +41,7 @@ # # If you update this number make sure the graalvm.version value in ./pom.xml matches -VERSION="23.0.2-dev" +VERSION="23.0.3-dev" MAIN_CLASS="com.oracle.truffle.sl.launcher.SLMain" SCRIPT_HOME="$(cd "$(dirname "$0")" && pwd -P)" diff --git a/truffle/external_repos/simpletool/pom.xml b/truffle/external_repos/simpletool/pom.xml index 72ef1e007dbf3..c62e71a20acc3 100644 --- a/truffle/external_repos/simpletool/pom.xml +++ b/truffle/external_repos/simpletool/pom.xml @@ -49,7 +49,7 @@ UTF-8 1.8 1.8 - 23.0.2-dev + 23.0.3-dev diff --git a/truffle/mx.truffle/suite.py b/truffle/mx.truffle/suite.py index 844138aeb5838..1eaa8751cf529 100644 --- a/truffle/mx.truffle/suite.py +++ b/truffle/mx.truffle/suite.py @@ -41,8 +41,8 @@ suite = { "mxversion": "6.17.0", "name" : "truffle", - "version" : "23.0.2", - "release" : True, + "version" : "23.0.3", + "release" : False, "groupId" : "org.graalvm.truffle", "sourceinprojectwhitelist" : [], "url" : "http://openjdk.java.net/projects/graal", diff --git a/vm/mx.vm/suite.py b/vm/mx.vm/suite.py index a47b1fb302bc8..98a9ab11d6a58 100644 --- a/vm/mx.vm/suite.py +++ b/vm/mx.vm/suite.py @@ -1,8 +1,8 @@ suite = { "name": "vm", - "version" : "23.0.2", + "version" : "23.0.3", "mxversion": "6.17.0", - "release" : True, + "release" : False, "groupId" : "org.graalvm", "url" : "http://www.graalvm.org/", @@ -39,7 +39,7 @@ "name": "graal-nodejs", "subdir": True, "dynamic": True, - "version": "e2b74f45ce0eb8ae3f9bd24b068f128e91d607e8", + "version": "6627021bd787fe8800681b6d8899b5e764bac034", "urls" : [ {"url" : "https://github.com/graalvm/graaljs.git", "kind" : "git"}, {"url": "https://curio.ssw.jku.at/nexus/content/repositories/snapshots", "kind": "binary"}, @@ -49,7 +49,7 @@ "name": "graal-js", "subdir": True, "dynamic": True, - "version": "e2b74f45ce0eb8ae3f9bd24b068f128e91d607e8", + "version": "6627021bd787fe8800681b6d8899b5e764bac034", "urls": [ {"url": "https://github.com/graalvm/graaljs.git", "kind" : "git"}, {"url": "https://curio.ssw.jku.at/nexus/content/repositories/snapshots", "kind": "binary"}, @@ -75,7 +75,7 @@ }, { "name": "graalpython", - "version": "5ee94e7b30384a04d69c3c861aeb736fc095c195", + "version": "249facdaa87860239cb454df7732d6e810224f9e", "dynamic": True, "urls": [ {"url": "https://github.com/graalvm/graalpython.git", "kind": "git"}, diff --git a/wasm/mx.wasm/suite.py b/wasm/mx.wasm/suite.py index f0cb2f13727f5..4e0383341c91a 100644 --- a/wasm/mx.wasm/suite.py +++ b/wasm/mx.wasm/suite.py @@ -42,7 +42,7 @@ "mxversion": "6.17.0", "name" : "wasm", "groupId" : "org.graalvm.wasm", - "version" : "23.0.2", + "version" : "23.0.3", "versionConflictResolution" : "latest", "url" : "http://graalvm.org/", "developer" : { From 7434dd0906ea33b0489d7312ab57425aa57fa980 Mon Sep 17 00:00:00 2001 From: David Leopoldseder Date: Mon, 26 Jun 2023 14:05:24 +0200 Subject: [PATCH 03/34] canon: expose dead phi cycle detection as feature that can be disabled (cherry picked from commit e27665f37e474c1af70e33a015c0aedcbdeafb78) --- .../phases/common/CanonicalizerPhase.java | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/compiler/src/org.graalvm.compiler.phases.common/src/org/graalvm/compiler/phases/common/CanonicalizerPhase.java b/compiler/src/org.graalvm.compiler.phases.common/src/org/graalvm/compiler/phases/common/CanonicalizerPhase.java index 97254545d08a8..ae865f66af86c 100644 --- a/compiler/src/org.graalvm.compiler.phases.common/src/org/graalvm/compiler/phases/common/CanonicalizerPhase.java +++ b/compiler/src/org.graalvm.compiler.phases.common/src/org/graalvm/compiler/phases/common/CanonicalizerPhase.java @@ -25,6 +25,7 @@ package org.graalvm.compiler.phases.common; import static org.graalvm.compiler.phases.common.CanonicalizerPhase.CanonicalizerFeature.CFG_SIMPLIFICATION; +import static org.graalvm.compiler.phases.common.CanonicalizerPhase.CanonicalizerFeature.DEAD_PHI_CYCLE_DETECTION; import static org.graalvm.compiler.phases.common.CanonicalizerPhase.CanonicalizerFeature.GVN; import static org.graalvm.compiler.phases.common.CanonicalizerPhase.CanonicalizerFeature.READ_CANONICALIZATION; @@ -108,7 +109,13 @@ public enum CanonicalizerFeature { * Determines if the canonicalizer is allowed to perform global value numbering. See * {@link StructuredGraph#findDuplicate(Node)} for details. */ - GVN; + GVN, + /** + * Determines if the canonicalizer is allowed to perform a global graph analysis on dead + * loop phi cycles and delete them. + * {@link CanonicalizerPhase#isDeadLoopPhiCycle(PhiNode, NodeFlood)} for details. + */ + DEAD_PHI_CYCLE_DETECTION; } protected static final int MAX_ITERATION_PER_NODE = 10; @@ -158,6 +165,12 @@ public CanonicalizerPhase copyWithoutGVN() { return new CanonicalizerPhase(customSimplification, newFeatures); } + public CanonicalizerPhase copyWithoutDeadPhiCycleDetection() { + EnumSet newFeatures = EnumSet.copyOf(features); + newFeatures.remove(DEAD_PHI_CYCLE_DETECTION); + return new CanonicalizerPhase(customSimplification, newFeatures); + } + public CanonicalizerPhase copyWithoutSimplification() { EnumSet newFeatures = EnumSet.copyOf(features); newFeatures.remove(CFG_SIMPLIFICATION); @@ -314,7 +327,7 @@ public void usagesDroppedToZero(Node node) { for (Node n : tool.workList) { processNode(n, tool); ++sum; - if (tool.allUsagesAvailable() && n.isAlive() && n instanceof PhiNode && ((PhiNode) n).isLoopPhi()) { + if (features.contains(DEAD_PHI_CYCLE_DETECTION) && tool.allUsagesAvailable() && n.isAlive() && n instanceof PhiNode && ((PhiNode) n).isLoopPhi()) { if (phiPostProcessingWorkList == null) { phiPostProcessingWorkList = EconomicSet.create(); } From 4ccf57e585241ba96e589cc80d1d619b4c0f8ca8 Mon Sep 17 00:00:00 2001 From: Christian Haeubl Date: Mon, 4 Sep 2023 09:49:18 +0200 Subject: [PATCH 04/34] Use some minimal alignment for unaligned heap chunks. Some cleanups and additional sanity checks. (cherry picked from commit 6c0aa3039e2bb8edf0d7af556176625d9d63881e) --- .../oracle/svm/core/genscavenge/HeapParameters.java | 5 +++++ .../svm/core/genscavenge/UnalignedHeapChunk.java | 4 ---- .../svm/core/code/AbstractRuntimeCodeInstaller.java | 6 ++++-- .../core/os/AbstractCommittedMemoryProvider.java | 13 ++++++++++++- .../oracle/svm/core/os/CommittedMemoryProvider.java | 7 ------- .../src/com/oracle/svm/core/util/PointerUtils.java | 2 ++ 6 files changed, 23 insertions(+), 14 deletions(-) diff --git a/substratevm/src/com.oracle.svm.core.genscavenge/src/com/oracle/svm/core/genscavenge/HeapParameters.java b/substratevm/src/com.oracle.svm.core.genscavenge/src/com/oracle/svm/core/genscavenge/HeapParameters.java index 9c2be3f9a442b..42bb84bf63f63 100644 --- a/substratevm/src/com.oracle.svm.core.genscavenge/src/com/oracle/svm/core/genscavenge/HeapParameters.java +++ b/substratevm/src/com.oracle.svm.core.genscavenge/src/com/oracle/svm/core/genscavenge/HeapParameters.java @@ -123,6 +123,11 @@ static UnsignedWord getAlignedHeapChunkAlignment() { return getAlignedHeapChunkSize(); } + @Fold + public static UnsignedWord getMinUnalignedChunkSize() { + return UnalignedHeapChunk.getChunkSizeForObject(HeapParameters.getLargeArrayThreshold()); + } + @Fold public static UnsignedWord getLargeArrayThreshold() { long largeArrayThreshold = SerialAndEpsilonGCOptions.LargeArrayThreshold.getValue(); diff --git a/substratevm/src/com.oracle.svm.core.genscavenge/src/com/oracle/svm/core/genscavenge/UnalignedHeapChunk.java b/substratevm/src/com.oracle.svm.core.genscavenge/src/com/oracle/svm/core/genscavenge/UnalignedHeapChunk.java index b6673242aec1a..92d350a0549ed 100644 --- a/substratevm/src/com.oracle.svm.core.genscavenge/src/com/oracle/svm/core/genscavenge/UnalignedHeapChunk.java +++ b/substratevm/src/com.oracle.svm.core.genscavenge/src/com/oracle/svm/core/genscavenge/UnalignedHeapChunk.java @@ -105,10 +105,6 @@ public static Pointer getObjectEnd(UnalignedHeader that) { return HeapChunk.getEndPointer(that); } - public static UnsignedWord getOverhead() { - return getObjectStartOffset(); - } - static UnsignedWord getChunkSizeForObject(UnsignedWord objectSize) { UnsignedWord objectStart = getObjectStartOffset(); UnsignedWord alignment = WordFactory.unsigned(ConfigurationValues.getObjectLayout().getAlignment()); diff --git a/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/code/AbstractRuntimeCodeInstaller.java b/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/code/AbstractRuntimeCodeInstaller.java index f745ac0f495b2..b10ca00f9653a 100644 --- a/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/code/AbstractRuntimeCodeInstaller.java +++ b/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/code/AbstractRuntimeCodeInstaller.java @@ -47,11 +47,13 @@ protected Pointer allocateCodeMemory(long size) { } protected void makeCodeMemoryExecutableReadOnly(Pointer start, UnsignedWord size) { - RuntimeCodeInfoAccess.makeCodeMemoryExecutableReadOnly((CodePointer) start, size); + int result = RuntimeCodeInfoAccess.makeCodeMemoryExecutableReadOnly((CodePointer) start, size); + VMError.guarantee(result == 0, "Failed to make code memory read only."); } protected void makeCodeMemoryExecutableWritable(Pointer start, UnsignedWord size) { - RuntimeCodeInfoAccess.makeCodeMemoryExecutableWritable((CodePointer) start, size); + int result = RuntimeCodeInfoAccess.makeCodeMemoryExecutableWritable((CodePointer) start, size); + VMError.guarantee(result == 0, "Failed to make code memory writable."); } protected static void doInstallPrepared(SharedMethod method, CodeInfo codeInfo, SubstrateInstalledCode installedCode) { diff --git a/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/os/AbstractCommittedMemoryProvider.java b/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/os/AbstractCommittedMemoryProvider.java index f381b6ed1b4d1..4888517486e26 100644 --- a/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/os/AbstractCommittedMemoryProvider.java +++ b/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/os/AbstractCommittedMemoryProvider.java @@ -42,6 +42,7 @@ import com.oracle.svm.core.Uninterruptible; import com.oracle.svm.core.c.function.CEntryPointErrors; import com.oracle.svm.core.code.RuntimeCodeCache; +import com.oracle.svm.core.config.ConfigurationValues; import com.oracle.svm.core.heap.Heap; import com.oracle.svm.core.util.UnsignedUtils; import com.oracle.svm.core.util.VMError; @@ -109,7 +110,7 @@ public Pointer allocateAlignedChunk(UnsignedWord nbytes, UnsignedWord alignment) @Override public Pointer allocateUnalignedChunk(UnsignedWord nbytes) { - return allocate(nbytes, WordFactory.unsigned(1), false); + return allocate(nbytes, getAlignmentForUnalignedChunks(), false); } @Override @@ -172,6 +173,16 @@ private void free(PointerBase start, UnsignedWord nbytes) { } } + /** + * Unaligned chunks also need some minimal alignment - otherwise, the data in the chunk header + * or the Java heap object within the unaligned chunk would be misaligned. + */ + @Fold + protected static UnsignedWord getAlignmentForUnalignedChunks() { + int alignment = Math.max(ConfigurationValues.getTarget().wordSize, ConfigurationValues.getObjectLayout().getAlignment()); + return WordFactory.unsigned(alignment); + } + private final VirtualMemoryTracker tracker = new VirtualMemoryTracker(); public static class VirtualMemoryTracker { diff --git a/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/os/CommittedMemoryProvider.java b/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/os/CommittedMemoryProvider.java index d54b95287d574..273ad6e10cb47 100644 --- a/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/os/CommittedMemoryProvider.java +++ b/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/os/CommittedMemoryProvider.java @@ -32,7 +32,6 @@ import org.graalvm.word.Pointer; import org.graalvm.word.PointerBase; import org.graalvm.word.UnsignedWord; -import org.graalvm.word.WordFactory; import com.oracle.svm.core.Uninterruptible; import com.oracle.svm.core.c.function.CEntryPointCreateIsolateParameters; @@ -43,12 +42,6 @@ * memory or swap space. */ public interface CommittedMemoryProvider { - /** - * Value for alignment parameters that indicates that no specific alignment is required (other - * than the {@linkplain #getGranularity() granularity} usually). - */ - UnsignedWord UNALIGNED = WordFactory.unsigned(1); - @Fold static CommittedMemoryProvider get() { return ImageSingletons.lookup(CommittedMemoryProvider.class); diff --git a/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/util/PointerUtils.java b/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/util/PointerUtils.java index 6eaa28430b1d4..306d3b796109f 100644 --- a/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/util/PointerUtils.java +++ b/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/util/PointerUtils.java @@ -101,6 +101,7 @@ public static UnsignedWord absoluteDifference(PointerBase pointer1, PointerBase * @param y Another Pointer. * @return The whichever Pointer is smaller. */ + @Uninterruptible(reason = "Called from uninterruptible code.", mayBeInlined = true) public static T min(T x, T y) { return (((Pointer) x).belowOrEqual((Pointer) y)) ? x : y; } @@ -112,6 +113,7 @@ public static T min(T x, T y) { * @param y Another Pointer. * @return The whichever Pointer is larger. */ + @Uninterruptible(reason = "Called from uninterruptible code.", mayBeInlined = true) public static T max(T x, T y) { return (((Pointer) x).aboveOrEqual((Pointer) y)) ? x : y; } From 9929daca3c0d1aaac3bc7e1da9cbd43ef2640408 Mon Sep 17 00:00:00 2001 From: Hamza Ghaissi Date: Wed, 25 Oct 2023 10:58:49 +0100 Subject: [PATCH 05/34] Adapt fix to version 23.0 --- .../oracle/svm/core/c/function/CEntryPointErrors.java | 3 +++ .../src/com/oracle/svm/core/util/VMError.java | 10 ++++++++++ 2 files changed, 13 insertions(+) diff --git a/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/c/function/CEntryPointErrors.java b/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/c/function/CEntryPointErrors.java index 8ca7d3021dfa7..218a077363143 100644 --- a/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/c/function/CEntryPointErrors.java +++ b/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/c/function/CEntryPointErrors.java @@ -59,6 +59,9 @@ private CEntryPointErrors() { @Description("An argument was NULL.") // public static final int NULL_ARGUMENT = 2; + @Description("Memory allocation failed, the OS is probably out of memory.") // + public static final int ALLOCATION_FAILED = 3; + @Description("The specified thread is not attached to the isolate.") // public static final int UNATTACHED_THREAD = 4; diff --git a/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/util/VMError.java b/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/util/VMError.java index bbee4ee3dae2b..10335e80140bd 100644 --- a/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/util/VMError.java +++ b/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/util/VMError.java @@ -64,6 +64,9 @@ public static final class HostedError extends Error { } + public static final String msgShouldNotReachHere = "should not reach here"; + public static final String msgShouldNotReachHereAtRuntime = msgShouldNotReachHere + ": this code is expected to be unreachable at runtime"; + public static RuntimeException shouldNotReachHere() { throw new HostedError("should not reach here"); } @@ -80,6 +83,13 @@ public static RuntimeException shouldNotReachHere(String msg, Throwable cause) { throw new HostedError(msg, cause); } + /** + * A hardcoded list of options (if, switch) did not handle the case actually provided. + */ + public static RuntimeException shouldNotReachHereAtRuntime() { + throw new HostedError(msgShouldNotReachHereAtRuntime); + } + @Uninterruptible(reason = "Called from uninterruptible code.", mayBeInlined = true) public static void guarantee(boolean condition) { if (!condition) { From ca1fc1b297846281bac44748a5c3540f79edaa77 Mon Sep 17 00:00:00 2001 From: Bernhard Urban-Forster Date: Tue, 22 Aug 2023 15:02:37 +0200 Subject: [PATCH 06/34] [GR-47839] Use fixed OS version for GraalVM builds on darwin-aarch64 (cherry picked from commit 11598149f037e9bed6254431459443072c996f16) --- vm/ci/ci_common/common.jsonnet | 1 + 1 file changed, 1 insertion(+) diff --git a/vm/ci/ci_common/common.jsonnet b/vm/ci/ci_common/common.jsonnet index cf399503724c2..fd63bca0a42d8 100644 --- a/vm/ci/ci_common/common.jsonnet +++ b/vm/ci/ci_common/common.jsonnet @@ -180,6 +180,7 @@ local devkits = graal_common.devkits; }, vm_darwin_aarch64: self.common_vm_darwin + graal_common.darwin_aarch64 + { + capabilities+: ['darwin_bigsur'], environment+: { # for compatibility with macOS BigSur MACOSX_DEPLOYMENT_TARGET: '11.0', From 4b3b001d7530ff6ca04d999edfce2cbc6c250cae Mon Sep 17 00:00:00 2001 From: Florian Angerer Date: Fri, 6 Oct 2023 12:12:14 +0200 Subject: [PATCH 07/34] Workaround CPU features Xcode 15 miscomp issue (GR-49301) (cherry picked from commit 6bd08da980dc290d2918dafc04b3c502bfc8934d) --- .../src/com.oracle.svm.native.libchelper/src/cpuid.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/substratevm/src/com.oracle.svm.native.libchelper/src/cpuid.c b/substratevm/src/com.oracle.svm.native.libchelper/src/cpuid.c index ccad45416b936..6719dee830192 100644 --- a/substratevm/src/com.oracle.svm.native.libchelper/src/cpuid.c +++ b/substratevm/src/com.oracle.svm.native.libchelper/src/cpuid.c @@ -42,6 +42,12 @@ #ifndef _WIN64 #include +#if defined(_MSC_VER) && !defined(__clang__) +#define NO_INLINE __declspec(noinline) +#else +#define NO_INLINE __attribute__((noinline)) +#endif + static void read_xem_xcr0(uint32_t *eax, uint32_t *edx) { __asm__ __volatile__("xgetbv" : "=a"(*eax), "=d"(*edx) : "c"(0)); } @@ -381,8 +387,8 @@ static void initialize_cpuinfo(CpuidInfo *_cpuid_info) } } -// ported from from vm_version_x86.hpp::feature_flags -static void set_cpufeatures(CPUFeatures *features, CpuidInfo *_cpuid_info) +// ported from from vm_version_x86.cpp::feature_flags +static void NO_INLINE set_cpufeatures(CPUFeatures *features, CpuidInfo *_cpuid_info) { if (_cpuid_info->std_cpuid1_edx.bits.cmpxchg8 != 0) features->fCX8 = 1; From 705bbf733a522fa3c537d4c693f54e1d40c9d8c7 Mon Sep 17 00:00:00 2001 From: Josef Eisl Date: Mon, 9 Oct 2023 08:38:59 +0200 Subject: [PATCH 08/34] svm: fix placement of the NO_INLINE definition in cpuid.c (cherry picked from commit 6b05065efe3c84d8123f6be13cd2988ce3748382) --- .../com.oracle.svm.native.libchelper/src/cpuid.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/substratevm/src/com.oracle.svm.native.libchelper/src/cpuid.c b/substratevm/src/com.oracle.svm.native.libchelper/src/cpuid.c index 6719dee830192..2e588a3062f70 100644 --- a/substratevm/src/com.oracle.svm.native.libchelper/src/cpuid.c +++ b/substratevm/src/com.oracle.svm.native.libchelper/src/cpuid.c @@ -28,6 +28,12 @@ #include #include +#if defined(_MSC_VER) && !defined(__clang__) +#define NO_INLINE __declspec(noinline) +#else +#define NO_INLINE __attribute__((noinline)) +#endif + #ifndef _WIN64 #include #else @@ -42,12 +48,6 @@ #ifndef _WIN64 #include -#if defined(_MSC_VER) && !defined(__clang__) -#define NO_INLINE __declspec(noinline) -#else -#define NO_INLINE __attribute__((noinline)) -#endif - static void read_xem_xcr0(uint32_t *eax, uint32_t *edx) { __asm__ __volatile__("xgetbv" : "=a"(*eax), "=d"(*edx) : "c"(0)); } @@ -388,7 +388,7 @@ static void initialize_cpuinfo(CpuidInfo *_cpuid_info) } // ported from from vm_version_x86.cpp::feature_flags -static void NO_INLINE set_cpufeatures(CPUFeatures *features, CpuidInfo *_cpuid_info) +NO_INLINE static void set_cpufeatures(CPUFeatures *features, CpuidInfo *_cpuid_info) { if (_cpuid_info->std_cpuid1_edx.bits.cmpxchg8 != 0) features->fCX8 = 1; From aef9a21922838c3c1d58a858fbb8f08813de6710 Mon Sep 17 00:00:00 2001 From: Florian Angerer Date: Wed, 11 Oct 2023 11:59:28 +0200 Subject: [PATCH 09/34] svm: add comment about the reason for NO_INLINE (cherry picked from commit 65f4a3ed9adc4a9ce0aa51cb9d35af36591ac090) --- substratevm/src/com.oracle.svm.native.libchelper/src/cpuid.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/substratevm/src/com.oracle.svm.native.libchelper/src/cpuid.c b/substratevm/src/com.oracle.svm.native.libchelper/src/cpuid.c index 2e588a3062f70..b967d65889b8f 100644 --- a/substratevm/src/com.oracle.svm.native.libchelper/src/cpuid.c +++ b/substratevm/src/com.oracle.svm.native.libchelper/src/cpuid.c @@ -388,6 +388,8 @@ static void initialize_cpuinfo(CpuidInfo *_cpuid_info) } // ported from from vm_version_x86.cpp::feature_flags +// NO_INLINE is necessary to avoid an unexpected behavior if compiling on Darwin +// with Apple clang version 15.0.0 (included in Xcode 15.0). NO_INLINE static void set_cpufeatures(CPUFeatures *features, CpuidInfo *_cpuid_info) { if (_cpuid_info->std_cpuid1_edx.bits.cmpxchg8 != 0) From cdb0389887fbfff5fb368a04f1bb9986dc55883a Mon Sep 17 00:00:00 2001 From: Foivos Zakkak Date: Tue, 17 Oct 2023 15:43:31 +0300 Subject: [PATCH 10/34] Introduce `--disable-debuginfo-stripping` mx argument Disable the stripping of debug symbols from the generated native bits Closes https://github.com/oracle/graal/issues/6995 (cherry picked from commit 0162b2283096e8f5cd1c2f5671922c25bdea60c4) --- sdk/mx.sdk/mx_sdk_vm_impl.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/sdk/mx.sdk/mx_sdk_vm_impl.py b/sdk/mx.sdk/mx_sdk_vm_impl.py index 763b45df424c4..4221888de3650 100644 --- a/sdk/mx.sdk/mx_sdk_vm_impl.py +++ b/sdk/mx.sdk/mx_sdk_vm_impl.py @@ -1166,7 +1166,7 @@ def generate_debug_info(self, image_config): return self.is_debug_supported() and _generate_debuginfo(image_config) def generate_separate_debug_info(self, image_config): - return self.generate_debug_info(image_config) and self._separate_debuginfo_ext + return self.generate_debug_info(image_config) and not mx.get_opts().disable_debuginfo_stripping and self._separate_debuginfo_ext def separate_debuginfo_ext(self): return self._separate_debuginfo_ext @@ -1174,6 +1174,8 @@ def separate_debuginfo_ext(self): def get_debug_flags(self, image_config): assert self.is_debug_supported() flags = ['-g'] + if not self.generate_separate_debug_info(image_config): + flags += svm_experimental_options(['-H:-StripDebugInfo']) if mx.is_darwin(): flags += ['-H:+UseOldDebugInfo'] if self.generate_separate_debug_info(image_config): @@ -3787,6 +3789,7 @@ def graalvm_vendor_version(): mx.add_argument('--sources', action='store', help='Comma-separated list of projects and distributions of open-source components for which source file archives must be included' + (' (all by default).' if _debuginfo_default else '.'), default=None) mx.add_argument('--debuginfo-dists', action='store_true', help='Generate debuginfo distributions.') mx.add_argument('--generate-debuginfo', action='store', help='Comma-separated list of launchers and libraries (syntax: lib:polyglot) for which to generate debug information (`native-image -g`) (all by default)', default=None) +mx.add_argument('--disable-debuginfo-stripping', action='store_true', help='Disable the stripping of debug symbols from the native image.') mx.add_argument('--snapshot-catalog', action='store', help='Change the default URL of the component catalog for snapshots.', default=None) mx.add_argument('--gds-snapshot-catalog', action='store', help='Change the default appended URL of the component catalog for snapshots.', default=None) mx.add_argument('--release-catalog', action='store', help='Change the default URL of the component catalog for releases.', default=None) From ae28c577cae8a068a1687c917c93ca63b3ec0998 Mon Sep 17 00:00:00 2001 From: Martin Entlicher Date: Wed, 25 Oct 2023 18:12:49 +0200 Subject: [PATCH 11/34] Add the mandatory experimental property 'debuggerId' and handle GET of /json/list path. (GR-49664) (cherry picked from commit de48c8431b263e1a7e548927dfde82efee7eff51) --- .../test/AbstractFunctionValueTest.java | 3 +- .../test/BuggyLanguageInspectDebugTest.java | 4 +- .../test/DisabledDomainTest.java | 2 +- .../test/ITLInspectDebugTest.java | 40 +++--- .../test/InspectorMessageTransportTest.java | 2 +- .../test/InspectorReceiverTest.java | 12 +- .../test/LazyAccessInspectDebugTest.java | 4 +- .../test/NotReadableValuesTest.java | 4 +- .../test/RelativeSourceInspectDebugTest.java | 12 +- .../test/SLInspectDebugTest.java | 123 ++++++++++++------ .../chromeinspector/test/TestMemoryLeaks.java | 6 +- .../chromeinspector/InspectorDebugger.java | 9 ++ .../domains/DebuggerDomain.java | 2 + .../server/InspectServerSession.java | 3 + .../server/InspectorServer.java | 15 ++- 15 files changed, 165 insertions(+), 76 deletions(-) diff --git a/tools/src/com.oracle.truffle.tools.chromeinspector.test/src/com/oracle/truffle/tools/chromeinspector/test/AbstractFunctionValueTest.java b/tools/src/com.oracle.truffle.tools.chromeinspector.test/src/com/oracle/truffle/tools/chromeinspector/test/AbstractFunctionValueTest.java index 8977f1319bc6d..4136259d32797 100644 --- a/tools/src/com.oracle.truffle.tools.chromeinspector.test/src/com/oracle/truffle/tools/chromeinspector/test/AbstractFunctionValueTest.java +++ b/tools/src/com.oracle.truffle.tools.chromeinspector.test/src/com/oracle/truffle/tools/chromeinspector/test/AbstractFunctionValueTest.java @@ -65,7 +65,8 @@ protected final Future runWith(Object truffleObject) throws Exception { tester.sendMessage("{\"id\":1,\"method\":\"Runtime.enable\"}"); assertEquals("{\"result\":{},\"id\":1}", tester.getMessages(true).trim()); tester.sendMessage("{\"id\":2,\"method\":\"Debugger.enable\"}"); - assertEquals("{\"result\":{},\"id\":2}", tester.getMessages(true).trim()); + tester.receiveMessages( + "{\"result\":{\"debuggerId\":\"UniqueDebuggerId.", "},\"id\":2}\n"); tester.sendMessage("{\"id\":3,\"method\":\"Debugger.setBreakpointByUrl\",\"params\":{\"lineNumber\":3,\"url\":\"" + FILE_NAME + "\",\"columnNumber\":0,\"condition\":\"\"}}"); assertTrue(tester.compareReceivedMessages( "{\"result\":{\"breakpointId\":\"1\",\"locations\":[]},\"id\":3}\n")); diff --git a/tools/src/com.oracle.truffle.tools.chromeinspector.test/src/com/oracle/truffle/tools/chromeinspector/test/BuggyLanguageInspectDebugTest.java b/tools/src/com.oracle.truffle.tools.chromeinspector.test/src/com/oracle/truffle/tools/chromeinspector/test/BuggyLanguageInspectDebugTest.java index 9550b78dd723e..04aa4b0e12466 100644 --- a/tools/src/com.oracle.truffle.tools.chromeinspector.test/src/com/oracle/truffle/tools/chromeinspector/test/BuggyLanguageInspectDebugTest.java +++ b/tools/src/com.oracle.truffle.tools.chromeinspector.test/src/com/oracle/truffle/tools/chromeinspector/test/BuggyLanguageInspectDebugTest.java @@ -137,9 +137,9 @@ private void testBuggyCalls(AtomicReference language, String pref tester.setErr(errorStream); tester.sendMessage("{\"id\":1,\"method\":\"Runtime.enable\"}"); tester.sendMessage("{\"id\":2,\"method\":\"Debugger.enable\"}"); - assertTrue(tester.compareReceivedMessages( + tester.receiveMessages( "{\"result\":{},\"id\":1}\n" + - "{\"result\":{},\"id\":2}\n")); + "{\"result\":{\"debuggerId\":\"UniqueDebuggerId.", "},\"id\":2}\n"); tester.sendMessage("{\"id\":3,\"method\":\"Runtime.runIfWaitingForDebugger\"}"); assertTrue(tester.compareReceivedMessages( "{\"result\":{},\"id\":3}\n" + diff --git a/tools/src/com.oracle.truffle.tools.chromeinspector.test/src/com/oracle/truffle/tools/chromeinspector/test/DisabledDomainTest.java b/tools/src/com.oracle.truffle.tools.chromeinspector.test/src/com/oracle/truffle/tools/chromeinspector/test/DisabledDomainTest.java index efc9fbd75dddd..26a0d5af4a1e6 100644 --- a/tools/src/com.oracle.truffle.tools.chromeinspector.test/src/com/oracle/truffle/tools/chromeinspector/test/DisabledDomainTest.java +++ b/tools/src/com.oracle.truffle.tools.chromeinspector.test/src/com/oracle/truffle/tools/chromeinspector/test/DisabledDomainTest.java @@ -53,7 +53,7 @@ public void testDisabledDomainsCalls() throws Exception { tester.sendMessage("{\"id\":10," + debuggerMessage); assertEquals("{\"id\":10,\"error\":{\"code\":-32601,\"message\":\"Domain Debugger is disabled.\"}}", tester.getMessages(true).trim()); tester.sendMessage("{\"id\":11,\"method\":\"Debugger.enable\"}"); - assertEquals("{\"result\":{},\"id\":11}", tester.getMessages(true).trim()); + tester.receiveMessages("{\"result\":{\"debuggerId\":\"UniqueDebuggerId.", "},\"id\":11}\n"); tester.sendMessage("{\"id\":12," + debuggerMessage); assertEquals("{\"result\":{\"breakpointId\":\"1\",\"locations\":[]},\"id\":12}", tester.getMessages(true).trim()); tester.sendMessage("{\"id\":13,\"method\":\"Debugger.disable\"}"); diff --git a/tools/src/com.oracle.truffle.tools.chromeinspector.test/src/com/oracle/truffle/tools/chromeinspector/test/ITLInspectDebugTest.java b/tools/src/com.oracle.truffle.tools.chromeinspector.test/src/com/oracle/truffle/tools/chromeinspector/test/ITLInspectDebugTest.java index 6c45d1ed16ee6..76e785164c21b 100644 --- a/tools/src/com.oracle.truffle.tools.chromeinspector.test/src/com/oracle/truffle/tools/chromeinspector/test/ITLInspectDebugTest.java +++ b/tools/src/com.oracle.truffle.tools.chromeinspector.test/src/com/oracle/truffle/tools/chromeinspector/test/ITLInspectDebugTest.java @@ -70,7 +70,8 @@ public void testSuspendInInitialization() throws Exception { tester.sendMessage("{\"id\":1,\"method\":\"Runtime.enable\"}"); assertEquals("{\"result\":{},\"id\":1}", tester.getMessages(true).trim()); tester.sendMessage("{\"id\":2,\"method\":\"Debugger.enable\"}"); - assertEquals("{\"result\":{},\"id\":2}", tester.getMessages(true).trim()); + tester.receiveMessages( + "{\"result\":{\"debuggerId\":\"UniqueDebuggerId.", "},\"id\":2}\n"); tester.sendMessage("{\"id\":3,\"method\":\"Runtime.runIfWaitingForDebugger\"}"); assertTrue(tester.compareReceivedMessages( "{\"result\":{},\"id\":3}\n" + @@ -101,7 +102,8 @@ public void testSuspendInInitialization() throws Exception { tester.sendMessage("{\"id\":1,\"method\":\"Runtime.enable\"}"); assertEquals("{\"result\":{},\"id\":1}", tester.getMessages(true).trim()); tester.sendMessage("{\"id\":2,\"method\":\"Debugger.enable\"}"); - assertEquals("{\"result\":{},\"id\":2}", tester.getMessages(true).trim()); + tester.receiveMessages( + "{\"result\":{\"debuggerId\":\"UniqueDebuggerId.", "},\"id\":2}\n"); tester.sendMessage("{\"id\":3,\"method\":\"Runtime.runIfWaitingForDebugger\"}"); assertTrue(tester.compareReceivedMessages( "{\"result\":{},\"id\":3}\n" + @@ -142,7 +144,8 @@ public void testSuspendInInternal() throws Exception { tester.sendMessage("{\"id\":1,\"method\":\"Runtime.enable\"}"); assertEquals("{\"result\":{},\"id\":1}", tester.getMessages(true).trim()); tester.sendMessage("{\"id\":2,\"method\":\"Debugger.enable\"}"); - assertEquals("{\"result\":{},\"id\":2}", tester.getMessages(true).trim()); + tester.receiveMessages( + "{\"result\":{\"debuggerId\":\"UniqueDebuggerId.", "},\"id\":2}\n"); tester.sendMessage("{\"id\":3,\"method\":\"Runtime.runIfWaitingForDebugger\"}"); assertTrue(tester.compareReceivedMessages( "{\"result\":{},\"id\":3}\n" + @@ -172,7 +175,8 @@ public void testSuspendInInternal() throws Exception { tester.sendMessage("{\"id\":1,\"method\":\"Runtime.enable\"}"); assertEquals("{\"result\":{},\"id\":1}", tester.getMessages(true).trim()); tester.sendMessage("{\"id\":2,\"method\":\"Debugger.enable\"}"); - assertEquals("{\"result\":{},\"id\":2}", tester.getMessages(true).trim()); + tester.receiveMessages( + "{\"result\":{\"debuggerId\":\"UniqueDebuggerId.", "},\"id\":2}\n"); tester.sendMessage("{\"id\":3,\"method\":\"Runtime.runIfWaitingForDebugger\"}"); assertTrue(tester.compareReceivedMessages( "{\"result\":{},\"id\":3}\n" + @@ -213,7 +217,8 @@ public void testThis() throws Exception { tester.sendMessage("{\"id\":1,\"method\":\"Runtime.enable\"}"); assertEquals("{\"result\":{},\"id\":1}", tester.getMessages(true).trim()); tester.sendMessage("{\"id\":2,\"method\":\"Debugger.enable\"}"); - assertEquals("{\"result\":{},\"id\":2}", tester.getMessages(true).trim()); + tester.receiveMessages( + "{\"result\":{\"debuggerId\":\"UniqueDebuggerId.", "},\"id\":2}\n"); tester.sendMessage("{\"id\":3,\"method\":\"Runtime.runIfWaitingForDebugger\"}"); assertTrue(tester.compareReceivedMessages( "{\"result\":{},\"id\":3}\n" + @@ -269,9 +274,10 @@ public void testShortURIs() throws Exception { tester.sendMessage("{\"id\":1,\"method\":\"Runtime.enable\"}"); tester.sendMessage("{\"id\":2,\"method\":\"Debugger.enable\"}"); tester.sendMessage("{\"id\":3,\"method\":\"Runtime.runIfWaitingForDebugger\"}"); - assertTrue(tester.compareReceivedMessages( + tester.receiveMessages( "{\"result\":{},\"id\":1}\n" + - "{\"result\":{},\"id\":2}\n" + + "{\"result\":{\"debuggerId\":\"UniqueDebuggerId.", "},\"id\":2}\n"); + assertTrue(tester.compareReceivedMessages( "{\"result\":{},\"id\":3}\n" + "{\"method\":\"Runtime.executionContextCreated\",\"params\":{\"context\":{\"origin\":\"\",\"name\":\"test\",\"id\":1}}}\n")); tester.eval(source1); @@ -319,9 +325,10 @@ public void testOutput() throws Exception { tester.sendMessage("{\"id\":1,\"method\":\"Runtime.enable\"}"); tester.sendMessage("{\"id\":2,\"method\":\"Debugger.enable\"}"); tester.sendMessage("{\"id\":3,\"method\":\"Runtime.runIfWaitingForDebugger\"}"); - assertTrue(tester.compareReceivedMessages( + tester.receiveMessages( "{\"result\":{},\"id\":1}\n" + - "{\"result\":{},\"id\":2}\n" + + "{\"result\":{\"debuggerId\":\"UniqueDebuggerId.", "},\"id\":2}\n"); + assertTrue(tester.compareReceivedMessages( "{\"result\":{},\"id\":3}\n" + "{\"method\":\"Runtime.executionContextCreated\",\"params\":{\"context\":{\"origin\":\"\",\"name\":\"test\",\"id\":1}}}\n")); tester.eval(source); @@ -387,9 +394,10 @@ public void testOutputNoNL() throws Exception { tester.sendMessage("{\"id\":1,\"method\":\"Runtime.enable\"}"); tester.sendMessage("{\"id\":2,\"method\":\"Debugger.enable\"}"); tester.sendMessage("{\"id\":3,\"method\":\"Runtime.runIfWaitingForDebugger\"}"); - assertTrue(tester.compareReceivedMessages( + tester.receiveMessages( "{\"result\":{},\"id\":1}\n" + - "{\"result\":{},\"id\":2}\n" + + "{\"result\":{\"debuggerId\":\"UniqueDebuggerId.", "},\"id\":2}\n"); + assertTrue(tester.compareReceivedMessages( "{\"result\":{},\"id\":3}\n" + "{\"method\":\"Runtime.executionContextCreated\",\"params\":{\"context\":{\"origin\":\"\",\"name\":\"test\",\"id\":1}}}\n")); tester.eval(source); @@ -426,9 +434,10 @@ public void testAsynchronousStackTraces() throws Exception { tester.sendMessage("{\"id\":2,\"method\":\"Debugger.enable\"}"); tester.sendMessage("{\"id\":3,\"method\":\"Debugger.setAsyncCallStackDepth\",\"params\":{\"maxDepth\":1}}"); tester.sendMessage("{\"id\":4,\"method\":\"Runtime.runIfWaitingForDebugger\"}"); - assertTrue(tester.compareReceivedMessages( + tester.receiveMessages( "{\"result\":{},\"id\":1}\n" + - "{\"result\":{},\"id\":2}\n" + + "{\"result\":{\"debuggerId\":\"UniqueDebuggerId.", "},\"id\":2}\n"); + assertTrue(tester.compareReceivedMessages( "{\"result\":{},\"id\":3}\n" + "{\"result\":{},\"id\":4}\n" + "{\"method\":\"Runtime.executionContextCreated\",\"params\":{\"context\":{\"origin\":\"\",\"name\":\"test\",\"id\":1}}}\n")); @@ -511,9 +520,10 @@ public void testSuspendALot() throws Exception { tester.sendMessage("{\"id\":2,\"method\":\"Debugger.enable\"}"); tester.sendMessage("{\"id\":3,\"method\":\"Debugger.setAsyncCallStackDepth\",\"params\":{\"maxDepth\":1}}"); tester.sendMessage("{\"id\":4,\"method\":\"Runtime.runIfWaitingForDebugger\"}"); - assertTrue(tester.compareReceivedMessages( + tester.receiveMessages( "{\"result\":{},\"id\":1}\n" + - "{\"result\":{},\"id\":2}\n" + + "{\"result\":{\"debuggerId\":\"UniqueDebuggerId.", "},\"id\":2}\n"); + assertTrue(tester.compareReceivedMessages( "{\"result\":{},\"id\":3}\n" + "{\"result\":{},\"id\":4}\n" + "{\"method\":\"Runtime.executionContextCreated\",\"params\":{\"context\":{\"origin\":\"\",\"name\":\"test\",\"id\":1}}}\n")); diff --git a/tools/src/com.oracle.truffle.tools.chromeinspector.test/src/com/oracle/truffle/tools/chromeinspector/test/InspectorMessageTransportTest.java b/tools/src/com.oracle.truffle.tools.chromeinspector.test/src/com/oracle/truffle/tools/chromeinspector/test/InspectorMessageTransportTest.java index b036120031d1a..0bd7b0f72f6bb 100644 --- a/tools/src/com.oracle.truffle.tools.chromeinspector.test/src/com/oracle/truffle/tools/chromeinspector/test/InspectorMessageTransportTest.java +++ b/tools/src/com.oracle.truffle.tools.chromeinspector.test/src/com/oracle/truffle/tools/chromeinspector/test/InspectorMessageTransportTest.java @@ -61,7 +61,7 @@ public class InspectorMessageTransportTest extends EnginesGCedTest { private static final String[] MESSAGES_TO_BACKEND; private static final String[] MESSAGES_TO_CLIENT = { "{\"result\":{},\"id\":5}", - "{\"result\":{},\"id\":6}", + "{\"result\":{\"debuggerId\":\"UniqueDebuggerId.", "{\"result\":{},\"id\":7}", "{\"result\":{},\"id\":8}", "{\"result\":{},\"id\":20}", diff --git a/tools/src/com.oracle.truffle.tools.chromeinspector.test/src/com/oracle/truffle/tools/chromeinspector/test/InspectorReceiverTest.java b/tools/src/com.oracle.truffle.tools.chromeinspector.test/src/com/oracle/truffle/tools/chromeinspector/test/InspectorReceiverTest.java index 974844e0c7ab9..54a5447c64d72 100644 --- a/tools/src/com.oracle.truffle.tools.chromeinspector.test/src/com/oracle/truffle/tools/chromeinspector/test/InspectorReceiverTest.java +++ b/tools/src/com.oracle.truffle.tools.chromeinspector.test/src/com/oracle/truffle/tools/chromeinspector/test/InspectorReceiverTest.java @@ -52,7 +52,8 @@ public void testThisReceiver1() throws Exception { tester.sendMessage("{\"id\":1,\"method\":\"Runtime.enable\"}"); assertEquals("{\"result\":{},\"id\":1}", tester.getMessages(true).trim()); tester.sendMessage("{\"id\":2,\"method\":\"Debugger.enable\"}"); - assertEquals("{\"result\":{},\"id\":2}", tester.getMessages(true).trim()); + tester.receiveMessages( + "{\"result\":{\"debuggerId\":\"UniqueDebuggerId.", "},\"id\":2}\n"); tester.sendMessage("{\"id\":3,\"method\":\"Runtime.runIfWaitingForDebugger\"}"); assertTrue(tester.compareReceivedMessages( "{\"result\":{},\"id\":3}\n" + @@ -98,7 +99,8 @@ public void testThisReceiver2() throws Exception { tester.sendMessage("{\"id\":1,\"method\":\"Runtime.enable\"}"); assertEquals("{\"result\":{},\"id\":1}", tester.getMessages(true).trim()); tester.sendMessage("{\"id\":2,\"method\":\"Debugger.enable\"}"); - assertEquals("{\"result\":{},\"id\":2}", tester.getMessages(true).trim()); + tester.receiveMessages( + "{\"result\":{\"debuggerId\":\"UniqueDebuggerId.", "},\"id\":2}\n"); tester.sendMessage("{\"id\":3,\"method\":\"Runtime.runIfWaitingForDebugger\"}"); assertTrue(tester.compareReceivedMessages( "{\"result\":{},\"id\":3}\n" + @@ -154,7 +156,8 @@ private static void checkMultipleReceivers(String receiver, String sourceHash) t tester.sendMessage("{\"id\":1,\"method\":\"Runtime.enable\"}"); assertEquals("{\"result\":{},\"id\":1}", tester.getMessages(true).trim()); tester.sendMessage("{\"id\":2,\"method\":\"Debugger.enable\"}"); - assertEquals("{\"result\":{},\"id\":2}", tester.getMessages(true).trim()); + tester.receiveMessages( + "{\"result\":{\"debuggerId\":\"UniqueDebuggerId.", "},\"id\":2}\n"); tester.sendMessage("{\"id\":3,\"method\":\"Runtime.runIfWaitingForDebugger\"}"); assertTrue(tester.compareReceivedMessages( "{\"result\":{},\"id\":3}\n" + @@ -211,7 +214,8 @@ public void testOtherReceiver1() throws Exception { tester.sendMessage("{\"id\":1,\"method\":\"Runtime.enable\"}"); assertEquals("{\"result\":{},\"id\":1}", tester.getMessages(true).trim()); tester.sendMessage("{\"id\":2,\"method\":\"Debugger.enable\"}"); - assertEquals("{\"result\":{},\"id\":2}", tester.getMessages(true).trim()); + tester.receiveMessages( + "{\"result\":{\"debuggerId\":\"UniqueDebuggerId.", "},\"id\":2}\n"); tester.sendMessage("{\"id\":3,\"method\":\"Runtime.runIfWaitingForDebugger\"}"); assertTrue(tester.compareReceivedMessages( "{\"result\":{},\"id\":3}\n" + diff --git a/tools/src/com.oracle.truffle.tools.chromeinspector.test/src/com/oracle/truffle/tools/chromeinspector/test/LazyAccessInspectDebugTest.java b/tools/src/com.oracle.truffle.tools.chromeinspector.test/src/com/oracle/truffle/tools/chromeinspector/test/LazyAccessInspectDebugTest.java index b99aea7f1126c..e725f05d1c652 100644 --- a/tools/src/com.oracle.truffle.tools.chromeinspector.test/src/com/oracle/truffle/tools/chromeinspector/test/LazyAccessInspectDebugTest.java +++ b/tools/src/com.oracle.truffle.tools.chromeinspector.test/src/com/oracle/truffle/tools/chromeinspector/test/LazyAccessInspectDebugTest.java @@ -81,9 +81,9 @@ public void testReadWithSideEffects() throws Exception { InspectorTester tester = InspectorTester.start(true); tester.sendMessage("{\"id\":1,\"method\":\"Runtime.enable\"}"); tester.sendMessage("{\"id\":2,\"method\":\"Debugger.enable\"}"); - assertTrue(tester.compareReceivedMessages( + tester.receiveMessages( "{\"result\":{},\"id\":1}\n" + - "{\"result\":{},\"id\":2}\n")); + "{\"result\":{\"debuggerId\":\"UniqueDebuggerId.", "},\"id\":2}\n"); tester.sendMessage("{\"id\":3,\"method\":\"Runtime.runIfWaitingForDebugger\"}"); assertTrue(tester.compareReceivedMessages( "{\"result\":{},\"id\":3}\n" + diff --git a/tools/src/com.oracle.truffle.tools.chromeinspector.test/src/com/oracle/truffle/tools/chromeinspector/test/NotReadableValuesTest.java b/tools/src/com.oracle.truffle.tools.chromeinspector.test/src/com/oracle/truffle/tools/chromeinspector/test/NotReadableValuesTest.java index 2a55f9661f34f..a07f844fc91e9 100644 --- a/tools/src/com.oracle.truffle.tools.chromeinspector.test/src/com/oracle/truffle/tools/chromeinspector/test/NotReadableValuesTest.java +++ b/tools/src/com.oracle.truffle.tools.chromeinspector.test/src/com/oracle/truffle/tools/chromeinspector/test/NotReadableValuesTest.java @@ -63,9 +63,9 @@ public void testNotReadableVariables() throws Exception { InspectorTester tester = InspectorTester.start(true); tester.sendMessage("{\"id\":1,\"method\":\"Runtime.enable\"}"); tester.sendMessage("{\"id\":2,\"method\":\"Debugger.enable\"}"); - assertTrue(tester.compareReceivedMessages( + tester.receiveMessages( "{\"result\":{},\"id\":1}\n" + - "{\"result\":{},\"id\":2}\n")); + "{\"result\":{\"debuggerId\":\"UniqueDebuggerId.", "},\"id\":2}\n"); tester.sendMessage("{\"id\":3,\"method\":\"Runtime.runIfWaitingForDebugger\"}"); assertTrue(tester.compareReceivedMessages( "{\"result\":{},\"id\":3}\n" + diff --git a/tools/src/com.oracle.truffle.tools.chromeinspector.test/src/com/oracle/truffle/tools/chromeinspector/test/RelativeSourceInspectDebugTest.java b/tools/src/com.oracle.truffle.tools.chromeinspector.test/src/com/oracle/truffle/tools/chromeinspector/test/RelativeSourceInspectDebugTest.java index 121d26951057a..fcc2042e60619 100644 --- a/tools/src/com.oracle.truffle.tools.chromeinspector.test/src/com/oracle/truffle/tools/chromeinspector/test/RelativeSourceInspectDebugTest.java +++ b/tools/src/com.oracle.truffle.tools.chromeinspector.test/src/com/oracle/truffle/tools/chromeinspector/test/RelativeSourceInspectDebugTest.java @@ -123,7 +123,8 @@ public void testSourcePath() throws Exception { tester.sendMessage("{\"id\":1,\"method\":\"Runtime.enable\"}"); assertEquals("{\"result\":{},\"id\":1}", tester.getMessages(true).trim()); tester.sendMessage("{\"id\":2,\"method\":\"Debugger.enable\"}"); - assertEquals("{\"result\":{},\"id\":2}", tester.getMessages(true).trim()); + tester.receiveMessages( + "{\"result\":{\"debuggerId\":\"UniqueDebuggerId.", "},\"id\":2}\n"); tester.sendMessage("{\"id\":3,\"method\":\"Runtime.runIfWaitingForDebugger\"}"); // @formatter:off The default formatting makes unnecessarily big indents and illogical line breaks @@ -183,7 +184,8 @@ public void testNonExistingSourcePath() throws Exception { tester.sendMessage("{\"id\":1,\"method\":\"Runtime.enable\"}"); assertEquals("{\"result\":{},\"id\":1}", tester.getMessages(true).trim()); tester.sendMessage("{\"id\":2,\"method\":\"Debugger.enable\"}"); - assertEquals("{\"result\":{},\"id\":2}", tester.getMessages(true).trim()); + tester.receiveMessages( + "{\"result\":{\"debuggerId\":\"UniqueDebuggerId.", "},\"id\":2}\n"); tester.sendMessage("{\"id\":3,\"method\":\"Runtime.runIfWaitingForDebugger\"}"); String resolvedPath = new File("relative/path").toPath().toAbsolutePath().toUri().toString(); @@ -305,7 +307,8 @@ private static void testBreakpoints(int sectionLine, int sectionColumn, int bpLi tester.sendMessage("{\"id\":1,\"method\":\"Runtime.enable\"}"); assertEquals("{\"result\":{},\"id\":1}", tester.getMessages(true).trim()); tester.sendMessage("{\"id\":2,\"method\":\"Debugger.enable\"}"); - assertEquals("{\"result\":{},\"id\":2}", tester.getMessages(true).trim()); + tester.receiveMessages( + "{\"result\":{\"debuggerId\":\"UniqueDebuggerId.", "},\"id\":2}\n"); tester.sendMessage("{\"id\":3,\"method\":\"Runtime.runIfWaitingForDebugger\"}"); // @formatter:off The default formatting makes unnecessarily big indents and illogical line breaks @@ -383,7 +386,8 @@ public void testEagerSourceLoad() throws Exception { assertTrue(tester.compareReceivedMessages( "{\"method\":\"Debugger.scriptParsed\",\"params\":{\"endLine\":3,\"scriptId\":\"1\",\"endColumn\":0,\"startColumn\":0,\"startLine\":0,\"length\":" + 180 + ",\"executionContextId\":1,\"url\":\"" + prolog2URI + "\",\"hash\":\"ddbb5c60e6d93544f2f9afd9f84696c2ffd09768\"}}\n")); - assertEquals("{\"result\":{},\"id\":2}", tester.getMessages(true).trim()); + tester.receiveMessages( + "{\"result\":{\"debuggerId\":\"UniqueDebuggerId.", "},\"id\":2}\n"); tester.sendMessage("{\"id\":3,\"method\":\"Runtime.runIfWaitingForDebugger\"}"); // @formatter:off The default formatting makes unnecessarily big indents and illogical line breaks diff --git a/tools/src/com.oracle.truffle.tools.chromeinspector.test/src/com/oracle/truffle/tools/chromeinspector/test/SLInspectDebugTest.java b/tools/src/com.oracle.truffle.tools.chromeinspector.test/src/com/oracle/truffle/tools/chromeinspector/test/SLInspectDebugTest.java index 74461c209e051..8c6e12e084312 100644 --- a/tools/src/com.oracle.truffle.tools.chromeinspector.test/src/com/oracle/truffle/tools/chromeinspector/test/SLInspectDebugTest.java +++ b/tools/src/com.oracle.truffle.tools.chromeinspector.test/src/com/oracle/truffle/tools/chromeinspector/test/SLInspectDebugTest.java @@ -201,7 +201,8 @@ public void testInitialSuspendAndSource() throws Exception { tester.sendMessage("{\"id\":1,\"method\":\"Runtime.enable\"}"); assertEquals("{\"result\":{},\"id\":1}", tester.getMessages(true).trim()); tester.sendMessage("{\"id\":2,\"method\":\"Debugger.enable\"}"); - assertEquals("{\"result\":{},\"id\":2}", tester.getMessages(true).trim()); + tester.receiveMessages( + "{\"result\":{\"debuggerId\":\"UniqueDebuggerId.", "},\"id\":2}\n"); tester.sendMessage("{\"id\":3,\"method\":\"Runtime.runIfWaitingForDebugger\"}"); assertTrue(tester.compareReceivedMessages( "{\"result\":{},\"id\":3}\n" + @@ -243,8 +244,10 @@ public void testStepping() throws Exception { tester.sendMessage("{\"id\":2,\"method\":\"Debugger.enable\"}"); tester.sendMessage("{\"id\":3,\"method\":\"Runtime.runIfWaitingForDebugger\"}"); assertTrue(tester.compareReceivedMessages( - "{\"result\":{},\"id\":1}\n" + - "{\"result\":{},\"id\":2}\n" + + "{\"result\":{},\"id\":1}\n")); + tester.receiveMessages( + "{\"result\":{\"debuggerId\":\"UniqueDebuggerId.", "},\"id\":2}\n"); + assertTrue(tester.compareReceivedMessages( "{\"result\":{},\"id\":3}\n" + "{\"method\":\"Runtime.executionContextCreated\",\"params\":{\"context\":{\"origin\":\"\",\"name\":\"test\",\"id\":1}}}\n")); tester.eval(source); @@ -331,8 +334,10 @@ public void testBreakpoints() throws Exception { tester.sendMessage("{\"id\":3,\"method\":\"Runtime.runIfWaitingForDebugger\"}"); String slTestURI = InspectorTester.getStringURI(source.getURI()); assertTrue(tester.compareReceivedMessages( - "{\"result\":{},\"id\":1}\n" + - "{\"result\":{},\"id\":2}\n" + + "{\"result\":{},\"id\":1}\n")); + tester.receiveMessages( + "{\"result\":{\"debuggerId\":\"UniqueDebuggerId.", "},\"id\":2}\n"); + assertTrue(tester.compareReceivedMessages( "{\"result\":{},\"id\":3}\n" + "{\"method\":\"Runtime.executionContextCreated\",\"params\":{\"context\":{\"origin\":\"\",\"name\":\"test\",\"id\":1}}}\n")); @@ -408,8 +413,10 @@ public void testBreakpointDeactivation() throws Exception { tester.sendMessage("{\"id\":3,\"method\":\"Runtime.runIfWaitingForDebugger\"}"); String srcURL = InspectorTester.getStringURI(source.getURI()); assertTrue(tester.compareReceivedMessages( - "{\"result\":{},\"id\":1}\n" + - "{\"result\":{},\"id\":2}\n" + + "{\"result\":{},\"id\":1}\n")); + tester.receiveMessages( + "{\"result\":{\"debuggerId\":\"UniqueDebuggerId.", "},\"id\":2}\n"); + assertTrue(tester.compareReceivedMessages( "{\"result\":{},\"id\":3}\n" + "{\"method\":\"Runtime.executionContextCreated\",\"params\":{\"context\":{\"origin\":\"\",\"name\":\"test\",\"id\":1}}}\n")); tester.sendMessage("{\"id\":3,\"method\":\"Debugger.setBreakpointByUrl\",\"params\":{\"lineNumber\":9,\"url\":\"" + srcURL + "\",\"columnNumber\":0,\"condition\":\"\"}}"); @@ -564,8 +571,11 @@ private void testGuestFunctionBreakpoints(boolean useConsoleUtilities) throws Ex tester.sendMessage("{\"id\":1,\"method\":\"Runtime.enable\"}"); tester.sendMessage("{\"id\":2,\"method\":\"Debugger.enable\"}"); tester.sendMessage("{\"id\":3,\"method\":\"Runtime.runIfWaitingForDebugger\"}"); - assertTrue(tester.compareReceivedMessages("{\"result\":{},\"id\":1}\n" + - "{\"result\":{},\"id\":2}\n" + + assertTrue(tester.compareReceivedMessages( + "{\"result\":{},\"id\":1}\n")); + tester.receiveMessages( + "{\"result\":{\"debuggerId\":\"UniqueDebuggerId.", "},\"id\":2}\n"); + assertTrue(tester.compareReceivedMessages( "{\"result\":{},\"id\":3}\n" + "{\"method\":\"Runtime.executionContextCreated\",\"params\":{\"context\":{\"origin\":\"\",\"name\":\"test\",\"id\":1}}}\n")); tester.eval(source); @@ -645,8 +655,11 @@ private void testBuiltInFunctionBreakpoints(boolean useConsoleUtilities) throws tester.sendMessage("{\"id\":1,\"method\":\"Runtime.enable\"}"); tester.sendMessage("{\"id\":2,\"method\":\"Debugger.enable\"}"); tester.sendMessage("{\"id\":3,\"method\":\"Runtime.runIfWaitingForDebugger\"}"); - assertTrue(tester.compareReceivedMessages("{\"result\":{},\"id\":1}\n" + - "{\"result\":{},\"id\":2}\n" + + assertTrue(tester.compareReceivedMessages( + "{\"result\":{},\"id\":1}\n")); + tester.receiveMessages( + "{\"result\":{\"debuggerId\":\"UniqueDebuggerId.", "},\"id\":2}\n"); + assertTrue(tester.compareReceivedMessages( "{\"result\":{},\"id\":3}\n" + "{\"method\":\"Runtime.executionContextCreated\",\"params\":{\"context\":{\"origin\":\"\",\"name\":\"test\",\"id\":1}}}\n")); tester.eval(source); @@ -721,8 +734,11 @@ public void testScopes() throws Exception { tester.sendMessage("{\"id\":1,\"method\":\"Runtime.enable\"}"); tester.sendMessage("{\"id\":2,\"method\":\"Debugger.enable\"}"); tester.sendMessage("{\"id\":3,\"method\":\"Runtime.runIfWaitingForDebugger\"}"); - assertTrue(tester.compareReceivedMessages("{\"result\":{},\"id\":1}\n" + - "{\"result\":{},\"id\":2}\n" + + assertTrue(tester.compareReceivedMessages( + "{\"result\":{},\"id\":1}\n")); + tester.receiveMessages( + "{\"result\":{\"debuggerId\":\"UniqueDebuggerId.", "},\"id\":2}\n"); + assertTrue(tester.compareReceivedMessages( "{\"result\":{},\"id\":3}\n" + "{\"method\":\"Runtime.executionContextCreated\",\"params\":{\"context\":{\"origin\":\"\",\"name\":\"test\",\"id\":1}}}\n")); tester.eval(source); @@ -798,8 +814,11 @@ public void testNotSuspended() throws Exception { tester.sendMessage("{\"id\":1,\"method\":\"Runtime.enable\"}"); tester.sendMessage("{\"id\":2,\"method\":\"Debugger.enable\"}"); tester.sendMessage("{\"id\":3,\"method\":\"Runtime.runIfWaitingForDebugger\"}"); - assertTrue(tester.compareReceivedMessages("{\"result\":{},\"id\":1}\n" + - "{\"result\":{},\"id\":2}\n" + + assertTrue(tester.compareReceivedMessages( + "{\"result\":{},\"id\":1}\n")); + tester.receiveMessages( + "{\"result\":{\"debuggerId\":\"UniqueDebuggerId.", "},\"id\":2}\n"); + assertTrue(tester.compareReceivedMessages( "{\"result\":{},\"id\":3}\n" + "{\"method\":\"Runtime.executionContextCreated\",\"params\":{\"context\":{\"origin\":\"\",\"name\":\"test\",\"id\":1}}}\n")); tester.eval(source); @@ -857,8 +876,11 @@ public void testNoInternalSources() throws Exception { tester.sendMessage("{\"id\":1,\"method\":\"Runtime.enable\"}"); tester.sendMessage("{\"id\":2,\"method\":\"Debugger.enable\"}"); tester.sendMessage("{\"id\":3,\"method\":\"Runtime.runIfWaitingForDebugger\"}"); - assertTrue(tester.compareReceivedMessages("{\"result\":{},\"id\":1}\n" + - "{\"result\":{},\"id\":2}\n" + + assertTrue(tester.compareReceivedMessages( + "{\"result\":{},\"id\":1}\n")); + tester.receiveMessages( + "{\"result\":{\"debuggerId\":\"UniqueDebuggerId.", "},\"id\":2}\n"); + assertTrue(tester.compareReceivedMessages( "{\"result\":{},\"id\":3}\n" + "{\"method\":\"Runtime.executionContextCreated\",\"params\":{\"context\":{\"origin\":\"\",\"name\":\"test\",\"id\":1}}}\n")); long id = tester.getContextId(); @@ -1125,8 +1147,11 @@ public void testNoBlackboxedSources() throws Exception { tester.sendMessage("{\"id\":2,\"method\":\"Debugger.enable\"}"); tester.sendMessage("{\"id\":3,\"method\":\"Debugger.setBlackboxPatterns\",\"params\":{\"patterns\":[\"BlackboxedFunc.sl\"]}}"); tester.sendMessage("{\"id\":4,\"method\":\"Runtime.runIfWaitingForDebugger\"}"); - assertTrue(tester.compareReceivedMessages("{\"result\":{},\"id\":1}\n" + - "{\"result\":{},\"id\":2}\n" + + assertTrue(tester.compareReceivedMessages( + "{\"result\":{},\"id\":1}\n")); + tester.receiveMessages( + "{\"result\":{\"debuggerId\":\"UniqueDebuggerId.", "},\"id\":2}\n"); + assertTrue(tester.compareReceivedMessages( "{\"result\":{},\"id\":3}\n" + "{\"result\":{},\"id\":4}\n" + "{\"method\":\"Runtime.executionContextCreated\",\"params\":{\"context\":{\"origin\":\"\",\"name\":\"test\",\"id\":1}}}\n")); @@ -1244,8 +1269,10 @@ public void testRestartFrame() throws Exception { tester.sendMessage("{\"id\":3,\"method\":\"Runtime.runIfWaitingForDebugger\"}"); String srcURL = InspectorTester.getStringURI(source.getURI()); assertTrue(tester.compareReceivedMessages( - "{\"result\":{},\"id\":1}\n" + - "{\"result\":{},\"id\":2}\n" + + "{\"result\":{},\"id\":1}\n")); + tester.receiveMessages( + "{\"result\":{\"debuggerId\":\"UniqueDebuggerId.", "},\"id\":2}\n"); + assertTrue(tester.compareReceivedMessages( "{\"result\":{},\"id\":3}\n" + "{\"method\":\"Runtime.executionContextCreated\",\"params\":{\"context\":{\"origin\":\"\",\"name\":\"test\",\"id\":1}}}\n")); tester.sendMessage("{\"id\":3,\"method\":\"Debugger.setBreakpointByUrl\",\"params\":{\"lineNumber\":6,\"url\":\"" + srcURL + "\",\"columnNumber\":0,\"condition\":\"\"}}"); @@ -1375,8 +1402,10 @@ public void testReturnValue() throws Exception { tester.sendMessage("{\"id\":2,\"method\":\"Debugger.enable\"}"); tester.sendMessage("{\"id\":3,\"method\":\"Runtime.runIfWaitingForDebugger\"}"); assertTrue(tester.compareReceivedMessages( - "{\"result\":{},\"id\":1}\n" + - "{\"result\":{},\"id\":2}\n" + + "{\"result\":{},\"id\":1}\n")); + tester.receiveMessages( + "{\"result\":{\"debuggerId\":\"UniqueDebuggerId.", "},\"id\":2}\n"); + assertTrue(tester.compareReceivedMessages( "{\"result\":{},\"id\":3}\n" + "{\"method\":\"Runtime.executionContextCreated\",\"params\":{\"context\":{\"origin\":\"\",\"name\":\"test\",\"id\":1}}}\n")); tester.eval(source); @@ -1585,8 +1614,10 @@ public void testBreakpointCorrections() throws Exception { tester.sendMessage("{\"id\":3,\"method\":\"Runtime.runIfWaitingForDebugger\"}"); String srcURL = InspectorTester.getStringURI(source.getURI()); assertTrue(tester.compareReceivedMessages( - "{\"result\":{},\"id\":1}\n" + - "{\"result\":{},\"id\":2}\n" + + "{\"result\":{},\"id\":1}\n")); + tester.receiveMessages( + "{\"result\":{\"debuggerId\":\"UniqueDebuggerId.", "},\"id\":2}\n"); + assertTrue(tester.compareReceivedMessages( "{\"result\":{},\"id\":3}\n" + "{\"method\":\"Runtime.executionContextCreated\",\"params\":{\"context\":{\"origin\":\"\",\"name\":\"test\",\"id\":1}}}\n")); @@ -1666,8 +1697,10 @@ public void testPossibleBreakpoints() throws Exception { tester.sendMessage("{\"id\":3,\"method\":\"Runtime.runIfWaitingForDebugger\"}"); String srcURL = InspectorTester.getStringURI(source.getURI()); assertTrue(tester.compareReceivedMessages( - "{\"result\":{},\"id\":1}\n" + - "{\"result\":{},\"id\":2}\n" + + "{\"result\":{},\"id\":1}\n")); + tester.receiveMessages( + "{\"result\":{\"debuggerId\":\"UniqueDebuggerId.", "},\"id\":2}\n"); + assertTrue(tester.compareReceivedMessages( "{\"result\":{},\"id\":3}\n" + "{\"method\":\"Runtime.executionContextCreated\",\"params\":{\"context\":{\"origin\":\"\",\"name\":\"test\",\"id\":1}}}\n")); @@ -1732,8 +1765,10 @@ public void testThrown() throws Exception { tester.sendMessage("{\"id\":3,\"method\":\"Runtime.runIfWaitingForDebugger\"}"); String srcURL = InspectorTester.getStringURI(source.getURI()); assertTrue(tester.compareReceivedMessages( - "{\"result\":{},\"id\":1}\n" + - "{\"result\":{},\"id\":2}\n" + + "{\"result\":{},\"id\":1}\n")); + tester.receiveMessages( + "{\"result\":{\"debuggerId\":\"UniqueDebuggerId.", "},\"id\":2}\n"); + assertTrue(tester.compareReceivedMessages( "{\"result\":{},\"id\":3}\n" + "{\"method\":\"Runtime.executionContextCreated\",\"params\":{\"context\":{\"origin\":\"\",\"name\":\"test\",\"id\":1}}}\n")); tester.sendMessage("{\"id\":3,\"method\":\"Debugger.setPauseOnExceptions\",\"params\":{\"state\":\"uncaught\"}}"); @@ -1781,8 +1816,10 @@ public void testSetVariableValue() throws Exception { tester.sendMessage("{\"id\":3,\"method\":\"Runtime.runIfWaitingForDebugger\"}"); String srcURL = InspectorTester.getStringURI(source.getURI()); assertTrue(tester.compareReceivedMessages( - "{\"result\":{},\"id\":1}\n" + - "{\"result\":{},\"id\":2}\n" + + "{\"result\":{},\"id\":1}\n")); + tester.receiveMessages( + "{\"result\":{\"debuggerId\":\"UniqueDebuggerId.", "},\"id\":2}\n"); + assertTrue(tester.compareReceivedMessages( "{\"result\":{},\"id\":3}\n" + "{\"method\":\"Runtime.executionContextCreated\",\"params\":{\"context\":{\"origin\":\"\",\"name\":\"test\",\"id\":1}}}\n")); int suspendLine = 15; @@ -1870,8 +1907,10 @@ public void testMemberCompletionChrome() throws Exception { tester.sendMessage("{\"id\":3,\"method\":\"Runtime.runIfWaitingForDebugger\"}"); String srcURL = InspectorTester.getStringURI(source.getURI()); assertTrue(tester.compareReceivedMessages( - "{\"result\":{},\"id\":1}\n" + - "{\"result\":{},\"id\":2}\n" + + "{\"result\":{},\"id\":1}\n")); + tester.receiveMessages( + "{\"result\":{\"debuggerId\":\"UniqueDebuggerId.", "},\"id\":2}\n"); + assertTrue(tester.compareReceivedMessages( "{\"result\":{},\"id\":3}\n" + "{\"method\":\"Runtime.executionContextCreated\",\"params\":{\"context\":{\"origin\":\"\",\"name\":\"test\",\"id\":1}}}\n")); tester.eval(source); @@ -1914,8 +1953,10 @@ public void testMemberCompletionVSCode() throws Exception { tester.sendMessage("{\"id\":3,\"method\":\"Runtime.runIfWaitingForDebugger\"}"); String srcURL = InspectorTester.getStringURI(source.getURI()); assertTrue(tester.compareReceivedMessages( - "{\"result\":{},\"id\":1}\n" + - "{\"result\":{},\"id\":2}\n" + + "{\"result\":{},\"id\":1}\n")); + tester.receiveMessages( + "{\"result\":{\"debuggerId\":\"UniqueDebuggerId.", "},\"id\":2}\n"); + assertTrue(tester.compareReceivedMessages( "{\"result\":{},\"id\":3}\n" + "{\"method\":\"Runtime.executionContextCreated\",\"params\":{\"context\":{\"origin\":\"\",\"name\":\"test\",\"id\":1}}}\n")); tester.eval(source); @@ -1953,8 +1994,10 @@ public void testCompletionUpdate() throws Exception { tester.sendMessage("{\"id\":2,\"method\":\"Debugger.enable\"}"); tester.sendMessage("{\"id\":3,\"method\":\"Runtime.runIfWaitingForDebugger\"}"); assertTrue(tester.compareReceivedMessages( - "{\"result\":{},\"id\":1}\n" + - "{\"result\":{},\"id\":2}\n" + + "{\"result\":{},\"id\":1}\n")); + tester.receiveMessages( + "{\"result\":{\"debuggerId\":\"UniqueDebuggerId.", "},\"id\":2}\n"); + assertTrue(tester.compareReceivedMessages( "{\"result\":{},\"id\":3}\n" + "{\"method\":\"Runtime.executionContextCreated\",\"params\":{\"context\":{\"origin\":\"\",\"name\":\"test\",\"id\":1}}}\n")); tester.eval(source); @@ -2012,8 +2055,10 @@ public void testObjectGroups() throws Exception { tester.sendMessage("{\"id\":3,\"method\":\"Runtime.runIfWaitingForDebugger\"}"); String srcURL = InspectorTester.getStringURI(source.getURI()); assertTrue(tester.compareReceivedMessages( - "{\"result\":{},\"id\":1}\n" + - "{\"result\":{},\"id\":2}\n" + + "{\"result\":{},\"id\":1}\n")); + tester.receiveMessages( + "{\"result\":{\"debuggerId\":\"UniqueDebuggerId.", "},\"id\":2}\n"); + assertTrue(tester.compareReceivedMessages( "{\"result\":{},\"id\":3}\n" + "{\"method\":\"Runtime.executionContextCreated\",\"params\":{\"context\":{\"origin\":\"\",\"name\":\"test\",\"id\":1}}}\n")); tester.eval(source); diff --git a/tools/src/com.oracle.truffle.tools.chromeinspector.test/src/com/oracle/truffle/tools/chromeinspector/test/TestMemoryLeaks.java b/tools/src/com.oracle.truffle.tools.chromeinspector.test/src/com/oracle/truffle/tools/chromeinspector/test/TestMemoryLeaks.java index 91598da345747..8cefd9132f4c2 100644 --- a/tools/src/com.oracle.truffle.tools.chromeinspector.test/src/com/oracle/truffle/tools/chromeinspector/test/TestMemoryLeaks.java +++ b/tools/src/com.oracle.truffle.tools.chromeinspector.test/src/com/oracle/truffle/tools/chromeinspector/test/TestMemoryLeaks.java @@ -68,9 +68,11 @@ public void testRemoteObjectsLeak() throws Exception { tester.sendMessage("{\"id\":1,\"method\":\"Runtime.enable\"}"); tester.sendMessage("{\"id\":2,\"method\":\"Debugger.enable\"}"); tester.sendMessage("{\"id\":3,\"method\":\"Runtime.runIfWaitingForDebugger\"}"); + assertTrue(tester.compareReceivedMessages( + "{\"result\":{},\"id\":1}\n")); + tester.receiveMessages( + "{\"result\":{\"debuggerId\":\"UniqueDebuggerId.", "},\"id\":2}\n"); assertTrue(tester.compareReceivedMessages("" + - "{\"result\":{},\"id\":1}\n" + - "{\"result\":{},\"id\":2}\n" + "{\"result\":{},\"id\":3}\n" + "{\"method\":\"Runtime.executionContextCreated\",\"params\":{\"context\":{\"origin\":\"\",\"name\":\"test\",\"id\":1}}}\n")); tester.eval(source); diff --git a/tools/src/com.oracle.truffle.tools.chromeinspector/src/com/oracle/truffle/tools/chromeinspector/InspectorDebugger.java b/tools/src/com.oracle.truffle.tools.chromeinspector/src/com/oracle/truffle/tools/chromeinspector/InspectorDebugger.java index 253c575b8e23c..135237d7d5f40 100644 --- a/tools/src/com.oracle.truffle.tools.chromeinspector/src/com/oracle/truffle/tools/chromeinspector/InspectorDebugger.java +++ b/tools/src/com.oracle.truffle.tools.chromeinspector/src/com/oracle/truffle/tools/chromeinspector/InspectorDebugger.java @@ -42,6 +42,7 @@ import java.util.concurrent.ThreadFactory; import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicBoolean; +import java.util.concurrent.atomic.AtomicLong; import java.util.concurrent.atomic.AtomicReference; import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReadWriteLock; @@ -105,6 +106,8 @@ public final class InspectorDebugger extends DebuggerDomain { "\\s*\\k\\.push\\(Object\\.getOwnPropertyNames\\(\\k\\)\\)" + "\\};\\s*return\\s+\\k\\}\\)\\((?.*)\\)$"); + private static final AtomicLong lastUniqueId = new AtomicLong(); + private final InspectorExecutionContext context; private final Object suspendLock = new Object(); private volatile SuspendedCallbackImpl suspendedCallback; @@ -121,6 +124,7 @@ public final class InspectorDebugger extends DebuggerDomain { private final Phaser onSuspendPhaser = new Phaser(); private final BlockingQueue suspendThreadExecutables = new LinkedBlockingQueue<>(); private final ReadWriteLock domainLock; + private final long uniqueId = lastUniqueId.incrementAndGet(); public InspectorDebugger(InspectorExecutionContext context, boolean suspend, ReadWriteLock domainLock) { this.context = context; @@ -153,6 +157,11 @@ public void execute(CancellableRunnable executable) throws NoSuspendedThreadExce } } + @Override + public String getUniqueDebuggerId() { + return "UniqueDebuggerId." + uniqueId; + } + private void startSession() { Debugger tdbg = context.getEnv().lookup(context.getEnv().getInstruments().get("debugger"), Debugger.class); suspendedCallback = new SuspendedCallbackImpl(); diff --git a/tools/src/com.oracle.truffle.tools.chromeinspector/src/com/oracle/truffle/tools/chromeinspector/domains/DebuggerDomain.java b/tools/src/com.oracle.truffle.tools.chromeinspector/src/com/oracle/truffle/tools/chromeinspector/domains/DebuggerDomain.java index c18da3e217ce8..45788a201794b 100644 --- a/tools/src/com.oracle.truffle.tools.chromeinspector/src/com/oracle/truffle/tools/chromeinspector/domains/DebuggerDomain.java +++ b/tools/src/com.oracle.truffle.tools.chromeinspector/src/com/oracle/truffle/tools/chromeinspector/domains/DebuggerDomain.java @@ -38,6 +38,8 @@ public abstract class DebuggerDomain extends Domain { protected DebuggerDomain() { } + public abstract String getUniqueDebuggerId(); + public abstract void setAsyncCallStackDepth(int maxDepth) throws CommandProcessException; public abstract void setBlackboxPatterns(String[] patterns); diff --git a/tools/src/com.oracle.truffle.tools.chromeinspector/src/com/oracle/truffle/tools/chromeinspector/server/InspectServerSession.java b/tools/src/com.oracle.truffle.tools.chromeinspector/src/com/oracle/truffle/tools/chromeinspector/server/InspectServerSession.java index 21ec0454cbf14..ccb9415b28d04 100644 --- a/tools/src/com.oracle.truffle.tools.chromeinspector/src/com/oracle/truffle/tools/chromeinspector/server/InspectServerSession.java +++ b/tools/src/com.oracle.truffle.tools.chromeinspector/src/com/oracle/truffle/tools/chromeinspector/server/InspectServerSession.java @@ -390,6 +390,9 @@ private Params doProcessCommand(Command cmd, CommandPostProcessor postProcessor) runtime.releaseObjectGroup(json.optString("objectGroup")); break; case "Debugger.enable": + JSONObject dbgJson = new JSONObject(); + dbgJson.put("debuggerId", debugger.getUniqueDebuggerId()); + resultParams = new Params(dbgJson); debugger.enable(); break; case "Debugger.disable": diff --git a/tools/src/com.oracle.truffle.tools.chromeinspector/src/com/oracle/truffle/tools/chromeinspector/server/InspectorServer.java b/tools/src/com.oracle.truffle.tools.chromeinspector/src/com/oracle/truffle/tools/chromeinspector/server/InspectorServer.java index 981968e45d75e..1c68f95f9efdb 100644 --- a/tools/src/com.oracle.truffle.tools.chromeinspector/src/com/oracle/truffle/tools/chromeinspector/server/InspectorServer.java +++ b/tools/src/com.oracle.truffle.tools.chromeinspector/src/com/oracle/truffle/tools/chromeinspector/server/InspectorServer.java @@ -31,6 +31,8 @@ import java.net.Inet4Address; import java.net.InetAddress; import java.net.InetSocketAddress; +import java.net.URI; +import java.net.URISyntaxException; import java.net.UnknownHostException; import java.nio.ByteBuffer; import java.nio.channels.ByteChannel; @@ -303,15 +305,22 @@ private class JSONHandler implements Function { @Override public HttpResponse apply(HttpRequest request) { if ("GET".equals(request.getMethod())) { - String uri = request.getUri(); + String uriStr = request.getUri(); + URI uri; + try { + uri = new URI(uriStr); + } catch (URISyntaxException ex) { + return null; + } + String uriPath = uri.getPath(); String responseJson = null; - if ("/json/version".equals(uri)) { + if ("/json/version".equals(uriPath)) { JSONObject version = new JSONObject(); version.put("Browser", "GraalVM"); version.put("Protocol-Version", "1.2"); responseJson = version.toString(); } - if ("/json".equals(uri)) { + if ("/json".equals(uriPath) || "/json/list".equals(uriPath)) { JSONArray json = new JSONArray(); for (ServerPathSession serverPathSession : sessions.values()) { final String path = serverPathSession.pathContainingToken; From 02b4f1e31211be8b8aae5c3271a6b69becd12833 Mon Sep 17 00:00:00 2001 From: Anas El korchi Date: Tue, 31 Oct 2023 09:57:22 +0100 Subject: [PATCH 12/34] Adapt fix to 23.0 --- sdk/mx.sdk/mx_sdk_vm_impl.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sdk/mx.sdk/mx_sdk_vm_impl.py b/sdk/mx.sdk/mx_sdk_vm_impl.py index 4221888de3650..0c55c26f27020 100644 --- a/sdk/mx.sdk/mx_sdk_vm_impl.py +++ b/sdk/mx.sdk/mx_sdk_vm_impl.py @@ -1175,7 +1175,7 @@ def get_debug_flags(self, image_config): assert self.is_debug_supported() flags = ['-g'] if not self.generate_separate_debug_info(image_config): - flags += svm_experimental_options(['-H:-StripDebugInfo']) + flags += ['-H:-StripDebugInfo'] if mx.is_darwin(): flags += ['-H:+UseOldDebugInfo'] if self.generate_separate_debug_info(image_config): From f16ae260670526b4284b325e41d35757c979bf06 Mon Sep 17 00:00:00 2001 From: Christian Haeubl Date: Fri, 3 Nov 2023 09:38:12 +0100 Subject: [PATCH 13/34] Use JavaThreads.getCurrentThreadOrNull() instead of Thread.currentThread() in JFR. --- .../src/com/oracle/svm/core/jfr/JfrEvent.java | 8 ++++++- .../oracle/svm/core/jfr/JfrThreadLocal.java | 20 ++++++++--------- .../com/oracle/svm/core/jfr/SubstrateJVM.java | 22 +------------------ .../core/jfr/Target_jdk_jfr_internal_JVM.java | 6 ++--- .../oracle/svm/core/thread/JavaThreads.java | 11 ++++++++++ .../core/thread/Target_java_lang_Thread.java | 10 ++++++--- 6 files changed, 39 insertions(+), 38 deletions(-) diff --git a/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/jfr/JfrEvent.java b/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/jfr/JfrEvent.java index 87f055bdd6174..fd931876ede4e 100644 --- a/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/jfr/JfrEvent.java +++ b/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/jfr/JfrEvent.java @@ -28,6 +28,7 @@ import org.graalvm.nativeimage.Platforms; import com.oracle.svm.core.Uninterruptible; +import com.oracle.svm.core.thread.JavaThreads; /** * This file contains the VM-level events that Native Image supports on all JDK versions. The event @@ -87,6 +88,11 @@ public String getName() { @Uninterruptible(reason = "Prevent races with VM operations that start/stop recording.", callerMustBe = true) public boolean shouldEmit() { - return SubstrateJVM.get().isRecording() && SubstrateJVM.get().isEnabled(this) && !SubstrateJVM.get().isCurrentThreadExcluded(); + return shouldEmit0() && !JfrThreadLocal.isThreadExcluded(JavaThreads.getCurrentThreadOrNull()); + } + + @Uninterruptible(reason = "Prevent races with VM operations that start/stop recording.", callerMustBe = true) + private boolean shouldEmit0() { + return SubstrateJVM.get().isRecording() && SubstrateJVM.get().isEnabled(this); } } diff --git a/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/jfr/JfrThreadLocal.java b/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/jfr/JfrThreadLocal.java index b9563705bce7f..bada6464c6f9b 100644 --- a/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/jfr/JfrThreadLocal.java +++ b/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/jfr/JfrThreadLocal.java @@ -33,6 +33,7 @@ import org.graalvm.word.UnsignedWord; import org.graalvm.word.WordFactory; +import com.oracle.svm.core.JavaMainWrapper; import com.oracle.svm.core.SubstrateUtil; import com.oracle.svm.core.Uninterruptible; import com.oracle.svm.core.UnmanagedMemoryUtil; @@ -41,6 +42,7 @@ import com.oracle.svm.core.sampler.SamplerBuffer; import com.oracle.svm.core.sampler.SamplerSampleWriterData; import com.oracle.svm.core.thread.JavaThreads; +import com.oracle.svm.core.thread.PlatformThreads; import com.oracle.svm.core.thread.Target_java_lang_Thread; import com.oracle.svm.core.thread.ThreadListener; import com.oracle.svm.core.thread.VMOperation; @@ -48,8 +50,6 @@ import com.oracle.svm.core.threadlocal.FastThreadLocalLong; import com.oracle.svm.core.threadlocal.FastThreadLocalObject; import com.oracle.svm.core.threadlocal.FastThreadLocalWord; -import com.oracle.svm.core.JavaMainWrapper; -import com.oracle.svm.core.thread.PlatformThreads; /** * This class holds various JFR-specific thread local values. @@ -222,8 +222,8 @@ private static void flushToGlobalMemoryAndRetireBuffer(JfrBuffer buffer) { * This method excludes/includes a thread from JFR (emitting events and sampling). At the * moment, only the current thread may be excluded/included. See GR-44616. */ - public void setExcluded(Thread thread, boolean excluded) { - if (thread == null || !thread.equals(Thread.currentThread())) { + public static void setExcluded(Thread thread, boolean excluded) { + if (thread == null || thread != JavaThreads.getCurrentThreadOrNull()) { return; } IsolateThread currentIsolateThread = CurrentIsolate.getCurrentThread(); @@ -241,18 +241,18 @@ public void setExcluded(Thread thread, boolean excluded) { * See {@link PlatformThreads#ensureCurrentAssigned(String, ThreadGroup, boolean)} where a * {@link Thread} object must be created before it can be assigned to the current thread. This * may happen during shutdown in {@link JavaMainWrapper}. Therefore, this method must account - * for the case where {@link Thread#currentThread()} returns null. + * for the case where {@link JavaThreads#getCurrentThreadOrNull()} returns null. */ @Uninterruptible(reason = "Called from uninterruptible code.", mayBeInlined = true) - public boolean isCurrentThreadExcluded() { - if (Thread.currentThread() == null) { + public static boolean isThreadExcluded(Thread thread) { + if (thread == null) { return true; } - Target_java_lang_Thread tjlt = SubstrateUtil.cast(Thread.currentThread(), Target_java_lang_Thread.class); + Target_java_lang_Thread tjlt = SubstrateUtil.cast(thread, Target_java_lang_Thread.class); return tjlt.jfrExcluded; } - public Target_jdk_jfr_internal_EventWriter getEventWriter() { + public static Target_jdk_jfr_internal_EventWriter getEventWriter() { return javaEventWriter.get(); } @@ -269,7 +269,7 @@ public Target_jdk_jfr_internal_EventWriter newEventWriter() { throw new OutOfMemoryError("OOME for thread local buffer"); } - Target_jdk_jfr_internal_EventWriter result = JfrEventWriterAccess.newEventWriter(buffer, isCurrentThreadExcluded()); + Target_jdk_jfr_internal_EventWriter result = JfrEventWriterAccess.newEventWriter(buffer, isThreadExcluded(JavaThreads.getCurrentThreadOrNull())); javaEventWriter.set(result); return result; } diff --git a/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/jfr/SubstrateJVM.java b/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/jfr/SubstrateJVM.java index e3ce893e1b7a0..9222f226484b1 100644 --- a/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/jfr/SubstrateJVM.java +++ b/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/jfr/SubstrateJVM.java @@ -611,7 +611,7 @@ public void subscribeLogLevel(@SuppressWarnings("unused") LogTag lt, @SuppressWa * See {@link JVM#getEventWriter}. */ public Target_jdk_jfr_internal_EventWriter getEventWriter() { - return threadLocal.getEventWriter(); + return JfrThreadLocal.getEventWriter(); } /** @@ -675,26 +675,6 @@ public Object getConfiguration(Class eventClass) { return DynamicHub.fromClass(eventClass).getJfrEventConfiguration(); } - public void setExcluded(Thread thread, boolean excluded) { - getThreadLocal().setExcluded(thread, excluded); - } - - public boolean isExcluded(Thread thread) { - /* - * Only the current thread is passed to this method in JDK 17, 19, and 20. Eventually, we - * will need to implement that in a more general way though, see GR-44616. - */ - if (!thread.equals(Thread.currentThread())) { - return false; - } - return isCurrentThreadExcluded(); - } - - @Uninterruptible(reason = "Called from uninterruptible code.", mayBeInlined = true) - public boolean isCurrentThreadExcluded() { - return getThreadLocal().isCurrentThreadExcluded(); - } - private static class JfrBeginRecordingOperation extends JavaVMOperation { JfrBeginRecordingOperation() { super(VMOperationInfos.get(JfrBeginRecordingOperation.class, "JFR begin recording", SystemEffect.SAFEPOINT)); diff --git a/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/jfr/Target_jdk_jfr_internal_JVM.java b/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/jfr/Target_jdk_jfr_internal_JVM.java index c788d5cf93b89..76a40fea28bc1 100644 --- a/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/jfr/Target_jdk_jfr_internal_JVM.java +++ b/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/jfr/Target_jdk_jfr_internal_JVM.java @@ -456,19 +456,19 @@ public boolean shouldRotateDisk() { @Substitute @TargetElement(onlyWith = JDK17OrLater.class) // public void include(Thread thread) { - SubstrateJVM.get().setExcluded(thread, false); + JfrThreadLocal.setExcluded(thread, false); } @Substitute @TargetElement(onlyWith = JDK17OrLater.class) // public void exclude(Thread thread) { - SubstrateJVM.get().setExcluded(thread, true); + JfrThreadLocal.setExcluded(thread, true); } @Substitute @TargetElement(onlyWith = JDK17OrLater.class) // public boolean isExcluded(Thread thread) { - return SubstrateJVM.get().isExcluded(thread); + return JfrThreadLocal.isThreadExcluded(thread); } @Substitute diff --git a/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/thread/JavaThreads.java b/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/thread/JavaThreads.java index 82aa1ac06088d..53dacdd1b157d 100644 --- a/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/thread/JavaThreads.java +++ b/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/thread/JavaThreads.java @@ -458,6 +458,17 @@ public static long getCurrentThreadIdOrZero() { } return 0L; } + + @Uninterruptible(reason = "Called from uninterruptible code.", mayBeInlined = true) + public static Thread getCurrentThreadOrNull() { + Thread thread = PlatformThreads.currentThread.get(); + if (thread == null) { + return null; + } + + Target_java_lang_Thread tjlt = SubstrateUtil.cast(thread, Target_java_lang_Thread.class); + return (tjlt.vthread != null) ? tjlt.vthread : thread; + } } /* GR-43733: this class can be removed when we drop the JDK 17 support. */ diff --git a/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/thread/Target_java_lang_Thread.java b/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/thread/Target_java_lang_Thread.java index cce5b52685ebf..189253efe91a9 100644 --- a/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/thread/Target_java_lang_Thread.java +++ b/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/thread/Target_java_lang_Thread.java @@ -320,9 +320,13 @@ static Thread currentCarrierThread() { @Substitute @TargetElement(name = "currentThread", onlyWith = ContinuationsSupported.class) static Thread currentVThread() { - Thread thread = PlatformThreads.currentThread.get(); - Target_java_lang_Thread tjlt = SubstrateUtil.cast(thread, Target_java_lang_Thread.class); - return (tjlt.vthread != null) ? tjlt.vthread : thread; + Thread thread = JavaThreads.getCurrentThreadOrNull(); + if (GraalDirectives.inIntrinsic()) { + ReplacementsUtil.dynamicAssert(thread != null, "Thread has not been set yet"); + } else { + assert thread != null : "Thread has not been set yet"; + } + return thread; } @SuppressWarnings("static-method") From 408429edb6b331fd9ef0814d30232189473f39a3 Mon Sep 17 00:00:00 2001 From: Jan Stola Date: Fri, 3 Nov 2023 17:55:55 +0000 Subject: [PATCH 14/34] [GR-49798] Backport: Upgrading the underlying Node.js to version 18.18.2. PullRequest: js/2970 --- vm/mx.vm/suite.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/vm/mx.vm/suite.py b/vm/mx.vm/suite.py index 98a9ab11d6a58..dc74d2d52784d 100644 --- a/vm/mx.vm/suite.py +++ b/vm/mx.vm/suite.py @@ -39,7 +39,7 @@ "name": "graal-nodejs", "subdir": True, "dynamic": True, - "version": "6627021bd787fe8800681b6d8899b5e764bac034", + "version": "99c8a2c475732c770e7e05ae0823d49648cc7ebb", "urls" : [ {"url" : "https://github.com/graalvm/graaljs.git", "kind" : "git"}, {"url": "https://curio.ssw.jku.at/nexus/content/repositories/snapshots", "kind": "binary"}, @@ -49,7 +49,7 @@ "name": "graal-js", "subdir": True, "dynamic": True, - "version": "6627021bd787fe8800681b6d8899b5e764bac034", + "version": "99c8a2c475732c770e7e05ae0823d49648cc7ebb", "urls": [ {"url": "https://github.com/graalvm/graaljs.git", "kind" : "git"}, {"url": "https://curio.ssw.jku.at/nexus/content/repositories/snapshots", "kind": "binary"}, From d8c7571d8680d82ab102094ac3a7372ec5457c9b Mon Sep 17 00:00:00 2001 From: Christian Haeubl Date: Mon, 6 Nov 2023 18:36:17 +0100 Subject: [PATCH 15/34] Report consistent values when memory usage is queried via MemoryPoolMXBean. --- .../core/genscavenge/AbstractMemoryPoolMXBean.java | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/substratevm/src/com.oracle.svm.core.genscavenge/src/com/oracle/svm/core/genscavenge/AbstractMemoryPoolMXBean.java b/substratevm/src/com.oracle.svm.core.genscavenge/src/com/oracle/svm/core/genscavenge/AbstractMemoryPoolMXBean.java index f2a23be29ba30..cb373d37299db 100644 --- a/substratevm/src/com.oracle.svm.core.genscavenge/src/com/oracle/svm/core/genscavenge/AbstractMemoryPoolMXBean.java +++ b/substratevm/src/com.oracle.svm.core.genscavenge/src/com/oracle/svm/core/genscavenge/AbstractMemoryPoolMXBean.java @@ -40,6 +40,7 @@ import com.oracle.svm.core.heap.AbstractMXBean; import com.oracle.svm.core.jdk.UninterruptibleUtils; +import com.oracle.svm.core.util.UnsignedUtils; import sun.management.Util; @@ -72,11 +73,17 @@ UnsignedWord getInitialValue() { abstract void afterCollection(GCAccounting accounting); MemoryUsage memoryUsage(UnsignedWord usedAndCommitted) { - return new MemoryUsage(getInitialValue().rawValue(), usedAndCommitted.rawValue(), usedAndCommitted.rawValue(), getMaximumValue().rawValue()); + return memoryUsage(usedAndCommitted, usedAndCommitted); } MemoryUsage memoryUsage(UnsignedWord used, UnsignedWord committed) { - return new MemoryUsage(getInitialValue().rawValue(), used.rawValue(), committed.rawValue(), getMaximumValue().rawValue()); + /* + * Actual memory usage may temporarily exceed the maximum. It would be better to return + * UNDEFINED as the maximum value but this could break compatibility (i.e., we only do that + * starting with GraalVM 24.0). + */ + long max = UnsignedUtils.max(getMaximumValue(), UnsignedUtils.max(used, committed)).rawValue(); + return new MemoryUsage(getInitialValue().rawValue(), used.rawValue(), committed.rawValue(), max); } @Override From 853f7fb8e1ee7662d50eec9b58172481bbdd1cdb Mon Sep 17 00:00:00 2001 From: Christian Haeubl Date: Fri, 20 Oct 2023 16:55:40 +0200 Subject: [PATCH 16/34] Don't zap pre-zeroed unaligned chunks. (cherry picked from commit 129fa266e667c7133c99d1ccbdda9115567b6280) --- .../src/com/oracle/svm/core/genscavenge/HeapChunkProvider.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/substratevm/src/com.oracle.svm.core.genscavenge/src/com/oracle/svm/core/genscavenge/HeapChunkProvider.java b/substratevm/src/com.oracle.svm.core.genscavenge/src/com/oracle/svm/core/genscavenge/HeapChunkProvider.java index 4df6532b8e513..6db2eec7d7bc1 100644 --- a/substratevm/src/com.oracle.svm.core.genscavenge/src/com/oracle/svm/core/genscavenge/HeapChunkProvider.java +++ b/substratevm/src/com.oracle.svm.core.genscavenge/src/com/oracle/svm/core/genscavenge/HeapChunkProvider.java @@ -279,7 +279,8 @@ UnalignedHeader produceUnalignedChunk(UnsignedWord objectSize) { UnalignedHeapChunk.initialize(result, chunkSize); assert objectSize.belowOrEqual(HeapChunk.availableObjectMemory(result)) : "UnalignedHeapChunk insufficient for requested object"; - if (HeapParameters.getZapProducedHeapChunks()) { + /* Avoid zapping if unaligned chunks are pre-zeroed. */ + if (!CommittedMemoryProvider.get().areUnalignedChunksZeroed() && HeapParameters.getZapProducedHeapChunks()) { zap(result, HeapParameters.getProducedHeapChunkZapWord()); } From 283d0f8e003bcc4cc28b61cd5cf4d69359db1515 Mon Sep 17 00:00:00 2001 From: Jakub Chaloupka Date: Tue, 24 Oct 2023 16:08:22 +0200 Subject: [PATCH 17/34] Prevent automatic leave of an explicitly entered context during close called from a host call. (cherry picked from commit 0b14c1e31ba02def0b6d28fa230c3d4f30e27dab) Adapt fix to 23.0 --- .../src/org/graalvm/polyglot/Engine.java | 5 + .../polyglot/impl/AbstractPolyglotImpl.java | 4 + .../api/test/polyglot/AutomaticLeaveTest.java | 108 ++++++++++++++++++ .../truffle/api/test/polyglot/reflection.json | 4 + .../truffle/polyglot/PolyglotContextImpl.java | 24 +--- .../oracle/truffle/polyglot/PolyglotImpl.java | 25 ++++ 6 files changed, 147 insertions(+), 23 deletions(-) create mode 100644 truffle/src/com.oracle.truffle.api.test/src/com/oracle/truffle/api/test/polyglot/AutomaticLeaveTest.java diff --git a/sdk/src/org.graalvm.polyglot/src/org/graalvm/polyglot/Engine.java b/sdk/src/org.graalvm.polyglot/src/org/graalvm/polyglot/Engine.java index 91a033dc1379e..7e18a44515213 100644 --- a/sdk/src/org.graalvm.polyglot/src/org/graalvm/polyglot/Engine.java +++ b/sdk/src/org.graalvm.polyglot/src/org/graalvm/polyglot/Engine.java @@ -1239,6 +1239,11 @@ public ThreadScope createThreadScope() { return null; } + @Override + public boolean isInCurrentEngineHostCallback(Object engine) { + return false; + } + @Override public OptionDescriptors createUnionOptionDescriptors(OptionDescriptors... optionDescriptors) { return OptionDescriptors.createUnion(optionDescriptors); diff --git a/sdk/src/org.graalvm.polyglot/src/org/graalvm/polyglot/impl/AbstractPolyglotImpl.java b/sdk/src/org.graalvm.polyglot/src/org/graalvm/polyglot/impl/AbstractPolyglotImpl.java index 463ed8b1f8cff..9a984a2c77e64 100644 --- a/sdk/src/org.graalvm.polyglot/src/org/graalvm/polyglot/impl/AbstractPolyglotImpl.java +++ b/sdk/src/org.graalvm.polyglot/src/org/graalvm/polyglot/impl/AbstractPolyglotImpl.java @@ -1186,6 +1186,10 @@ public ThreadScope createThreadScope() { return getNext().createThreadScope(); } + public boolean isInCurrentEngineHostCallback(Object engine) { + return getNext().isInCurrentEngineHostCallback(engine); + } + public LogHandler newLogHandler(Object logHandlerOrStream) { return getNext().newLogHandler(logHandlerOrStream); } diff --git a/truffle/src/com.oracle.truffle.api.test/src/com/oracle/truffle/api/test/polyglot/AutomaticLeaveTest.java b/truffle/src/com.oracle.truffle.api.test/src/com/oracle/truffle/api/test/polyglot/AutomaticLeaveTest.java new file mode 100644 index 0000000000000..08e3ea49ae378 --- /dev/null +++ b/truffle/src/com.oracle.truffle.api.test/src/com/oracle/truffle/api/test/polyglot/AutomaticLeaveTest.java @@ -0,0 +1,108 @@ +/* + * Copyright (c) 2023, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * The Universal Permissive License (UPL), Version 1.0 + * + * Subject to the condition set forth below, permission is hereby granted to any + * person obtaining a copy of this software, associated documentation and/or + * data (collectively the "Software"), free of charge and under any and all + * copyright rights in the Software, and any and all patent rights owned or + * freely licensable by each licensor hereunder covering either (i) the + * unmodified Software as contributed to or provided by such licensor, or (ii) + * the Larger Works (as defined below), to deal in both + * + * (a) the Software, and + * + * (b) any piece of software and/or hardware listed in the lrgrwrks.txt file if + * one is included with the Software each a "Larger Work" to which the Software + * is contributed by such licensors), + * + * without restriction, including without limitation the rights to copy, create + * derivative works of, display, perform, and distribute the Software and make, + * use, sell, offer for sale, import, export, have made, and have sold the + * Software and the Larger Work(s), and to sublicense the foregoing rights on + * either these or other terms. + * + * This license is subject to the following condition: + * + * The above copyright notice and either this complete permission notice or at a + * minimum a reference to the UPL must be included in all copies or substantial + * portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +package com.oracle.truffle.api.test.polyglot; + +import org.graalvm.polyglot.Context; +import org.graalvm.polyglot.HostAccess; +import org.junit.Assert; +import org.junit.Test; + +import com.oracle.truffle.api.ContextThreadLocal; +import com.oracle.truffle.api.TruffleLanguage; +import com.oracle.truffle.api.interop.InteropLibrary; +import com.oracle.truffle.api.nodes.RootNode; +import com.oracle.truffle.api.test.common.AbstractExecutableTestLanguage; + +public class AutomaticLeaveTest { + + static class ThreadContext { + + } + + @TruffleLanguage.Registration + static class AutomaticLeaveInHostCallTestLanguage extends AbstractExecutableTestLanguage { + + final ContextThreadLocal threadContext = createContextThreadLocal((c, t) -> new ThreadContext()); + + @Override + protected Object execute(RootNode node, Env env, Object[] contextArguments, Object[] frameArguments) throws Exception { + if (contextArguments[0] != null) { + InteropLibrary.getUncached().invokeMember(contextArguments[0], "close"); + } + // If the close operation automatically leaves the explicitly entered context, then + // context thread local get fails. + threadContext.get(); + return null; + } + } + + public static class ContextCloser { + private final Context context; + + public ContextCloser(Context context) { + this.context = context; + } + + public void close() { + context.close(); + } + } + + @Test + public void testAutomaticLeave() { + try (Context context = Context.newBuilder().allowHostAccess(HostAccess.ALL).build()) { + context.enter(); + AbstractExecutableTestLanguage.evalTestLanguage(context, AutomaticLeaveInHostCallTestLanguage.class, "", new Object[]{null}); + Context.getCurrent(); + } + AbstractPolyglotTest.assertFails(Context::getCurrent, IllegalStateException.class, (e) -> Assert.assertTrue(e.getMessage().startsWith("No current context is available."))); + } + + @Test + public void testNoAutomaticLeaveInHostCall() { + try (Context context = Context.newBuilder().allowHostAccess(HostAccess.ALL).build()) { + context.enter(); + AbstractExecutableTestLanguage.evalTestLanguage(context, AutomaticLeaveInHostCallTestLanguage.class, "", new ContextCloser(context)); + Context.getCurrent(); + } + AbstractPolyglotTest.assertFails(Context::getCurrent, IllegalStateException.class, (e) -> Assert.assertTrue(e.getMessage().startsWith("No current context is available."))); + } +} diff --git a/truffle/src/com.oracle.truffle.api.test/src/com/oracle/truffle/api/test/polyglot/reflection.json b/truffle/src/com.oracle.truffle.api.test/src/com/oracle/truffle/api/test/polyglot/reflection.json index ad1528e57da18..165c096ae0185 100644 --- a/truffle/src/com.oracle.truffle.api.test/src/com/oracle/truffle/api/test/polyglot/reflection.json +++ b/truffle/src/com.oracle.truffle.api.test/src/com/oracle/truffle/api/test/polyglot/reflection.json @@ -216,5 +216,9 @@ { "name": "com.oracle.truffle.polyglot.PolyglotLanguageInstance", "allDeclaredFields": true, "allPublicFields": true + }, + { + "name": "com.oracle.truffle.api.test.polyglot.AutomaticLeaveTest$ContextCloser", + "allPublicMethods": true } ] diff --git a/truffle/src/com.oracle.truffle.polyglot/src/com/oracle/truffle/polyglot/PolyglotContextImpl.java b/truffle/src/com.oracle.truffle.polyglot/src/com/oracle/truffle/polyglot/PolyglotContextImpl.java index 9a15f2d0d072b..09664bb96820f 100644 --- a/truffle/src/com.oracle.truffle.polyglot/src/com/oracle/truffle/polyglot/PolyglotContextImpl.java +++ b/truffle/src/com.oracle.truffle.polyglot/src/com/oracle/truffle/polyglot/PolyglotContextImpl.java @@ -92,7 +92,6 @@ import com.oracle.truffle.api.CompilerDirectives; import com.oracle.truffle.api.CompilerDirectives.CompilationFinal; import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary; -import com.oracle.truffle.api.RootCallTarget; import com.oracle.truffle.api.ThreadLocalAction; import com.oracle.truffle.api.Truffle; import com.oracle.truffle.api.TruffleContext; @@ -1527,27 +1526,6 @@ static void printResult(PolyglotLanguageContext languageContext, Object result) } } - private static boolean isCurrentEngineHostCallback(PolyglotEngineImpl engine) { - RootNode topMostGuestToHostRootNode = Truffle.getRuntime().iterateFrames((f) -> { - RootNode root = ((RootCallTarget) f.getCallTarget()).getRootNode(); - if (EngineAccessor.HOST.isGuestToHostRootNode(root)) { - return root; - } - return null; - }); - if (topMostGuestToHostRootNode == null) { - return false; - } else { - PolyglotSharingLayer sharing = (PolyglotSharingLayer) EngineAccessor.NODES.getSharingLayer(topMostGuestToHostRootNode); - PolyglotEngineImpl rootEngine = sharing.engine; - if (rootEngine == engine) { - return true; - } else { - return false; - } - } - } - /** * Embedder close. */ @@ -2365,7 +2343,7 @@ synchronized void clearExplicitContextStack() { if (parent == null) { engine.polyglotHostService.notifyClearExplicitContextStack(this); } - if (isActive(Thread.currentThread()) && !isCurrentEngineHostCallback(engine)) { + if (isActive(Thread.currentThread()) && !engine.getImpl().getRootImpl().isInCurrentEngineHostCallback(engine)) { PolyglotThreadInfo threadInfo = getCurrentThreadInfo(); if (!threadInfo.explicitContextStack.isEmpty()) { PolyglotContextImpl c = this; diff --git a/truffle/src/com.oracle.truffle.polyglot/src/com/oracle/truffle/polyglot/PolyglotImpl.java b/truffle/src/com.oracle.truffle.polyglot/src/com/oracle/truffle/polyglot/PolyglotImpl.java index b228bd8f03ee4..42a6efdb2b7f3 100644 --- a/truffle/src/com.oracle.truffle.polyglot/src/com/oracle/truffle/polyglot/PolyglotImpl.java +++ b/truffle/src/com.oracle.truffle.polyglot/src/com/oracle/truffle/polyglot/PolyglotImpl.java @@ -81,11 +81,14 @@ import org.graalvm.polyglot.proxy.Proxy; import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary; +import com.oracle.truffle.api.RootCallTarget; +import com.oracle.truffle.api.Truffle; import com.oracle.truffle.api.TruffleFile; import com.oracle.truffle.api.TruffleLanguage; import com.oracle.truffle.api.TruffleOptions; import com.oracle.truffle.api.impl.DispatchOutputStream; import com.oracle.truffle.api.interop.TruffleObject; +import com.oracle.truffle.api.nodes.RootNode; import com.oracle.truffle.api.source.Source; import com.oracle.truffle.api.strings.TruffleString; import com.oracle.truffle.polyglot.PolyglotEngineImpl.LogConfig; @@ -519,6 +522,28 @@ public ThreadScope createThreadScope() { return null; } + @Override + public boolean isInCurrentEngineHostCallback(Object engine) { + RootNode topMostGuestToHostRootNode = Truffle.getRuntime().iterateFrames((f) -> { + RootNode root = ((RootCallTarget) f.getCallTarget()).getRootNode(); + if (EngineAccessor.HOST.isGuestToHostRootNode(root)) { + return root; + } + return null; + }); + if (topMostGuestToHostRootNode == null) { + return false; + } else { + PolyglotSharingLayer sharing = (PolyglotSharingLayer) EngineAccessor.NODES.getSharingLayer(topMostGuestToHostRootNode); + PolyglotEngineImpl rootEngine = sharing.engine; + if (rootEngine == engine) { + return true; + } else { + return false; + } + } + } + @Override public LogHandler newLogHandler(Object logHandlerOrStream) { return PolyglotLoggers.asLogHandler(this, logHandlerOrStream); From 70ea07c375abf34bb6a6eb9403354c37b8b7b58f Mon Sep 17 00:00:00 2001 From: Christian Haeubl Date: Tue, 31 Oct 2023 08:39:47 +0100 Subject: [PATCH 18/34] Fix crash during isolate teardown. (cherry picked from commit 514f292ba5835f92d91a9b2ac693c88767a82247) --- .../src/com/oracle/svm/core/Isolates.java | 1 + .../graal/snippets/CEntryPointSnippets.java | 57 ++++++++++++------- .../svm/core/thread/PlatformThreads.java | 1 + .../svm/core/thread/VMOperationControl.java | 2 +- 4 files changed, 38 insertions(+), 23 deletions(-) diff --git a/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/Isolates.java b/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/Isolates.java index 263203da68669..6d2ecb783f730 100644 --- a/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/Isolates.java +++ b/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/Isolates.java @@ -68,6 +68,7 @@ public class Isolates { * they have a single native state that does not distinguish between isolates). */ public static boolean isCurrentFirst() { + VMError.guarantee(isCurrentFirst != null); return isCurrentFirst; } diff --git a/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/graal/snippets/CEntryPointSnippets.java b/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/graal/snippets/CEntryPointSnippets.java index 4101185e60077..eb13eb2cdca30 100644 --- a/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/graal/snippets/CEntryPointSnippets.java +++ b/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/graal/snippets/CEntryPointSnippets.java @@ -200,8 +200,7 @@ public static int createIsolateSnippet(CEntryPointCreateIsolateParameters parame Safepoint.transitionNativeToJava(false); } - result = runtimeCallInitializeIsolate(INITIALIZE_ISOLATE, parameters); - return result; + return runtimeCallInitializeIsolate(INITIALIZE_ISOLATE, parameters); } @Uninterruptible(reason = "Thread state not yet set up.") @@ -276,15 +275,41 @@ public static boolean isIsolateInitialized() { return isolateInitialized; } + @Uninterruptible(reason = "Must be uninterruptible because thread state is not set up after leaveTearDownIsolate().") @SubstrateForeignCallTarget(stubCallingConvention = false) private static int initializeIsolate(CEntryPointCreateIsolateParameters parameters) { - boolean firstIsolate = false; + int result = initializeIsolateInterruptibly(parameters); + if (result != CEntryPointErrors.NO_ERROR) { + CEntryPointActions.leaveTearDownIsolate(); + /* Extra return is needed because of validation. */ + return result; + } + return result; + } + + @Uninterruptible(reason = "Used as a transition between uninterruptible and interruptible code", calleeMustBe = false) + private static int initializeIsolateInterruptibly(CEntryPointCreateIsolateParameters parameters) { + return initializeIsolateInterruptibly0(parameters); + } - final long initStateAddr = FIRST_ISOLATE_INIT_STATE.get().rawValue(); - int state = Unsafe.getUnsafe().getInt(initStateAddr); - if (state != FirstIsolateInitStates.SUCCESSFUL) { - firstIsolate = Unsafe.getUnsafe().compareAndSetInt(null, initStateAddr, FirstIsolateInitStates.UNINITIALIZED, FirstIsolateInitStates.IN_PROGRESS); - if (!firstIsolate) { + private static int initializeIsolateInterruptibly0(CEntryPointCreateIsolateParameters parameters) { + /* + * The VM operation thread must be started early as no VM operations can be scheduled before + * this thread is fully started. The isolate teardown may also use VM operations. + */ + if (VMOperationControl.useDedicatedVMOperationThread()) { + VMOperationControl.startVMOperationThread(); + } + + long initStateAddr = FIRST_ISOLATE_INIT_STATE.get().rawValue(); + boolean firstIsolate = Unsafe.getUnsafe().compareAndSetInt(null, initStateAddr, FirstIsolateInitStates.UNINITIALIZED, FirstIsolateInitStates.IN_PROGRESS); + + Isolates.setCurrentIsFirstIsolate(firstIsolate); + Isolates.setCurrentStartTime(); + + if (!firstIsolate) { + int state = Unsafe.getUnsafe().getInt(initStateAddr); + if (state != FirstIsolateInitStates.SUCCESSFUL) { while (state == FirstIsolateInitStates.IN_PROGRESS) { // spin-wait for first isolate PauseNode.pause(); state = Unsafe.getUnsafe().getIntVolatile(null, initStateAddr); @@ -294,16 +319,7 @@ private static int initializeIsolate(CEntryPointCreateIsolateParameters paramete } } } - Isolates.setCurrentIsFirstIsolate(firstIsolate); - - /* - * The VM operation thread must be started early as no VM operations can be scheduled before - * this thread is fully started. - */ - if (VMOperationControl.useDedicatedVMOperationThread()) { - VMOperationControl.startVMOperationThread(); - } - + /* * The reference handler thread must also be started early. Otherwise, it could happen that * the GC publishes pending references but there is no thread to process them. This could @@ -334,7 +350,6 @@ private static int initializeIsolate(CEntryPointCreateIsolateParameters paramete Log.logStream().println("error: " + e.getMessage()); System.exit(1); } else { - CEntryPointActions.leaveTearDownIsolate(); return CEntryPointErrors.ARGUMENT_PARSING_FAILED; } } @@ -346,12 +361,11 @@ private static int initializeIsolate(CEntryPointCreateIsolateParameters paramete boolean success = PlatformNativeLibrarySupport.singleton().initializeBuiltinLibraries(); if (firstIsolate) { // let other isolates (if any) initialize now - state = success ? FirstIsolateInitStates.SUCCESSFUL : FirstIsolateInitStates.FAILED; + int state = success ? FirstIsolateInitStates.SUCCESSFUL : FirstIsolateInitStates.FAILED; Unsafe.getUnsafe().putIntVolatile(null, initStateAddr, state); } if (!success) { - CEntryPointActions.leaveTearDownIsolate(); return CEntryPointErrors.ISOLATE_INITIALIZATION_FAILED; } @@ -369,7 +383,6 @@ private static int initializeIsolate(CEntryPointCreateIsolateParameters paramete } catch (Throwable t) { System.err.println("Uncaught exception while running initialization hooks:"); t.printStackTrace(); - CEntryPointActions.leaveTearDownIsolate(); return CEntryPointErrors.ISOLATE_INITIALIZATION_FAILED; } diff --git a/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/thread/PlatformThreads.java b/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/thread/PlatformThreads.java index d22e987f66af8..fd91ae3cfa1f9 100644 --- a/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/thread/PlatformThreads.java +++ b/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/thread/PlatformThreads.java @@ -1029,6 +1029,7 @@ static boolean compareAndSetThreadStatus(Thread thread, int expectedStatus, int } } + @Uninterruptible(reason = "Called from uninterruptible code.", mayBeInlined = true) static boolean isAlive(Thread thread) { int threadStatus = getThreadStatus(thread); return !(threadStatus == ThreadStatus.NEW || threadStatus == ThreadStatus.TERMINATED); diff --git a/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/thread/VMOperationControl.java b/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/thread/VMOperationControl.java index d857bcbb8e474..a17aa4afaac49 100644 --- a/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/thread/VMOperationControl.java +++ b/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/thread/VMOperationControl.java @@ -435,7 +435,7 @@ public IsolateThread getIsolateThread() { @Uninterruptible(reason = "Called from uninterruptible code.", mayBeInlined = true) public boolean isRunning() { - return isolateThread.isNonNull() && !stopped; + return PlatformThreads.isAlive(thread); } } From 9f43ac78d169b949bb1505d9ba15ea7095fe543b Mon Sep 17 00:00:00 2001 From: Christian Haeubl Date: Tue, 31 Oct 2023 11:04:04 +0100 Subject: [PATCH 19/34] Set IsolateThread to null after teardown. (cherry picked from commit 12e9a8b3ca1969729dfd68f4487b53cd9c0dce5a) --- .../oracle/svm/core/graal/snippets/CEntryPointSnippets.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/graal/snippets/CEntryPointSnippets.java b/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/graal/snippets/CEntryPointSnippets.java index eb13eb2cdca30..af7327cec9f5d 100644 --- a/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/graal/snippets/CEntryPointSnippets.java +++ b/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/graal/snippets/CEntryPointSnippets.java @@ -88,6 +88,7 @@ import com.oracle.svm.core.graal.nodes.CEntryPointEnterNode; import com.oracle.svm.core.graal.nodes.CEntryPointLeaveNode; import com.oracle.svm.core.graal.nodes.CEntryPointUtilityNode; +import com.oracle.svm.core.graal.nodes.WriteCurrentVMThreadNode; import com.oracle.svm.core.heap.Heap; import com.oracle.svm.core.heap.PhysicalMemory; import com.oracle.svm.core.heap.ReferenceHandler; @@ -305,7 +306,6 @@ private static int initializeIsolateInterruptibly0(CEntryPointCreateIsolateParam boolean firstIsolate = Unsafe.getUnsafe().compareAndSetInt(null, initStateAddr, FirstIsolateInitStates.UNINITIALIZED, FirstIsolateInitStates.IN_PROGRESS); Isolates.setCurrentIsFirstIsolate(firstIsolate); - Isolates.setCurrentStartTime(); if (!firstIsolate) { int state = Unsafe.getUnsafe().getInt(initStateAddr); @@ -319,7 +319,6 @@ private static int initializeIsolateInterruptibly0(CEntryPointCreateIsolateParam } } } - /* * The reference handler thread must also be started early. Otherwise, it could happen that * the GC publishes pending references but there is no thread to process them. This could @@ -519,6 +518,7 @@ private static int tearDownIsolate() { int result = Isolates.tearDownCurrent(); // release the heap memory associated with final isolate thread VMThreads.singleton().freeIsolateThread(finalThread); + WriteCurrentVMThreadNode.writeCurrentVMThread(WordFactory.nullPointer()); return result; } catch (Throwable t) { return reportException(t); From 1b723bb9027c6fecad1923ebb35e7d3396e47816 Mon Sep 17 00:00:00 2001 From: Martin Entlicher Date: Mon, 13 Nov 2023 00:20:08 +0100 Subject: [PATCH 20/34] Upgrade org.json to version 20231013. (GR-50058) --- truffle/mx.truffle/suite.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/truffle/mx.truffle/suite.py b/truffle/mx.truffle/suite.py index 1eaa8751cf529..a575c55cd011d 100644 --- a/truffle/mx.truffle/suite.py +++ b/truffle/mx.truffle/suite.py @@ -142,10 +142,10 @@ }, "TruffleJSON" : { - "urls" : ["https://lafo.ssw.uni-linz.ac.at/pub/graal-external-deps/trufflejson-20230227.jar"], - "digest" : "sha512:2b48819e94ca82472ffbdd3befc214351e1cfd0f87eb97d4aed092b48f11b53a7d82a637b008e022254781d2439aefe45ca4794eea8ad05de69934c5317c9a27", - "sourceUrls": ["https://lafo.ssw.uni-linz.ac.at/pub/graal-external-deps/trufflejson-20230227-src.jar"], - "sourceDigest" : "sha512:ecf08ea386398a9834f560e0afbb1bc2630037e3b170fe6d5c60e23ed4e198072cec2cd3569bdc1cae22318cd5fb97123dc5bb6d1e138c08f8d5c612f486956a", + "urls" : ["https://lafo.ssw.uni-linz.ac.at/pub/graal-external-deps/trufflejson-20231013.jar"], + "digest" : "sha512:35a51c5deb0a3e3690b6d1d3d84682bc5e43b2fba1f1611d456526664667532103eb6efff6b2ea9eaedd099c9429f2b661ccbab44b681a031bdbb3e9758da949", + "sourceUrls": ["https://lafo.ssw.uni-linz.ac.at/pub/graal-external-deps/trufflejson-20231013-src.jar"], + "sourceDigest" : "sha512:24e7276d1ac030297ff1c6a0ff2f2604ab5949af916f827efb677839d537aaf304bbf355dbb223f8a1ecebddb21e4b2a8e2dd87039e4816115a0e9568230fbf6", }, "VISUALVM-LIB-JFLUID-HEAP" : { From 20b47bace78e79b738cd5fa425b06972559e3318 Mon Sep 17 00:00:00 2001 From: Anas El korchi Date: Tue, 14 Nov 2023 14:46:09 +0100 Subject: [PATCH 21/34] [GR-49794] Merge tag jdk-17.0.10+4. --- common.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/common.json b/common.json index 07a251a455ff5..0a931c9de3cf1 100644 --- a/common.json +++ b/common.json @@ -14,9 +14,9 @@ "labsjdk-ce-17": {"name": "labsjdk", "version": "ce-17.0.9+9-jvmci-23.0-b22", "platformspecific": true }, "labsjdk-ce-17Debug": {"name": "labsjdk", "version": "ce-17.0.9+9-jvmci-23.0-b22-debug", "platformspecific": true }, "labsjdk-ce-17-llvm": {"name": "labsjdk", "version": "ce-17.0.9+9-jvmci-23.0-b22-sulong", "platformspecific": true }, - "labsjdk-ee-17": {"name": "labsjdk", "version": "ee-17.0.9+11-jvmci-23.0-b21", "platformspecific": true }, - "labsjdk-ee-17Debug": {"name": "labsjdk", "version": "ee-17.0.9+11-jvmci-23.0-b21-debug", "platformspecific": true }, - "labsjdk-ee-17-llvm": {"name": "labsjdk", "version": "ee-17.0.9+11-jvmci-23.0-b21-sulong", "platformspecific": true }, + "labsjdk-ee-17": {"name": "labsjdk", "version": "ee-17.0.10+4-jvmci-23.0-b23", "platformspecific": true }, + "labsjdk-ee-17Debug": {"name": "labsjdk", "version": "ee-17.0.10+4-jvmci-23.0-b23-debug", "platformspecific": true }, + "labsjdk-ee-17-llvm": {"name": "labsjdk", "version": "ee-17.0.10+4-jvmci-23.0-b23-sulong", "platformspecific": true }, "oraclejdk19": {"name": "jpg-jdk", "version": "19", "build_id": "26", "release": true, "platformspecific": true, "extrabundles": ["static-libs"]}, "labsjdk-ce-19": {"name": "labsjdk", "version": "ce-19.0.1+10-jvmci-23.0-b04", "platformspecific": true }, From 5b3e05434329329fb0434281772ab3e02c6410f7 Mon Sep 17 00:00:00 2001 From: Bernhard Urban-Forster Date: Wed, 6 Sep 2023 15:57:26 +0200 Subject: [PATCH 22/34] [GR-43389] [darwin-amd64] Workaround for buggy ld64 versions Some versions of `ld64` cannot deal with DIRECT8 relocations in the `.text` section. Approximately this is since version 820.1 (Xcode 14). Starting with Xcode15 beta3 the default linker has been replaced with "the new linker" (version 902.11) which does not suffer from this bug anymore. However, Xcode also ships a `ld-classic` which reassembles "the old linker" and is still affected by this bug (and it of course prints the same version number). See some more in-depth analysis of this ld64 bug in https://openradar.appspot.com/FB11942354 The workaround: Instead of emitting the address of a HostedMethod inlined, it will be put in the data section and thus requires a memory load to obtain it. (cherry picked from commit e30698b53f00a021fce8e7be17da960fcb4a262a) resolve conflicts resolve errors backport fixup --- .../AMD64LoadMethodPointerConstantOp.java | 12 +++++-- .../core/graal/code/SubstrateDataBuilder.java | 35 ++++++++++++++----- .../oracle/svm/hosted/code/CompileQueue.java | 29 +++++++++++---- .../code/amd64/AMD64HostedPatcherFeature.java | 1 + .../hosted/image/NativeImageCodeCache.java | 6 ++-- .../hosted/image/NativeImageHeapWriter.java | 18 ++++++++-- 6 files changed, 77 insertions(+), 24 deletions(-) diff --git a/substratevm/src/com.oracle.svm.core.graal.amd64/src/com/oracle/svm/core/graal/amd64/AMD64LoadMethodPointerConstantOp.java b/substratevm/src/com.oracle.svm.core.graal.amd64/src/com/oracle/svm/core/graal/amd64/AMD64LoadMethodPointerConstantOp.java index 46ec57d7ab269..df38fd162b75a 100644 --- a/substratevm/src/com.oracle.svm.core.graal.amd64/src/com/oracle/svm/core/graal/amd64/AMD64LoadMethodPointerConstantOp.java +++ b/substratevm/src/com.oracle.svm.core.graal.amd64/src/com/oracle/svm/core/graal/amd64/AMD64LoadMethodPointerConstantOp.java @@ -28,6 +28,8 @@ import static org.graalvm.compiler.lir.LIRInstruction.OperandFlag.HINT; import static org.graalvm.compiler.lir.LIRInstruction.OperandFlag.REG; +import com.oracle.svm.core.FrameAccess; +import org.graalvm.compiler.asm.amd64.AMD64Address; import org.graalvm.compiler.asm.amd64.AMD64MacroAssembler; import org.graalvm.compiler.lir.LIRInstructionClass; import org.graalvm.compiler.lir.StandardOp; @@ -38,6 +40,7 @@ import jdk.vm.ci.code.Register; import jdk.vm.ci.meta.AllocatableValue; +import org.graalvm.nativeimage.Platform; public final class AMD64LoadMethodPointerConstantOp extends AMD64LIRInstruction implements StandardOp.LoadConstantOp { public static final LIRInstructionClass TYPE = LIRInstructionClass.create(AMD64LoadMethodPointerConstantOp.class); @@ -53,8 +56,13 @@ public final class AMD64LoadMethodPointerConstantOp extends AMD64LIRInstruction @Override public void emitCode(CompilationResultBuilder crb, AMD64MacroAssembler masm) { Register resultReg = asRegister(result); - crb.recordInlineDataInCode(constant); - masm.movq(resultReg, 0L, true); + if (!Platform.includedIn(Platform.DARWIN_AMD64.class)) { + crb.recordInlineDataInCode(constant); + masm.movq(resultReg, 0L, true); + } else { + /* [GR-43389] ld64 bug does not allow direct8 relocations in .text on darwin */ + masm.movq(resultReg, (AMD64Address) crb.recordDataReferenceInCode(constant, FrameAccess.wordSize())); + } } @Override diff --git a/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/graal/code/SubstrateDataBuilder.java b/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/graal/code/SubstrateDataBuilder.java index 5db22aa8dab51..ac7c5bde7dbb5 100644 --- a/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/graal/code/SubstrateDataBuilder.java +++ b/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/graal/code/SubstrateDataBuilder.java @@ -28,9 +28,12 @@ import java.nio.ByteBuffer; +import com.oracle.svm.core.meta.SubstrateMethodPointerConstant; import org.graalvm.compiler.code.DataSection.Data; import org.graalvm.compiler.code.DataSection.Patches; import org.graalvm.compiler.lir.asm.DataBuilder; +import org.graalvm.compiler.core.common.type.CompressibleConstant; +import org.graalvm.compiler.core.common.type.TypedConstant; import com.oracle.svm.core.FrameAccess; import com.oracle.svm.core.SubstrateOptions; @@ -48,9 +51,13 @@ public class SubstrateDataBuilder extends DataBuilder { @Override public Data createDataItem(Constant constant) { int size; - if (constant instanceof VMConstant) { - assert constant instanceof SubstrateObjectConstant : "should be only VMConstant"; - return new ObjectData((SubstrateObjectConstant) constant); + + if (constant instanceof SubstrateMethodPointerConstant methodPointerConstant) { + size = FrameAccess.wordSize(); + return new ObjectData(size, size, methodPointerConstant); + } else if (constant instanceof VMConstant vmConstant) { + assert constant instanceof CompressibleConstant && constant instanceof TypedConstant : constant; + return new ObjectData(vmConstant); } else if (JavaConstant.isNull(constant)) { if (SubstrateObjectConstant.isCompressed((JavaConstant) constant)) { size = ConfigurationValues.getObjectLayout().getReferenceSize(); @@ -58,16 +65,15 @@ public Data createDataItem(Constant constant) { size = FrameAccess.uncompressedReferenceSize(); } return createZeroData(size, size); - } else if (constant instanceof SerializableConstant) { - SerializableConstant s = (SerializableConstant) constant; - return createSerializableData(s); + } else if (constant instanceof SerializableConstant serializableConstant) { + return createSerializableData(serializableConstant); } else { throw new JVMCIError(String.valueOf(constant)); } } public static class ObjectData extends Data { - private final SubstrateObjectConstant constant; + private final VMConstant constant; protected ObjectData(SubstrateObjectConstant constant) { super(ConfigurationValues.getObjectLayout().getReferenceSize(), ConfigurationValues.getObjectLayout().getReferenceSize()); @@ -75,7 +81,18 @@ protected ObjectData(SubstrateObjectConstant constant) { this.constant = constant; } - public SubstrateObjectConstant getConstant() { + protected ObjectData(int alignment, int size, VMConstant constant) { + super(alignment, size); + this.constant = constant; + } + + protected ObjectData(VMConstant constant) { + this(ConfigurationValues.getObjectLayout().getReferenceSize(), ConfigurationValues.getObjectLayout().getReferenceSize(), constant); + assert ((CompressibleConstant) constant).isCompressed() == ReferenceAccess.singleton() + .haveCompressedReferences() : "Constant object references in compiled code must be compressed (base-relative)"; + } + + public VMConstant getConstant() { return constant; } @@ -85,7 +102,7 @@ protected void emit(ByteBuffer buffer, Patches patches) { if (getSize() == Integer.BYTES) { buffer.putInt(0); } else if (getSize() == Long.BYTES) { - buffer.putLong(0L); + buffer.putLong(0); } else { shouldNotReachHere("Unsupported object constant reference size: " + getSize()); } diff --git a/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/code/CompileQueue.java b/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/code/CompileQueue.java index 06c186da5c9d6..0d5a14f9c650b 100644 --- a/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/code/CompileQueue.java +++ b/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/code/CompileQueue.java @@ -39,6 +39,7 @@ import java.util.concurrent.ConcurrentMap; import java.util.concurrent.ForkJoinPool; +import com.oracle.svm.core.graal.code.SubstrateDataBuilder; import org.graalvm.collections.EconomicMap; import org.graalvm.compiler.api.replacements.Fold; import org.graalvm.compiler.api.replacements.SnippetReflectionProvider; @@ -122,7 +123,6 @@ import com.oracle.svm.core.graal.phases.OptimizeExceptionPathsPhase; import com.oracle.svm.core.heap.RestrictHeapAccess; import com.oracle.svm.core.heap.RestrictHeapAccessCallees; -import com.oracle.svm.core.meta.MethodPointer; import com.oracle.svm.core.meta.SubstrateMethodPointerConstant; import com.oracle.svm.core.util.InterruptImageBuilding; import com.oracle.svm.core.util.VMError; @@ -151,6 +151,7 @@ import jdk.vm.ci.meta.MetaAccessProvider; import jdk.vm.ci.meta.ResolvedJavaMethod; import jdk.vm.ci.meta.VMConstant; +import org.graalvm.nativeimage.Platform; public class CompileQueue { @@ -1336,15 +1337,29 @@ protected void removeDeoptTargetOptimizations(LIRSuites lirSuites) { DeoptimizationUtils.removeDeoptTargetOptimizations(lirSuites); } + private void ensureCompiledForMethodPointerConstant(HostedMethod method, CompileReason reason, SubstrateMethodPointerConstant methodPointerConstant) { + HostedMethod referencedMethod = (HostedMethod) methodPointerConstant.pointer().getMethod(); + ensureCompiled(referencedMethod, new MethodPointerConstantReason(method, referencedMethod, reason)); + } + protected final void ensureCompiledForMethodPointerConstants(HostedMethod method, CompileReason reason, CompilationResult result) { for (DataPatch dataPatch : result.getDataPatches()) { Reference reference = dataPatch.reference; - if (reference instanceof ConstantReference) { - VMConstant constant = ((ConstantReference) reference).getConstant(); - if (constant instanceof SubstrateMethodPointerConstant) { - MethodPointer pointer = ((SubstrateMethodPointerConstant) constant).pointer(); - HostedMethod referencedMethod = (HostedMethod) pointer.getMethod(); - ensureCompiled(referencedMethod, new MethodPointerConstantReason(method, referencedMethod, reason)); + if (reference instanceof ConstantReference constantReference) { + VMConstant vmConstant = constantReference.getConstant(); + if (vmConstant instanceof SubstrateMethodPointerConstant methodPointerConstant) { + ensureCompiledForMethodPointerConstant(method, reason, methodPointerConstant); + } + } + } + + for (DataSection.Data data : result.getDataSection()) { + if (data instanceof SubstrateDataBuilder.ObjectData objectData) { + VMConstant vmConstant = objectData.getConstant(); + if (vmConstant instanceof SubstrateMethodPointerConstant methodPointerConstant) { + /* [GR-43389] Only reachable with ld64 workaround on */ + VMError.guarantee(Platform.includedIn(Platform.DARWIN_AMD64.class)); + ensureCompiledForMethodPointerConstant(method, reason, methodPointerConstant); } } } diff --git a/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/code/amd64/AMD64HostedPatcherFeature.java b/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/code/amd64/AMD64HostedPatcherFeature.java index 6b341a19d53cc..8258907c0d204 100644 --- a/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/code/amd64/AMD64HostedPatcherFeature.java +++ b/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/code/amd64/AMD64HostedPatcherFeature.java @@ -126,6 +126,7 @@ public void relocate(Reference ref, RelocatableBuffer relocs, int compStart) { VMConstant constant = ((ConstantReference) ref).getConstant(); Object relocVal = ref; if (constant instanceof SubstrateMethodPointerConstant) { + VMError.guarantee(!Platform.includedIn(Platform.DARWIN_AMD64.class), "[GR-43389] method pointer relocations should not be inlined."); MethodPointer pointer = ((SubstrateMethodPointerConstant) constant).pointer(); HostedMethod hMethod = (HostedMethod) pointer.getMethod(); VMError.guarantee(hMethod.isCompiled(), "Method %s is not compiled although there is a method pointer constant created for it.", hMethod); 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 2ec6df5486d7f..f11b8a8d5ddbe 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 @@ -182,7 +182,7 @@ public void layoutConstants() { CompilationResult compilation = pair.getRight(); for (DataSection.Data data : compilation.getDataSection()) { if (data instanceof SubstrateDataBuilder.ObjectData) { - JavaConstant constant = ((SubstrateDataBuilder.ObjectData) data).getConstant(); + VMConstant constant = ((SubstrateDataBuilder.ObjectData) data).getConstant(); constantReasons.put(constant, compilation.getName()); } } @@ -202,7 +202,7 @@ public void layoutConstants() { public void addConstantsToHeap() { for (DataSection.Data data : dataSection) { if (data instanceof SubstrateDataBuilder.ObjectData) { - JavaConstant constant = ((SubstrateDataBuilder.ObjectData) data).getConstant(); + VMConstant constant = ((SubstrateDataBuilder.ObjectData) data).getConstant(); addConstantToHeap(constant, NativeImageHeap.HeapInclusionReason.DataSection); } } @@ -567,7 +567,7 @@ protected boolean verifyMethods(CodeInfoEncoder codeInfoEncoder, CodeInfo codeIn public void writeConstants(NativeImageHeapWriter writer, RelocatableBuffer buffer) { ByteBuffer bb = buffer.getByteBuffer(); dataSection.buildDataSection(bb, (position, constant) -> { - writer.writeReference(buffer, position, (JavaConstant) constant, "VMConstant: " + constant); + writer.writeReference(buffer, position, constant, "VMConstant: " + constant); }); } diff --git a/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/image/NativeImageHeapWriter.java b/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/image/NativeImageHeapWriter.java index 2f3d015df53ba..f7662169cfa8f 100644 --- a/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/image/NativeImageHeapWriter.java +++ b/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/image/NativeImageHeapWriter.java @@ -31,11 +31,14 @@ import java.nio.ByteBuffer; import com.oracle.graal.pointsto.heap.ImageHeapConstant; +import com.oracle.svm.core.meta.SubstrateMethodPointerConstant; +import jdk.vm.ci.meta.Constant; import org.graalvm.compiler.core.common.CompressEncoding; import org.graalvm.compiler.core.common.NumUtil; import org.graalvm.compiler.debug.DebugContext; import org.graalvm.compiler.debug.Indent; import org.graalvm.nativeimage.ImageSingletons; +import org.graalvm.nativeimage.Platform; import org.graalvm.nativeimage.c.function.CFunctionPointer; import org.graalvm.nativeimage.c.function.RelocatedPointer; import org.graalvm.word.WordBase; @@ -164,10 +167,16 @@ private void write(RelocatableBuffer buffer, int index, JavaConstant con, Object private final boolean useHeapBase = NativeImageHeap.useHeapBase(); private final CompressEncoding compressEncoding = ImageSingletons.lookup(CompressEncoding.class); - void writeReference(RelocatableBuffer buffer, int index, JavaConstant target, Object reason) { - assert !(heap.getMetaAccess().isInstanceOf(target, WordBase.class)) : "word values are not references"; + void writeReference(RelocatableBuffer buffer, int index, Constant constant, Object reason) { mustBeReferenceAligned(index); - if (target.isNonNull()) { + + if (constant instanceof JavaConstant target) { + assert !(heap.getMetaAccess().isInstanceOf(target, WordBase.class)) : "word values are not references"; + + if (target.isNull()) { + return; + } + ObjectInfo targetInfo = heap.getConstantInfo(target); verifyTargetDidNotChange(target, reason, targetInfo); if (useHeapBase) { @@ -176,6 +185,9 @@ void writeReference(RelocatableBuffer buffer, int index, JavaConstant target, Ob } else { addDirectRelocationWithoutAddend(buffer, index, referenceSize(), SubstrateObjectConstant.asObject(target)); } + } else { + assert Platform.includedIn(Platform.DARWIN_AMD64.class) : "[GR-43389] Workaround for ld64 bug that does not allow direct8 relocations in .text on amd64"; + buffer.addRelocationWithoutAddend(index, ObjectFile.RelocationKind.DIRECT_8, ((SubstrateMethodPointerConstant) constant).pointer()); } } From 6d973dd030e2a7e55dcc4a98fada1d00eae4ff6d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gerg=C3=B6=20Barany?= Date: Tue, 31 Oct 2023 22:14:56 +0100 Subject: [PATCH 23/34] Clarify semantics of binary arithmetic reassociation (cherry picked from commit 6f027194aef5d8818ee91cdd33c3b39dfec59b87) fix error add back method isAssociative() remove unused imports fix formatting issues --- .../core/common/type/IntegerStamp.java | 4 +- .../nodes/calc/BinaryArithmeticNode.java | 58 ++++++++++++++----- .../graalvm/compiler/nodes/calc/SubNode.java | 9 ++- .../graalvm/compiler/nodes/loop/LoopEx.java | 2 +- .../phases/common/ReassociationPhase.java | 7 +-- 5 files changed, 52 insertions(+), 28 deletions(-) diff --git a/compiler/src/org.graalvm.compiler.core.common/src/org/graalvm/compiler/core/common/type/IntegerStamp.java b/compiler/src/org.graalvm.compiler.core.common/src/org/graalvm/compiler/core/common/type/IntegerStamp.java index c3d64a59838ad..db304041b0caf 100644 --- a/compiler/src/org.graalvm.compiler.core.common/src/org/graalvm/compiler/core/common/type/IntegerStamp.java +++ b/compiler/src/org.graalvm.compiler.core.common/src/org/graalvm/compiler/core/common/type/IntegerStamp.java @@ -1095,7 +1095,7 @@ public boolean isNeutral(Constant value) { } }, - new BinaryOp.Sub(true, false) { + new BinaryOp.Sub(false, false) { @Override public Constant foldConstant(Constant const1, Constant const2) { @@ -1487,7 +1487,7 @@ private long multiplyHighUnsigned(long x, long y, JavaKind javaKind) { } }, - new BinaryOp.Div(true, false) { + new BinaryOp.Div(false, false) { @Override public Constant foldConstant(Constant const1, Constant const2) { diff --git a/compiler/src/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/calc/BinaryArithmeticNode.java b/compiler/src/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/calc/BinaryArithmeticNode.java index 73ebb3dfe68e5..19a04aad138ae 100644 --- a/compiler/src/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/calc/BinaryArithmeticNode.java +++ b/compiler/src/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/calc/BinaryArithmeticNode.java @@ -48,7 +48,7 @@ import org.graalvm.compiler.nodes.extended.GuardedNode; import org.graalvm.compiler.nodes.spi.ArithmeticLIRLowerable; import org.graalvm.compiler.nodes.spi.NodeValueMap; - +import org.graalvm.compiler.core.common.type.ArithmeticStamp; import jdk.vm.ci.meta.Constant; @NodeInfo(cycles = CYCLES_1, size = SIZE_1) @@ -107,8 +107,7 @@ public ValueNode canonical(CanonicalizerTool tool, ValueNode forX, ValueNode for * (cond ? 95 : 105) */ // @formatter:on - return ConditionalNode.create(conditionalNode.condition, trueConstant, - falseConstant, view); + return ConditionalNode.create(conditionalNode.condition, trueConstant, falseConstant, view); } } } @@ -249,7 +248,7 @@ private static ReassociateMatch findReassociate(BinaryArithmeticNode parent, } private static boolean isReassociative(BinaryArithmeticNode parent, ValueNode child) { - if (!parent.isAssociative()) { + if (!parent.mayReassociate()) { return false; } if (isNonExactAddOrSub(parent)) { @@ -258,18 +257,50 @@ private static boolean isReassociative(BinaryArithmeticNode parent, ValueNode return child.getClass() == parent.getClass(); } + /** + * Determines whether this operation may be reassociated in the sense of + * {@link #reassociateUnmatchedValues} and {@link #reassociateMatchedValues}. These methods can + * perform transformations like {@code (a * 2) * b => (a * b) * 2}. In general, these + * transformations require the binary operation to be both {@linkplain BinaryOp#isAssociative() + * associative} to allow shifting of parentheses and {@linkplain BinaryOp#isCommutative() + * commutative} to allow changing the order of the operands. + *

+ * As a special case, subtraction on integers allows certain similar transformations, especially + * in expressions where it is mixed with addition. For example, + * {@link #reassociateUnmatchedValues} can transform {@code x + (C - y) -> (x - y) + C}, and + * {@link SubNode#canonical(CanonicalizerTool, ValueNode, ValueNode)} can transform + * {@code a - (a + b) -> -b}. Therefore this method returns {@code true} for integer + * subtraction. Users of this method must still check if the operation in question is + * subtraction and ensure that they only reassociate subtractions in sound ways. Floating-point + * subtraction does not permit such mathematically sound transformations due to rounding errors. + */ + public boolean mayReassociate() { + return mayReassociate(getArithmeticOp(), stamp(NodeView.DEFAULT)); + } + + /** + * Determines whether the {@code op} may be reassociated in the sense of + * {@link #reassociateUnmatchedValues} and {@link #reassociateMatchedValues}. + * + * @see #mayReassociate() + */ + public static boolean mayReassociate(BinaryOp op, Stamp stamp) { + return (op.isAssociative() && op.isCommutative()) || (stamp.isIntegerStamp() && op.equals(((ArithmeticStamp) stamp).getOps().getSub())); + } + /** * Tries to push down values which satisfy the criterion. This is an assistant function for * {@linkplain BinaryArithmeticNode#reassociateMatchedValues} reassociateMatchedValues}. For * example with a constantness criterion: {@code (a * 2) * b => (a * b) * 2} * - * This method accepts only {@linkplain BinaryOp#isAssociative() associative} operations such as - * +, -, *, &, | and ^ + * This method accepts only {@linkplain #mayReassociate() operations that allow reassociation} + * such as +, -, *, &, |, ^, min, and max. */ public static ValueNode reassociateUnmatchedValues(BinaryArithmeticNode node, NodePredicate criterion, NodeView view) { ValueNode forX = node.getX(); ValueNode forY = node.getY(); - assert node.getOp(forX, forY).isAssociative(); + BinaryOp op = node.getOp(forX, forY); + GraalError.guarantee(node.mayReassociate(), "%s: binary op %s does not satisfy precondition of reassociateUnmatchedValues", node, op); // No need to re-associate if one of the operands has matched the criterion. if (criterion.apply(forX) || criterion.apply(forY)) { @@ -394,14 +425,15 @@ public static ValueNode reassociateUnmatchedValues(BinaryArithmeticNode node, * Tries to re-associate values which satisfy the criterion. For example with a constantness * criterion: {@code (a + 2) + 1 => a + (1 + 2)} *

- * This method accepts only {@linkplain BinaryOp#isAssociative() associative} operations such as - * +, -, *, &, |, ^, min, max + * This method accepts only {@linkplain #mayReassociate() operations that allow reassociation} + * such as +, -, *, &, |, ^, min, and max. * * @param forY * @param forX */ public static ValueNode reassociateMatchedValues(BinaryArithmeticNode node, NodePredicate criterion, ValueNode forX, ValueNode forY, NodeView view) { - assert node.getOp(forX, forY).isAssociative(); + BinaryOp op = node.getOp(forX, forY); + GraalError.guarantee(node.mayReassociate(), "%s: binary op %s does not satisfy precondition of reassociateMatchedValues", node, op); ReassociateMatch match1 = findReassociate(node, criterion); if (match1 == null) { return node; @@ -481,12 +513,6 @@ public static ValueNode reassociateMatchedValues(BinaryArithmeticNode node, N return MaxNode.create(a, MaxNode.create(m1, m2, view), view); } else if (node instanceof MinNode) { return MinNode.create(a, MinNode.create(m1, m2, view), view); - } else if (node instanceof SignedFloatingIntegerDivNode) { - return SignedFloatingIntegerDivNode.create(a, SignedFloatingIntegerDivNode.create(m1, m2, view, null, ((FloatingIntegerDivRemNode) node).divisionOverflowIsJVMSCompliant()), view, null, - ((FloatingIntegerDivRemNode) node).divisionOverflowIsJVMSCompliant()); - } else if (node instanceof SignedFloatingIntegerRemNode) { - return SignedFloatingIntegerRemNode.create(a, SignedFloatingIntegerRemNode.create(m1, m2, view, null, ((FloatingIntegerDivRemNode) node).divisionOverflowIsJVMSCompliant()), view, null, - ((FloatingIntegerDivRemNode) node).divisionOverflowIsJVMSCompliant()); } else { throw GraalError.shouldNotReachHere("unhandled node in reassociation with matched values: " + node); // ExcludeFromJacocoGeneratedReport } diff --git a/compiler/src/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/calc/SubNode.java b/compiler/src/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/calc/SubNode.java index 63053733cffe3..e44309a8d542f 100644 --- a/compiler/src/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/calc/SubNode.java +++ b/compiler/src/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/calc/SubNode.java @@ -39,7 +39,6 @@ import org.graalvm.compiler.nodes.spi.CanonicalizerTool; import org.graalvm.compiler.nodes.spi.NodeLIRBuilderTool; import org.graalvm.compiler.nodes.util.GraphUtil; - import jdk.vm.ci.meta.Constant; import jdk.vm.ci.meta.PrimitiveConstant; @@ -79,8 +78,8 @@ private static ValueNode canonical(SubNode subNode, BinaryOp op, Stamp stam return ConstantNode.forPrimitive(stamp, zero); } } - boolean associative = op.isAssociative(); - if (associative) { + boolean mayReassociate = BinaryArithmeticNode.mayReassociate(op, stamp); + if (mayReassociate) { if (forX instanceof AddNode) { AddNode x = (AddNode) forX; if (x.getY() == forY) { @@ -129,7 +128,7 @@ private static ValueNode canonical(SubNode subNode, BinaryOp op, Stamp stam if (op.isNeutral(c)) { return forX; } - if (associative && self != null) { + if (mayReassociate && self != null) { ValueNode reassociated = reassociateMatchedValues(self, ValueNode.isConstantPredicate(), forX, forY, view); if (reassociated != self) { return reassociated; @@ -153,7 +152,7 @@ private static ValueNode canonical(SubNode subNode, BinaryOp op, Stamp stam */ return NegateNode.create(forY, view); } - if (associative && self != null) { + if (mayReassociate && self != null) { return reassociateMatchedValues(self, ValueNode.isConstantPredicate(), forX, forY, view); } } diff --git a/compiler/src/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/loop/LoopEx.java b/compiler/src/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/loop/LoopEx.java index 13e798cfdb42c..a5052d7dc47c3 100644 --- a/compiler/src/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/loop/LoopEx.java +++ b/compiler/src/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/loop/LoopEx.java @@ -231,7 +231,7 @@ public boolean reassociateInvariants() { InvariantPredicate invariant = new InvariantPredicate(); NodeBitMap newLoopNodes = graph.createNodeBitMap(); for (BinaryArithmeticNode binary : whole().nodes().filter(BinaryArithmeticNode.class)) { - if (!binary.isAssociative()) { + if (!binary.mayReassociate()) { continue; } ValueNode result = BinaryArithmeticNode.reassociateMatchedValues(binary, invariant, binary.getX(), binary.getY(), NodeView.DEFAULT); diff --git a/compiler/src/org.graalvm.compiler.phases.common/src/org/graalvm/compiler/phases/common/ReassociationPhase.java b/compiler/src/org.graalvm.compiler.phases.common/src/org/graalvm/compiler/phases/common/ReassociationPhase.java index c4945d4414857..a75f75d2405df 100644 --- a/compiler/src/org.graalvm.compiler.phases.common/src/org/graalvm/compiler/phases/common/ReassociationPhase.java +++ b/compiler/src/org.graalvm.compiler.phases.common/src/org/graalvm/compiler/phases/common/ReassociationPhase.java @@ -48,12 +48,11 @@ import org.graalvm.compiler.nodes.util.GraphUtil; import org.graalvm.compiler.phases.BasePhase; import org.graalvm.compiler.phases.common.util.EconomicSetNodeEventListener; - import jdk.vm.ci.meta.PrimitiveConstant; /** - * Rearrange {@link BinaryArithmeticNode#isAssociative() associative binary operations} for loop - * invariants and constants. + * Rearrange binary arithmetic operations that {@linkplain BinaryArithmeticNode#mayReassociate() may + * be reassociated} for loop invariants and constants. */ public class ReassociationPhase extends BasePhase { @@ -133,7 +132,7 @@ private static void reassociateConstants(StructuredGraph graph, CoreProviders co try (DebugContext.Scope s = debug.scope("ReassociateConstants")) { for (BinaryArithmeticNode binary : graph.getNodes().filter(BinaryArithmeticNode.class)) { // Skip re-associations to loop variant expressions. - if (!binary.isAssociative() || (!loopNodes.isNew(binary) && loopNodes.contains(binary))) { + if (!binary.mayReassociate() || (!loopNodes.isNew(binary) && loopNodes.contains(binary))) { continue; } ValueNode result = BinaryArithmeticNode.reassociateUnmatchedValues(binary, ValueNode.isConstantPredicate(), NodeView.DEFAULT); From 76c4213e1aa423ec38e31392af2abd4004291457 Mon Sep 17 00:00:00 2001 From: David Leopoldseder Date: Thu, 19 Oct 2023 15:25:29 +0200 Subject: [PATCH 24/34] loop unroll: handle stride overflow in int range (cherry picked from commit 8ef6f2e38d8d7234fedca99daf454274a3f60c3e) --- .../graalvm/compiler/core/common/NumUtil.java | 11 +++++ .../loop/phases/LoopTransformations.java | 21 +++++++--- .../loop/test/LoopPartialUnrollTest.java | 41 +++++++++++++++++++ .../nodes/loop/LoopFragmentInside.java | 3 +- 4 files changed, 70 insertions(+), 6 deletions(-) diff --git a/compiler/src/org.graalvm.compiler.core.common/src/org/graalvm/compiler/core/common/NumUtil.java b/compiler/src/org.graalvm.compiler.core.common/src/org/graalvm/compiler/core/common/NumUtil.java index 15b935770a25f..f1cc5b5328ef9 100644 --- a/compiler/src/org.graalvm.compiler.core.common/src/org/graalvm/compiler/core/common/NumUtil.java +++ b/compiler/src/org.graalvm.compiler.core.common/src/org/graalvm/compiler/core/common/NumUtil.java @@ -26,6 +26,7 @@ // JaCoCo Exclude +import org.graalvm.compiler.debug.GraalError; import jdk.vm.ci.code.CodeUtil; /** @@ -258,4 +259,14 @@ public static byte[] hexStringToBytes(String hex) { } return bytes; } + + public static long addExact(long a, long b, int bits) { + if (bits == 32) { + return Math.addExact((int) a, (int) b); + } else if (bits == 64) { + return Math.addExact(a, b); + } else { + throw GraalError.shouldNotReachHere("Must be one of java's core datatypes int/long but is " + bits); + } + } } diff --git a/compiler/src/org.graalvm.compiler.loop.phases/src/org/graalvm/compiler/loop/phases/LoopTransformations.java b/compiler/src/org.graalvm.compiler.loop.phases/src/org/graalvm/compiler/loop/phases/LoopTransformations.java index eff95e1b64675..e3d95e2aa202a 100644 --- a/compiler/src/org.graalvm.compiler.loop.phases/src/org/graalvm/compiler/loop/phases/LoopTransformations.java +++ b/compiler/src/org.graalvm.compiler.loop.phases/src/org/graalvm/compiler/loop/phases/LoopTransformations.java @@ -32,8 +32,11 @@ import org.graalvm.collections.EconomicMap; import org.graalvm.collections.Equivalence; + +import org.graalvm.compiler.core.common.NumUtil; import org.graalvm.compiler.core.common.RetryableBailoutException; import org.graalvm.compiler.core.common.calc.CanonicalCondition; +import org.graalvm.compiler.core.common.type.IntegerStamp; import org.graalvm.compiler.debug.DebugContext; import org.graalvm.compiler.debug.GraalError; import org.graalvm.compiler.graph.Graph.Mark; @@ -776,6 +779,17 @@ public static boolean countedLoopExitConditionHasMultipleUsages(LoopEx loop) { return condition.hasMoreThanOneUsage(); } + public static boolean strideAdditionOverflows(LoopEx loop) { + final int bits = ((IntegerStamp) loop.counted().getLimitCheckedIV().valueNode().stamp(NodeView.DEFAULT)).getBits(); + long stride = loop.counted().getLimitCheckedIV().constantStride(); + try { + NumUtil.addExact(stride, stride, bits); + return false; + } catch (ArithmeticException ae) { + return true; + } + } + public static boolean isUnrollableLoop(LoopEx loop) { if (!loop.isCounted() || !loop.counted().getLimitCheckedIV().isConstantStride() || !loop.loop().getChildren().isEmpty() || loop.loopBegin().loopEnds().count() != 1 || loop.loopBegin().loopExits().count() > 1 || loop.counted().isInverted()) { @@ -796,11 +810,8 @@ public static boolean isUnrollableLoop(LoopEx loop) { if (countedLoopExitConditionHasMultipleUsages(loop)) { return false; } - long stride = loop.counted().getLimitCheckedIV().constantStride(); - try { - Math.addExact(stride, stride); - } catch (ArithmeticException ae) { - condition.getDebug().log(DebugContext.VERBOSE_LEVEL, "isUnrollableLoop %s doubling the stride overflows %d", loopBegin, stride); + if (strideAdditionOverflows(loop)) { + condition.getDebug().log(DebugContext.VERBOSE_LEVEL, "isUnrollableLoop %s doubling the stride overflows %d", loopBegin, loop.counted().getLimitCheckedIV().constantStride()); return false; } if (!loop.canDuplicateLoop()) { diff --git a/compiler/src/org.graalvm.compiler.loop.test/src/org/graalvm/compiler/loop/test/LoopPartialUnrollTest.java b/compiler/src/org.graalvm.compiler.loop.test/src/org/graalvm/compiler/loop/test/LoopPartialUnrollTest.java index ed7aa077a97bb..684ced3c42813 100644 --- a/compiler/src/org.graalvm.compiler.loop.test/src/org/graalvm/compiler/loop/test/LoopPartialUnrollTest.java +++ b/compiler/src/org.graalvm.compiler.loop.test/src/org/graalvm/compiler/loop/test/LoopPartialUnrollTest.java @@ -62,6 +62,7 @@ import org.junit.Test; import jdk.vm.ci.meta.ResolvedJavaMethod; +import jdk.vm.ci.meta.SpeculationLog; public class LoopPartialUnrollTest extends GraalCompilerTest { @@ -392,4 +393,44 @@ public void testUsages() { check = true; } + static int rr = 0; + + static int countedAfterSnippet(int i, int limit) { + int res = 0; + for (int j = i; GraalDirectives.injectIterationCount(1000, j <= limit); j += Integer.MAX_VALUE) { + rr += 42; + res += j; + } + return res; + } + + SpeculationLog speculationLog; + boolean useSpeculationLog; + + @Override + protected SpeculationLog getSpeculationLog() { + if (!useSpeculationLog) { + speculationLog = null; + return null; + } + if (speculationLog == null) { + speculationLog = getCodeCache().createSpeculationLog(); + } + speculationLog.collectFailedSpeculations(); + return speculationLog; + } + + @Test + public void strideOverflow() { + check = false; + useSpeculationLog = true; + OptionValues opt = new OptionValues(getInitialOptions(), GraalOptions.LoopPeeling, false); + for (int i = -1000; i < 1000; i++) { + for (int j = 0; j < 100; j++) { + test(opt, "countedAfterSnippet", i, j); + } + } + check = true; + useSpeculationLog = false; + } } diff --git a/compiler/src/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/loop/LoopFragmentInside.java b/compiler/src/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/loop/LoopFragmentInside.java index a1fc8c1541a50..385654ad81691 100644 --- a/compiler/src/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/loop/LoopFragmentInside.java +++ b/compiler/src/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/loop/LoopFragmentInside.java @@ -39,6 +39,7 @@ import org.graalvm.compiler.graph.NodeBitMap; import org.graalvm.compiler.graph.Position; import org.graalvm.compiler.graph.iterators.NodeIterable; +import org.graalvm.compiler.loop.phases.LoopTransformations; import org.graalvm.compiler.nodeinfo.InputType; import org.graalvm.compiler.nodes.AbstractBeginNode; import org.graalvm.compiler.nodes.AbstractEndNode; @@ -230,7 +231,7 @@ public void insertWithinAfter(LoopEx loop, EconomicMap Date: Wed, 22 Nov 2023 09:49:14 +0100 Subject: [PATCH 25/34] not able to import LoopTransformations --- .../compiler/nodes/loop/LoopFragmentInside.java | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/compiler/src/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/loop/LoopFragmentInside.java b/compiler/src/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/loop/LoopFragmentInside.java index 385654ad81691..34abba7e7d98a 100644 --- a/compiler/src/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/loop/LoopFragmentInside.java +++ b/compiler/src/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/loop/LoopFragmentInside.java @@ -30,6 +30,7 @@ import org.graalvm.collections.EconomicMap; import org.graalvm.collections.Equivalence; +import org.graalvm.compiler.core.common.NumUtil; import org.graalvm.compiler.core.common.type.IntegerStamp; import org.graalvm.compiler.debug.DebugCloseable; import org.graalvm.compiler.debug.DebugContext; @@ -39,7 +40,6 @@ import org.graalvm.compiler.graph.NodeBitMap; import org.graalvm.compiler.graph.Position; import org.graalvm.compiler.graph.iterators.NodeIterable; -import org.graalvm.compiler.loop.phases.LoopTransformations; import org.graalvm.compiler.nodeinfo.InputType; import org.graalvm.compiler.nodes.AbstractBeginNode; import org.graalvm.compiler.nodes.AbstractEndNode; @@ -231,7 +231,7 @@ public void insertWithinAfter(LoopEx loop, EconomicMap Date: Mon, 30 Oct 2023 16:17:44 +0100 Subject: [PATCH 26/34] Check stamp before casting in IntegerLessThanNode (cherry picked from commit 6acac87ba40308740707664c181e2fde780bbea3) --- .../org/graalvm/compiler/nodes/calc/IntegerLessThanNode.java | 3 +++ 1 file changed, 3 insertions(+) diff --git a/compiler/src/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/calc/IntegerLessThanNode.java b/compiler/src/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/calc/IntegerLessThanNode.java index d6233cab709d2..582232f8a48f0 100644 --- a/compiler/src/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/calc/IntegerLessThanNode.java +++ b/compiler/src/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/calc/IntegerLessThanNode.java @@ -159,6 +159,9 @@ protected LogicNode findSynonym(ValueNode forX, ValueNode forY, NodeView view) { if (result != null) { return result; } + if (!(forX.stamp(view) instanceof IntegerStamp)) { + return null; + } // always prefer unsigned comparisons, however, if part of a graph we sometimes want to // disable it for testing purposes if (forX.getOptions() == null || GraalOptions.PreferUnsignedComparison.getValue(forX.getOptions())) { From 4c5f268bc2549ab06fcd7daa0c1955081112085c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Aleksandar=20Pejovi=C4=87?= Date: Thu, 16 Nov 2023 09:55:10 +0100 Subject: [PATCH 27/34] Update OS detection code to recognize Windows 11 and Windows Server 2022 (cherry picked from commit b58732bfcf98e6ad3499082cad72a681cdb5bf5b) --- .../core/windows/WindowsSystemPropertiesSupport.java | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/substratevm/src/com.oracle.svm.core.windows/src/com/oracle/svm/core/windows/WindowsSystemPropertiesSupport.java b/substratevm/src/com.oracle.svm.core.windows/src/com/oracle/svm/core/windows/WindowsSystemPropertiesSupport.java index 353855263cbae..fc6e0012e97e6 100644 --- a/substratevm/src/com.oracle.svm.core.windows/src/com/oracle/svm/core/windows/WindowsSystemPropertiesSupport.java +++ b/substratevm/src/com.oracle.svm.core.windows/src/com/oracle/svm/core/windows/WindowsSystemPropertiesSupport.java @@ -356,7 +356,11 @@ public Pair getOsNameAndVersion() { if (isWorkstation) { switch (minorVersion) { case 0: - osName = "Windows 10"; + if (buildNumber >= 22000) { + osName = "Windows 11"; + } else { + osName = "Windows 10"; + } break; default: osName = "Windows NT (unknown)"; @@ -364,7 +368,9 @@ public Pair getOsNameAndVersion() { } else { switch (minorVersion) { case 0: - if (buildNumber > 17762) { + if (buildNumber > 20347) { + osName = "Windows Server 2022"; + } else if (buildNumber > 17762) { osName = "Windows Server 2019"; } else { osName = "Windows Server 2016"; From bc86593752bcea73b41639b32fab18ace4075242 Mon Sep 17 00:00:00 2001 From: Foivos Zakkak Date: Tue, 7 Nov 2023 11:13:31 +0200 Subject: [PATCH 28/34] Use synchronized data structures for reachability handlers registration Prevent data races in reachability handlers registration when using `-H:-RunReachabilityHandlersConcurrently`. Closes https://github.com/oracle/graal/issues/5868 (cherry picked from commit 777cb827c6ec1a6dff803ad29fa3057c8b646f13) --- .../oracle/svm/hosted/ReachabilityHandlerFeature.java | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/ReachabilityHandlerFeature.java b/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/ReachabilityHandlerFeature.java index 21a5ee6371918..e32b859e0c190 100644 --- a/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/ReachabilityHandlerFeature.java +++ b/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/ReachabilityHandlerFeature.java @@ -32,6 +32,7 @@ import java.util.List; import java.util.Map; import java.util.Set; +import java.util.concurrent.ConcurrentHashMap; import java.util.function.BiConsumer; import java.util.function.Consumer; @@ -44,6 +45,7 @@ import com.oracle.svm.core.SubstrateOptions; import com.oracle.svm.core.feature.AutomaticallyRegisteredFeature; import com.oracle.svm.core.feature.InternalFeature; +import com.oracle.svm.core.util.ConcurrentIdentityHashMap; import com.oracle.svm.core.util.UserError; import com.oracle.svm.core.util.VMError; import com.oracle.svm.hosted.FeatureImpl.BeforeAnalysisAccessImpl; @@ -52,8 +54,8 @@ @AutomaticallyRegisteredFeature public class ReachabilityHandlerFeature extends ReachabilityHandler implements InternalFeature { - private final IdentityHashMap> activeHandlers = new IdentityHashMap<>(); - private final IdentityHashMap>> triggeredHandlers = new IdentityHashMap<>(); + private final Map> activeHandlers = new ConcurrentIdentityHashMap<>(); + private final Map>> triggeredHandlers = new ConcurrentIdentityHashMap<>(); public static ReachabilityHandlerFeature singleton() { return ImageSingletons.lookup(ReachabilityHandlerFeature.class); @@ -88,7 +90,7 @@ private void registerReachabilityHandler(BeforeAnalysisAccess a, Object callback BeforeAnalysisAccessImpl access = (BeforeAnalysisAccessImpl) a; AnalysisMetaAccess metaAccess = access.getMetaAccess(); - Set triggerSet = activeHandlers.computeIfAbsent(callback, c -> new HashSet<>()); + var triggerSet = activeHandlers.computeIfAbsent(callback, c -> ConcurrentHashMap.newKeySet()); for (Object trigger : triggers) { if (trigger instanceof Class) { @@ -119,7 +121,7 @@ public void duringAnalysis(DuringAnalysisAccess a) { Set triggers = activeHandlers.get(callback); if (callback instanceof Consumer) { if (isTriggered(access, triggers)) { - triggeredHandlers.put(callback, null); + triggeredHandlers.put(callback, Map.of()); toExactCallback(callback).accept(access); completedCallbacks.add(callback); } From a431edeed8f46c06b4ff696bd26b958affc15525 Mon Sep 17 00:00:00 2001 From: Gilles Duboscq Date: Thu, 16 Nov 2023 11:52:09 +0100 Subject: [PATCH 29/34] Use the vendor version for __svm_version_info (cherry picked from commit a8a1f0d7f723adbc1c75b52cd7ecae278ee5322d) --- .../src/com/oracle/svm/hosted/VMFeature.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/VMFeature.java b/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/VMFeature.java index 7ccebf38e94d5..80f22aad7fd5d 100644 --- a/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/VMFeature.java +++ b/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/VMFeature.java @@ -92,7 +92,7 @@ public void beforeAnalysis(BeforeAnalysisAccess a) { public void afterAnalysis(AfterAnalysisAccess access) { CGlobalDataFeature.singleton().registerWithGlobalSymbol( CGlobalDataFactory.createCString(VM.class.getName() + valueSeparator + - ImageSingletons.lookup(VM.class).version, VERSION_INFO_SYMBOL_NAME)); + ImageSingletons.lookup(VM.class).vendorVersion, VERSION_INFO_SYMBOL_NAME)); addCGlobalDataString("Target.Platform", ImageSingletons.lookup(Platform.class).getClass().getName()); addCGlobalDataString("Target.LibC", ImageSingletons.lookup(LibCBase.class).getClass().getName()); From 172b2720d783a19f97a40398b44c2fc93b11023c Mon Sep 17 00:00:00 2001 From: ol-automation_ww Date: Mon, 27 Nov 2023 20:09:46 +0000 Subject: [PATCH 30/34] update to jvmci-23.0-b24 --- common.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/common.json b/common.json index 0a931c9de3cf1..f0dbb945f6727 100644 --- a/common.json +++ b/common.json @@ -14,9 +14,9 @@ "labsjdk-ce-17": {"name": "labsjdk", "version": "ce-17.0.9+9-jvmci-23.0-b22", "platformspecific": true }, "labsjdk-ce-17Debug": {"name": "labsjdk", "version": "ce-17.0.9+9-jvmci-23.0-b22-debug", "platformspecific": true }, "labsjdk-ce-17-llvm": {"name": "labsjdk", "version": "ce-17.0.9+9-jvmci-23.0-b22-sulong", "platformspecific": true }, - "labsjdk-ee-17": {"name": "labsjdk", "version": "ee-17.0.10+4-jvmci-23.0-b23", "platformspecific": true }, - "labsjdk-ee-17Debug": {"name": "labsjdk", "version": "ee-17.0.10+4-jvmci-23.0-b23-debug", "platformspecific": true }, - "labsjdk-ee-17-llvm": {"name": "labsjdk", "version": "ee-17.0.10+4-jvmci-23.0-b23-sulong", "platformspecific": true }, + "labsjdk-ee-17": {"name": "labsjdk", "version": "ee-17.0.10+8-jvmci-23.0-b24-20231127114514-376f6215af+f148a03718", "platformspecific": true }, + "labsjdk-ee-17Debug": {"name": "labsjdk", "version": "ee-17.0.10+8-jvmci-23.0-b24-20231127114514-376f6215af+f148a03718-debug", "platformspecific": true }, + "labsjdk-ee-17-llvm": {"name": "labsjdk", "version": "ee-17.0.10+8-jvmci-23.0-b24-20231127114514-376f6215af+f148a03718-sulong", "platformspecific": true }, "oraclejdk19": {"name": "jpg-jdk", "version": "19", "build_id": "26", "release": true, "platformspecific": true, "extrabundles": ["static-libs"]}, "labsjdk-ce-19": {"name": "labsjdk", "version": "ce-19.0.1+10-jvmci-23.0-b04", "platformspecific": true }, From 05c3b3253888b4c7ae858261b66cf947223df802 Mon Sep 17 00:00:00 2001 From: Christian Wimmer Date: Mon, 27 Nov 2023 13:08:51 -0800 Subject: [PATCH 31/34] Allow UnlockExperimentalVMOptions also in GraalVM for JDK 17 --- .../src/com/oracle/svm/core/SubstrateOptions.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/SubstrateOptions.java b/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/SubstrateOptions.java index b07164e6d7041..058e01c4c3ba6 100644 --- a/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/SubstrateOptions.java +++ b/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/SubstrateOptions.java @@ -921,4 +921,6 @@ public Boolean getValueOrDefault(UnmodifiableEconomicMap, Object> v @Option(help = "file:doc-files/MissingRegistrationPathsHelp.txt")// public static final HostedOptionKey ThrowMissingRegistrationErrorsPaths = new HostedOptionKey<>(LocatableMultiOptionValue.Strings.build()); + @Option(help = "Has no effect in this version of GraalVM. It is present for forward-compatibility with future versions of GraalVM.", type = OptionType.Expert, stability = OptionStability.EXPERIMENTAL) // + public static final HostedOptionKey UnlockExperimentalVMOptions = new HostedOptionKey<>(false); } From 79ab5b946c84c84bba3cd0c7a1234ebc4a794b0d Mon Sep 17 00:00:00 2001 From: Anas El korchi Date: Tue, 28 Nov 2023 09:26:06 +0100 Subject: [PATCH 32/34] Use deployed artifacts for jvmci-23.0-b24 --- common.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/common.json b/common.json index f0dbb945f6727..309c6dae82f0f 100644 --- a/common.json +++ b/common.json @@ -14,9 +14,9 @@ "labsjdk-ce-17": {"name": "labsjdk", "version": "ce-17.0.9+9-jvmci-23.0-b22", "platformspecific": true }, "labsjdk-ce-17Debug": {"name": "labsjdk", "version": "ce-17.0.9+9-jvmci-23.0-b22-debug", "platformspecific": true }, "labsjdk-ce-17-llvm": {"name": "labsjdk", "version": "ce-17.0.9+9-jvmci-23.0-b22-sulong", "platformspecific": true }, - "labsjdk-ee-17": {"name": "labsjdk", "version": "ee-17.0.10+8-jvmci-23.0-b24-20231127114514-376f6215af+f148a03718", "platformspecific": true }, - "labsjdk-ee-17Debug": {"name": "labsjdk", "version": "ee-17.0.10+8-jvmci-23.0-b24-20231127114514-376f6215af+f148a03718-debug", "platformspecific": true }, - "labsjdk-ee-17-llvm": {"name": "labsjdk", "version": "ee-17.0.10+8-jvmci-23.0-b24-20231127114514-376f6215af+f148a03718-sulong", "platformspecific": true }, + "labsjdk-ee-17": {"name": "labsjdk", "version": "ee-17.0.10+8-jvmci-23.0-b24", "platformspecific": true }, + "labsjdk-ee-17Debug": {"name": "labsjdk", "version": "ee-17.0.10+8-jvmci-23.0-b24-debug", "platformspecific": true }, + "labsjdk-ee-17-llvm": {"name": "labsjdk", "version": "ee-17.0.10+8-jvmci-23.0-b24-sulong", "platformspecific": true }, "oraclejdk19": {"name": "jpg-jdk", "version": "19", "build_id": "26", "release": true, "platformspecific": true, "extrabundles": ["static-libs"]}, "labsjdk-ce-19": {"name": "labsjdk", "version": "ce-19.0.1+10-jvmci-23.0-b04", "platformspecific": true }, From 49035923111a537e987dfd06d83859d5c7c24398 Mon Sep 17 00:00:00 2001 From: ol-automation_ww Date: Thu, 30 Nov 2023 07:52:05 +0000 Subject: [PATCH 33/34] update to jvmci-23.0-b25 --- common.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/common.json b/common.json index 309c6dae82f0f..38f6d23a3c5d2 100644 --- a/common.json +++ b/common.json @@ -14,9 +14,9 @@ "labsjdk-ce-17": {"name": "labsjdk", "version": "ce-17.0.9+9-jvmci-23.0-b22", "platformspecific": true }, "labsjdk-ce-17Debug": {"name": "labsjdk", "version": "ce-17.0.9+9-jvmci-23.0-b22-debug", "platformspecific": true }, "labsjdk-ce-17-llvm": {"name": "labsjdk", "version": "ce-17.0.9+9-jvmci-23.0-b22-sulong", "platformspecific": true }, - "labsjdk-ee-17": {"name": "labsjdk", "version": "ee-17.0.10+8-jvmci-23.0-b24", "platformspecific": true }, - "labsjdk-ee-17Debug": {"name": "labsjdk", "version": "ee-17.0.10+8-jvmci-23.0-b24-debug", "platformspecific": true }, - "labsjdk-ee-17-llvm": {"name": "labsjdk", "version": "ee-17.0.10+8-jvmci-23.0-b24-sulong", "platformspecific": true }, + "labsjdk-ee-17": {"name": "labsjdk", "version": "ee-17.0.10+9-jvmci-23.0-b25", "platformspecific": true }, + "labsjdk-ee-17Debug": {"name": "labsjdk", "version": "ee-17.0.10+9-jvmci-23.0-b25-debug", "platformspecific": true }, + "labsjdk-ee-17-llvm": {"name": "labsjdk", "version": "ee-17.0.10+9-jvmci-23.0-b25-sulong", "platformspecific": true }, "oraclejdk19": {"name": "jpg-jdk", "version": "19", "build_id": "26", "release": true, "platformspecific": true, "extrabundles": ["static-libs"]}, "labsjdk-ce-19": {"name": "labsjdk", "version": "ce-19.0.1+10-jvmci-23.0-b04", "platformspecific": true }, From 2abe819ec9dcd9ec3e88f070ee7709c4289ad4f7 Mon Sep 17 00:00:00 2001 From: Christian Haeubl Date: Fri, 3 Nov 2023 11:44:29 +0100 Subject: [PATCH 34/34] Add an option to artificially increase the header size. (cherry picked from commit 993a4292d5a5be291f0db92ee4c2c910278b4065) --- .../com/oracle/svm/core/SubstrateOptions.java | 10 ++++++++++ .../oracle/svm/core/config/ObjectLayout.java | 9 +++++---- .../svm/hosted/HostedConfiguration.java | 19 +++++++++++-------- 3 files changed, 26 insertions(+), 12 deletions(-) diff --git a/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/SubstrateOptions.java b/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/SubstrateOptions.java index b07164e6d7041..7ebbae529c814 100644 --- a/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/SubstrateOptions.java +++ b/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/SubstrateOptions.java @@ -452,6 +452,16 @@ protected void onValueUpdate(EconomicMap, Object> values, Boolean o @Option(help = "How many bytes to pad fields and classes marked @Contended with.") // public static final HostedOptionKey ContendedPaddingWidth = new HostedOptionKey<>(128); + @Option(help = "Add additional header bytes to each object, for diagnostic purposes.", type = OptionType.Debug) // + public static final HostedOptionKey AdditionalHeaderBytes = new HostedOptionKey<>(0, SubstrateOptions::validateAdditionalHeaderBytes); + + private static void validateAdditionalHeaderBytes(HostedOptionKey optionKey) { + int value = optionKey.getValue(); + if (value < 0 || value % 4 != 0) { + throw UserError.abort("The option '%s' must be 0 or a multiple of 4.", optionKey.getName()); + } + } + /* * Isolate tear down options. */ diff --git a/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/config/ObjectLayout.java b/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/config/ObjectLayout.java index febd8215da9be..61d9aca4aea4d 100644 --- a/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/config/ObjectLayout.java +++ b/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/config/ObjectLayout.java @@ -58,10 +58,11 @@ public final class ObjectLayout { public ObjectLayout(SubstrateTargetDescription target, int referenceSize, int objectAlignment, int hubOffset, int firstFieldOffset, int arrayLengthOffset, int arrayBaseOffset, int fixedIdentityHashOffset) { - assert CodeUtil.isPowerOf2(referenceSize); - assert CodeUtil.isPowerOf2(objectAlignment); - assert hubOffset < firstFieldOffset && hubOffset < arrayLengthOffset; - assert fixedIdentityHashOffset == -1 || (fixedIdentityHashOffset > 0 && fixedIdentityHashOffset < arrayLengthOffset); + assert CodeUtil.isPowerOf2(referenceSize) : referenceSize; + assert CodeUtil.isPowerOf2(objectAlignment) : objectAlignment; + assert arrayLengthOffset % Integer.BYTES == 0; + assert hubOffset < firstFieldOffset && hubOffset < arrayLengthOffset : hubOffset; + assert fixedIdentityHashOffset == -1 || (fixedIdentityHashOffset > 0 && fixedIdentityHashOffset < arrayLengthOffset) : fixedIdentityHashOffset; this.target = target; this.referenceSize = referenceSize; diff --git a/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/HostedConfiguration.java b/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/HostedConfiguration.java index 38c9362fc31c9..ab8704e5b8ebd 100644 --- a/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/HostedConfiguration.java +++ b/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/HostedConfiguration.java @@ -140,13 +140,13 @@ public static ObjectLayout createObjectLayout() { public static ObjectLayout createObjectLayout(JavaKind referenceKind, boolean disableOptionalIdentityHash) { SubstrateTargetDescription target = ConfigurationValues.getTarget(); int referenceSize = target.arch.getPlatformKind(referenceKind).getSizeInBytes(); - int headerSize = referenceSize; int intSize = target.arch.getPlatformKind(JavaKind.Int).getSizeInBytes(); int objectAlignment = 8; - int headerOffset = 0; + int hubOffset = 0; + int headerSize = hubOffset + referenceSize; + int identityHashCodeOffset; - int firstFieldOffset; if (!disableOptionalIdentityHash && SubstrateOptions.SpawnIsolates.getValue() && headerSize + referenceSize <= objectAlignment) { /* * References are relative to the heap base, so we should be able to use fewer bits in @@ -158,15 +158,18 @@ public static ObjectLayout createObjectLayout(JavaKind referenceKind, boolean di * individual object was assigned an identity hash code after allocation. */ identityHashCodeOffset = -1; - firstFieldOffset = headerOffset + headerSize; } else { // need all object header bits except for lowest-order bits freed up by alignment - identityHashCodeOffset = headerOffset + referenceSize; - firstFieldOffset = identityHashCodeOffset + intSize; + identityHashCodeOffset = headerSize; + headerSize += intSize; } - int arrayLengthOffset = firstFieldOffset; + + headerSize += SubstrateOptions.AdditionalHeaderBytes.getValue(); + + int firstFieldOffset = headerSize; + int arrayLengthOffset = headerSize; int arrayBaseOffset = arrayLengthOffset + intSize; - return new ObjectLayout(target, referenceSize, objectAlignment, headerOffset, firstFieldOffset, arrayLengthOffset, arrayBaseOffset, identityHashCodeOffset); + return new ObjectLayout(target, referenceSize, objectAlignment, hubOffset, firstFieldOffset, arrayLengthOffset, arrayBaseOffset, identityHashCodeOffset); } public SVMHost createHostVM(OptionValues options, ClassLoader classLoader, ClassInitializationSupport classInitializationSupport,