diff --git a/common.json b/common.json index 07a251a455ff5..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.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+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 }, diff --git a/compiler/mx.compiler/suite.py b/compiler/mx.compiler/suite.py index 638095a7cd309..65525ce100ffb 100644 --- a/compiler/mx.compiler/suite.py +++ b/compiler/mx.compiler/suite.py @@ -4,7 +4,7 @@ "sourceinprojectwhitelist" : [], "groupId" : "org.graalvm.compiler", - "version" : "23.0.2.2", + "version" : "23.0.3.0", "release" : False, "url" : "http://www.graalvm.org/", "developer" : { 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.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.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/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/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())) { 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.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..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; @@ -230,7 +231,7 @@ public void insertWithinAfter(LoopEx loop, EconomicMap 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(); } 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); diff --git a/espresso/mx.espresso/suite.py b/espresso/mx.espresso/suite.py index 7313199381a3a..5d178da70bc05 100644 --- a/espresso/mx.espresso/suite.py +++ b/espresso/mx.espresso/suite.py @@ -23,7 +23,7 @@ suite = { "mxversion": "6.17.0", "name": "espresso", - "version" : "23.0.2.2", + "version" : "23.0.3.0", "release" : False, "groupId" : "org.graalvm.espresso", "url" : "https://www.graalvm.org/reference-manual/java-on-truffle/", diff --git a/regex/mx.regex/suite.py b/regex/mx.regex/suite.py index 56acf56d92574..866191ba882de 100644 --- a/regex/mx.regex/suite.py +++ b/regex/mx.regex/suite.py @@ -43,7 +43,7 @@ "name" : "regex", - "version" : "23.0.2.2", + "version" : "23.0.3.0", "release" : False, "groupId" : "org.graalvm.regex", "url" : "http://www.graalvm.org/", diff --git a/sdk/mx.sdk/mx_sdk_vm_impl.py b/sdk/mx.sdk/mx_sdk_vm_impl.py index 763b45df424c4..0c55c26f27020 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 += ['-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) diff --git a/sdk/mx.sdk/suite.py b/sdk/mx.sdk/suite.py index b379e4c02fca1..831387f9a25b5 100644 --- a/sdk/mx.sdk/suite.py +++ b/sdk/mx.sdk/suite.py @@ -41,7 +41,7 @@ suite = { "mxversion": "6.17.0", "name" : "sdk", - "version" : "23.0.2.2", + "version" : "23.0.3.0", "release" : False, "sourceinprojectwhitelist" : [], "url" : "https://github.com/oracle/graal", 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/substratevm/mx.substratevm/suite.py b/substratevm/mx.substratevm/suite.py index f4b8710cdc5c9..63744245d9bf2 100644 --- a/substratevm/mx.substratevm/suite.py +++ b/substratevm/mx.substratevm/suite.py @@ -2,7 +2,7 @@ suite = { "mxversion": "6.17.0", "name": "substratevm", - "version" : "23.0.2.2", + "version" : "23.0.3.0", "release" : False, "url" : "https://github.com/oracle/graal/tree/master/substratevm", 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 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()); } 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.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.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"; 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/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 { 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..0bae9f604f8ac 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. */ @@ -921,4 +931,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); } 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/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/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.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.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..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; @@ -200,8 +201,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 +276,40 @@ 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); + + 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,6 @@ 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 +349,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 +360,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 +382,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; } @@ -506,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); 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 5b4542c341c9a..a537bb00f185a 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 @@ -89,18 +90,11 @@ public String getName() { @Uninterruptible(reason = "Prevent races with VM operations that start/stop recording.", callerMustBe = true) public boolean shouldEmit() { - assert !hasDuration; - return shouldEmit0(); - } - - @Uninterruptible(reason = "Prevent races with VM operations that start/stop recording.", callerMustBe = true) - public boolean shouldEmit(long durationTicks) { - assert hasDuration; - return shouldEmit0() && durationTicks >= SubstrateJVM.get().getThresholdTicks(this); + 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) && !SubstrateJVM.get().isCurrentThreadExcluded(); + 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 ba310d083ca48..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 @@ -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 d6051542891c0..375e82d5a6f1f 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(); } /** @@ -680,26 +680,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/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/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/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/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") 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); } } 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; } 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) { 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, 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); } 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()); 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()); } } 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..b967d65889b8f 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 @@ -381,8 +387,10 @@ 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 +// 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) features->fCX8 = 1; diff --git a/tools/mx.tools/suite.py b/tools/mx.tools/suite.py index c187532407b34..bce433336a38b 100644 --- a/tools/mx.tools/suite.py +++ b/tools/mx.tools/suite.py @@ -26,7 +26,7 @@ "defaultLicense" : "GPLv2-CPE", "groupId" : "org.graalvm.tools", - "version" : "23.0.2.2", + "version" : "23.0.3.0", "release" : False, "url" : "http://openjdk.java.net/projects/graal", "developer" : { 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; 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 109d23bf7e927..49e0222f6ab5e 100644 --- a/truffle/mx.truffle/suite.py +++ b/truffle/mx.truffle/suite.py @@ -41,7 +41,7 @@ suite = { "mxversion": "6.17.0", "name" : "truffle", - "version" : "23.0.2.2", + "version" : "23.0.3.0", "release" : False, "groupId" : "org.graalvm.truffle", "sourceinprojectwhitelist" : [], @@ -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" : { 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); 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', diff --git a/vm/mx.vm/suite.py b/vm/mx.vm/suite.py index 7cd860c02f367..403bf97d684b4 100644 --- a/vm/mx.vm/suite.py +++ b/vm/mx.vm/suite.py @@ -1,6 +1,6 @@ suite = { "name": "vm", - "version" : "23.0.2.2", + "version" : "23.0.3.0", "mxversion": "6.17.0", "release" : False, "groupId" : "org.graalvm", @@ -39,7 +39,7 @@ "name": "graal-nodejs", "subdir": True, "dynamic": True, - "version": "e2b74f45ce0eb8ae3f9bd24b068f128e91d607e8", + "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": "e2b74f45ce0eb8ae3f9bd24b068f128e91d607e8", + "version": "99c8a2c475732c770e7e05ae0823d49648cc7ebb", "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 ccc0fdb7ceaf2..e3a911f3cb5f7 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.2", + "version" : "23.0.3.0", "versionConflictResolution" : "latest", "url" : "http://graalvm.org/", "developer" : {