# HG changeset patch # User mgronlun # Date 1569444041 -7200 # Node ID ca19b94eac7a6b0773bcf4666f02c8d417351198 # Parent e47423f1318ba163e8af5ae9c51379292d94d1ee# Parent 21a03fa2f6b6137c9a25e695b9779234e16a9382 Merge diff -r e47423f1318b -r ca19b94eac7a doc/testing.html --- a/doc/testing.html Mon Sep 23 09:16:05 2019 -0700 +++ b/doc/testing.html Wed Sep 25 22:40:41 2019 +0200 @@ -5,7 +5,7 @@ Testing the JDK - cond + // / \ + // begin begin + // | | + // end end C1 V2 + // \ / \ / + // merge---------->phi<------ C1 + // | ^ \ / + // if-------------|-------->== + // / \ | + // A B<--------Proxy + // + // Must be simplified to: + // + // if---------------------->cond + // / \ + // A B<--------Proxy------>V2 + // + // @formatter:on + // Checkstyle: resume + if (usage instanceof ValueProxyNode) { + ValueProxyNode proxy = (ValueProxyNode) usage; + if (proxy.proxyPoint() == trueSuccessor || proxy.proxyPoint() == falseSuccessor) { + continue; + } + } return false; } - for (Node usage : phiUsages) { - if (usage != compare && usage != merge.stateAfter()) { - return false; - } - } List mergePredecessors = merge.cfgPredecessors().snapshot(); assert phi.valueCount() == merge.forwardEndCount(); @@ -1499,8 +1701,7 @@ return false; } - // Sanity check that both ends are not followed by a merge without frame state. - if (!checkFrameState(trueSuccessor()) && !checkFrameState(falseSuccessor())) { + if (!mayRemoveSplit(merge)) { return false; } @@ -1527,8 +1728,8 @@ assert !ends.hasNext(); assert falseEnds.size() + trueEnds.size() == xs.length; - connectEnds(falseEnds, phiValues, oldFalseSuccessor, merge, tool); - connectEnds(trueEnds, phiValues, oldTrueSuccessor, merge, tool); + connectEnds(falseEnds, phi, phiValues, oldFalseSuccessor, merge, tool); + connectEnds(trueEnds, phi, phiValues, oldTrueSuccessor, merge, tool); if (this.trueSuccessorProbability == 0.0) { for (AbstractEndNode endNode : trueEnds) { @@ -1562,7 +1763,16 @@ return true; } - private void propagateZeroProbability(FixedNode startNode) { + private boolean mayRemoveSplit(AbstractMergeNode merge) { + + if (merge.stateAfter() != null && (!checkFrameState(trueSuccessor, MAX_FRAMESTATE_SEARCH_DEPTH) || !checkFrameState(trueSuccessor, MAX_FRAMESTATE_SEARCH_DEPTH))) { + return false; + } + + return true; + } + + private static void propagateZeroProbability(FixedNode startNode) { Node prev = null; for (FixedNode node : GraphUtil.predecessorIterable(startNode)) { if (node instanceof IfNode) { @@ -1598,7 +1808,14 @@ } } - private static boolean checkFrameState(FixedNode start) { + /** + * Snippet lowerings may produce patterns without a frame state on the merge. We need to take + * extra care when optimizing these patterns. + */ + private static boolean checkFrameState(FixedNode start, int maxDepth) { + if (maxDepth == 0) { + return false; + } FixedNode node = start; while (true) { if (node instanceof AbstractMergeNode) { @@ -1618,7 +1835,7 @@ if (node instanceof ControlSplitNode) { ControlSplitNode controlSplitNode = (ControlSplitNode) node; for (Node succ : controlSplitNode.cfgSuccessors()) { - if (checkFrameState((FixedNode) succ)) { + if (checkFrameState((FixedNode) succ, maxDepth - 1)) { return true; } } @@ -1632,6 +1849,7 @@ } else if (node instanceof ControlSinkNode) { return true; } else { + assert false : "unexpected node"; return false; } } @@ -1642,13 +1860,27 @@ * end. If {@code ends} is not empty, then {@code successor} is added to {@code tool}'s * {@linkplain SimplifierTool#addToWorkList(org.graalvm.compiler.graph.Node) work list}. * + * @param phi the original single-usage phi of the preceding merge + * @param phiValues the values of the phi at the merge, keyed by the merge ends * @param oldMerge the merge being removed - * @param phiValues the values of the phi at the merge, keyed by the merge ends */ - private void connectEnds(List ends, EconomicMap phiValues, AbstractBeginNode successor, AbstractMergeNode oldMerge, SimplifierTool tool) { + private void connectEnds(List ends, ValuePhiNode phi, EconomicMap phiValues, AbstractBeginNode successor, AbstractMergeNode oldMerge, SimplifierTool tool) { if (!ends.isEmpty()) { + // If there was a value proxy usage, then the proxy needs a new value. + ValueProxyNode valueProxy = null; + if (successor instanceof LoopExitNode) { + for (Node usage : phi.usages()) { + if (usage instanceof ValueProxyNode && ((ValueProxyNode) usage).proxyPoint() == successor) { + valueProxy = (ValueProxyNode) usage; + } + } + } + final ValueProxyNode proxy = valueProxy; if (ends.size() == 1) { AbstractEndNode end = ends.get(0); + if (proxy != null) { + phi.replaceAtUsages(phiValues.get(end), n -> n == proxy); + } ((FixedWithNextNode) end.predecessor()).setNext(successor); oldMerge.removeEnd(end); GraphUtil.killCFG(end); @@ -1660,6 +1892,10 @@ PhiNode oldPhi = (PhiNode) oldMerge.usages().first(); PhiNode newPhi = graph().addWithoutUnique(new ValuePhiNode(oldPhi.stamp(view), newMerge)); + if (proxy != null) { + phi.replaceAtUsages(newPhi, n -> n == proxy); + } + for (EndNode end : ends) { newPhi.addInput(phiValues.get(end)); newMerge.addForwardEnd(end); diff -r e47423f1318b -r ca19b94eac7a src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/Invoke.java --- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/Invoke.java Mon Sep 23 09:16:05 2019 -0700 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/Invoke.java Wed Sep 25 22:40:41 2019 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 2019, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it diff -r e47423f1318b -r ca19b94eac7a src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/InvokeNode.java --- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/InvokeNode.java Mon Sep 23 09:16:05 2019 -0700 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/InvokeNode.java Wed Sep 25 22:40:41 2019 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2009, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2009, 2019, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it diff -r e47423f1318b -r ca19b94eac7a src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/InvokeWithExceptionNode.java --- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/InvokeWithExceptionNode.java Mon Sep 23 09:16:05 2019 -0700 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/InvokeWithExceptionNode.java Wed Sep 25 22:40:41 2019 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 2019, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -34,6 +34,7 @@ import org.graalvm.compiler.core.common.type.Stamp; import org.graalvm.compiler.debug.DebugCloseable; +import org.graalvm.compiler.graph.IterableNodeType; import org.graalvm.compiler.graph.Node; import org.graalvm.compiler.graph.NodeClass; import org.graalvm.compiler.nodeinfo.NodeInfo; @@ -50,7 +51,7 @@ import jdk.vm.ci.code.BytecodeFrame; @NodeInfo(nameTemplate = "Invoke!#{p#targetMethod/s}", allowedUsageTypes = {Memory}, cycles = CYCLES_UNKNOWN, size = SIZE_UNKNOWN) -public final class InvokeWithExceptionNode extends ControlSplitNode implements Invoke, MemoryCheckpoint.Single, LIRLowerable, UncheckedInterfaceProvider { +public final class InvokeWithExceptionNode extends ControlSplitNode implements Invoke, IterableNodeType, MemoryCheckpoint.Single, LIRLowerable, UncheckedInterfaceProvider { public static final NodeClass TYPE = NodeClass.create(InvokeWithExceptionNode.class); private static final double EXCEPTION_PROBA = 1e-5; diff -r e47423f1318b -r ca19b94eac7a src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/LogicNode.java --- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/LogicNode.java Mon Sep 23 09:16:05 2019 -0700 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/LogicNode.java Wed Sep 25 22:40:41 2019 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 2019, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it diff -r e47423f1318b -r ca19b94eac7a src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/LoopBeginNode.java --- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/LoopBeginNode.java Mon Sep 23 09:16:05 2019 -0700 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/LoopBeginNode.java Wed Sep 25 22:40:41 2019 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 2019, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it diff -r e47423f1318b -r ca19b94eac7a src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/LoopExitNode.java --- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/LoopExitNode.java Mon Sep 23 09:16:05 2019 -0700 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/LoopExitNode.java Wed Sep 25 22:40:41 2019 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2019, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it diff -r e47423f1318b -r ca19b94eac7a src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/PiNode.java --- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/PiNode.java Mon Sep 23 09:16:05 2019 -0700 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/PiNode.java Wed Sep 25 22:40:41 2019 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2019, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -33,7 +33,6 @@ import org.graalvm.compiler.core.common.type.StampFactory; import org.graalvm.compiler.core.common.type.TypeReference; import org.graalvm.compiler.debug.DebugContext; -import org.graalvm.compiler.graph.IterableNodeType; import org.graalvm.compiler.graph.Node; import org.graalvm.compiler.graph.NodeClass; import org.graalvm.compiler.graph.spi.Canonicalizable; @@ -65,7 +64,7 @@ * also the scheduling restriction enforced by the guard, will go away. */ @NodeInfo(cycles = CYCLES_0, size = SIZE_0) -public class PiNode extends FloatingGuardedNode implements LIRLowerable, Virtualizable, IterableNodeType, Canonicalizable, ValueProxy { +public class PiNode extends FloatingGuardedNode implements LIRLowerable, Virtualizable, Canonicalizable, ValueProxy { public static final NodeClass TYPE = NodeClass.create(PiNode.class); @Input ValueNode object; diff -r e47423f1318b -r ca19b94eac7a src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/SimplifyingGraphDecoder.java --- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/SimplifyingGraphDecoder.java Mon Sep 23 09:16:05 2019 -0700 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/SimplifyingGraphDecoder.java Wed Sep 25 22:40:41 2019 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2019, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it diff -r e47423f1318b -r ca19b94eac7a src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/StructuredGraph.java --- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/StructuredGraph.java Mon Sep 23 09:16:05 2019 -0700 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/StructuredGraph.java Wed Sep 25 22:40:41 2019 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 2019, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it diff -r e47423f1318b -r ca19b94eac7a src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/ValueNode.java --- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/ValueNode.java Mon Sep 23 09:16:05 2019 -0700 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/ValueNode.java Wed Sep 25 22:40:41 2019 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2009, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2009, 2019, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -38,6 +38,7 @@ import jdk.vm.ci.meta.Constant; import jdk.vm.ci.meta.JavaConstant; import jdk.vm.ci.meta.JavaKind; +import jdk.vm.ci.meta.SerializableConstant; /** * This class represents a value within the graph, including local variables, phis, and all other @@ -166,6 +167,19 @@ } } + public final boolean isSerializableConstant() { + return isConstant() && asConstant() instanceof SerializableConstant; + } + + public final SerializableConstant asSerializableConstant() { + Constant value = asConstant(); + if (value instanceof SerializableConstant) { + return (SerializableConstant) value; + } else { + return null; + } + } + @Override public ValueNode asNode() { return this; diff -r e47423f1318b -r ca19b94eac7a src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/calc/AbstractNormalizeCompareNode.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/calc/AbstractNormalizeCompareNode.java Wed Sep 25 22:40:41 2019 +0200 @@ -0,0 +1,103 @@ +/* + * Copyright (c) 2009, 2018, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + + +package org.graalvm.compiler.nodes.calc; + +import static org.graalvm.compiler.nodeinfo.NodeSize.SIZE_2; + +import org.graalvm.compiler.core.common.calc.CanonicalCondition; +import org.graalvm.compiler.core.common.type.Stamp; +import org.graalvm.compiler.core.common.type.StampFactory; +import org.graalvm.compiler.graph.IterableNodeType; +import org.graalvm.compiler.graph.NodeClass; +import org.graalvm.compiler.nodeinfo.NodeCycles; +import org.graalvm.compiler.nodeinfo.NodeInfo; +import org.graalvm.compiler.nodes.ConstantNode; +import org.graalvm.compiler.nodes.LogicConstantNode; +import org.graalvm.compiler.nodes.LogicNode; +import org.graalvm.compiler.nodes.NodeView; +import org.graalvm.compiler.nodes.ValueNode; +import org.graalvm.compiler.options.OptionValues; + +import jdk.vm.ci.meta.ConstantReflectionProvider; +import jdk.vm.ci.meta.JavaKind; +import jdk.vm.ci.meta.MetaAccessProvider; + +/** + * Returns -1, 0, or 1 if either x < y, x == y, or x > y. + */ +@NodeInfo(cycles = NodeCycles.CYCLES_2, size = SIZE_2) +public abstract class AbstractNormalizeCompareNode extends BinaryNode implements IterableNodeType { + public static final NodeClass TYPE = NodeClass.create(AbstractNormalizeCompareNode.class); + + public AbstractNormalizeCompareNode(NodeClass c, JavaKind kind, ValueNode x, ValueNode y) { + super(c, StampFactory.forInteger(kind, -1, 1), x, y); + } + + @Override + public boolean inferStamp() { + return false; + } + + @Override + public Stamp foldStamp(Stamp stampX, Stamp stampY) { + return stamp(NodeView.DEFAULT); + } + + protected static ValueNode tryConstantFold(ValueNode x, ValueNode y, boolean isUnorderedLess, boolean unsigned, JavaKind kind, ConstantReflectionProvider constantReflection) { + LogicNode result = CompareNode.tryConstantFold(CanonicalCondition.EQ, x, y, null, false); + if (result instanceof LogicConstantNode) { + LogicConstantNode logicConstantNode = (LogicConstantNode) result; + LogicNode resultLT = CompareNode.tryConstantFold(unsigned ? CanonicalCondition.BT : CanonicalCondition.LT, x, y, constantReflection, isUnorderedLess); + if (resultLT instanceof LogicConstantNode) { + LogicConstantNode logicConstantNodeLT = (LogicConstantNode) resultLT; + if (logicConstantNodeLT.getValue()) { + return ConstantNode.forIntegerKind(kind, -1); + } else if (logicConstantNode.getValue()) { + return ConstantNode.forIntegerKind(kind, 0); + } else { + return ConstantNode.forIntegerKind(kind, 1); + } + } + } + return null; + } + + public abstract LogicNode createEqualComparison(); + + public abstract LogicNode createEqualComparison(ConstantReflectionProvider constantReflection, MetaAccessProvider metaAccess, OptionValues options, Integer smallestCompareWidth, NodeView view); + + public LogicNode createLowerComparison() { + return createLowerComparison(false); + } + + public LogicNode createLowerComparison(ConstantReflectionProvider constantReflection, MetaAccessProvider metaAccess, OptionValues options, Integer smallestCompareWidth, NodeView view) { + return createLowerComparison(false, constantReflection, metaAccess, options, smallestCompareWidth, view); + } + + public abstract LogicNode createLowerComparison(boolean swapInputs); + + public abstract LogicNode createLowerComparison(boolean swapInputs, ConstantReflectionProvider constantReflection, MetaAccessProvider metaAccess, OptionValues options, + Integer smallestCompareWidth, NodeView view); +} diff -r e47423f1318b -r ca19b94eac7a src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/calc/CompareNode.java --- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/calc/CompareNode.java Mon Sep 23 09:16:05 2019 -0700 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/calc/CompareNode.java Wed Sep 25 22:40:41 2019 +0200 @@ -184,17 +184,25 @@ realCondition = realCondition.mirror(); } return optimizeConditional(constant, (ConditionalNode) nonConstant, constantReflection, realCondition, unorderedIsTrue); - } else if (nonConstant instanceof NormalizeCompareNode) { - return optimizeNormalizeCompare(constantReflection, metaAccess, options, smallestCompareWidth, constant, (NormalizeCompareNode) nonConstant, mirrored, view); + } else if (nonConstant instanceof AbstractNormalizeCompareNode) { + return optimizeNormalizeCompare(constantReflection, metaAccess, options, smallestCompareWidth, constant, (AbstractNormalizeCompareNode) nonConstant, mirrored, view); } else if (nonConstant instanceof ConvertNode) { ConvertNode convert = (ConvertNode) nonConstant; boolean multiUsage = (convert.asNode().hasMoreThanOneUsage() && convert.getValue().hasExactlyOneUsage()); - if ((convert instanceof ZeroExtendNode || convert instanceof SignExtendNode) && multiUsage) { - // Do not perform for zero or sign extend if it could introduce + if (convert instanceof IntegerConvertNode && multiUsage) { + // Do not perform for integer convers if it could introduce // new live values. return null; } + if (convert instanceof NarrowNode) { + NarrowNode narrowNode = (NarrowNode) convert; + if (narrowNode.getInputBits() > 32 && !constant.isDefaultForKind()) { + // Avoid large integer constants. + return null; + } + } + boolean supported = true; if (convert.getValue().stamp(view) instanceof IntegerStamp) { IntegerStamp intStamp = (IntegerStamp) convert.getValue().stamp(view); @@ -233,7 +241,7 @@ @SuppressWarnings("unused") protected LogicNode optimizeNormalizeCompare(ConstantReflectionProvider constantReflection, MetaAccessProvider metaAccess, OptionValues options, Integer smallestCompareWidth, - Constant constant, NormalizeCompareNode normalizeNode, boolean mirrored, NodeView view) { + Constant constant, AbstractNormalizeCompareNode normalizeNode, boolean mirrored, NodeView view) { throw new PermanentBailoutException("NormalizeCompareNode connected to %s (%s %s %s)", this, constant, normalizeNode, mirrored); } diff -r e47423f1318b -r ca19b94eac7a src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/calc/ConditionalNode.java --- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/calc/ConditionalNode.java Mon Sep 23 09:16:05 2019 -0700 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/calc/ConditionalNode.java Wed Sep 25 22:40:41 2019 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2009, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2009, 2019, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -214,8 +214,7 @@ // (value & 1) == 0 ? 0 : 1 // (value & 1) == 1 ? 1 : 0 IntegerTestNode integerTestNode = (IntegerTestNode) condition; - if (integerTestNode.getY().isConstant()) { - assert integerTestNode.getX().stamp(view) instanceof IntegerStamp; + if (integerTestNode.getY().isConstant() && integerTestNode.getX().stamp(view) instanceof IntegerStamp) { long testY = integerTestNode.getY().asJavaConstant().asLong(); if (testY == 1 && constTrueValue == 0 && constFalseValue == 1) { return IntegerConvertNode.convertUnsigned(AndNode.create(integerTestNode.getX(), integerTestNode.getY(), view), stamp, view); diff -r e47423f1318b -r ca19b94eac7a src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/calc/FloatNormalizeCompareNode.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/calc/FloatNormalizeCompareNode.java Wed Sep 25 22:40:41 2019 +0200 @@ -0,0 +1,100 @@ +/* + * Copyright (c) 2009, 2018, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + + +package org.graalvm.compiler.nodes.calc; + +import org.graalvm.compiler.graph.NodeClass; +import org.graalvm.compiler.graph.spi.CanonicalizerTool; +import org.graalvm.compiler.nodeinfo.NodeInfo; +import org.graalvm.compiler.nodes.LogicNode; +import org.graalvm.compiler.nodes.NodeView; +import org.graalvm.compiler.nodes.ValueNode; +import org.graalvm.compiler.options.OptionValues; + +import jdk.vm.ci.meta.ConstantReflectionProvider; +import jdk.vm.ci.meta.JavaKind; +import jdk.vm.ci.meta.MetaAccessProvider; + +/** + * If the comparison is undecided (one of the inputs is NaN), the result is 1 if isUnorderedLess is + * false and -1 if isUnorderedLess is true. + */ +@NodeInfo +public final class FloatNormalizeCompareNode extends AbstractNormalizeCompareNode { + public static final NodeClass TYPE = NodeClass.create(FloatNormalizeCompareNode.class); + protected final boolean isUnorderedLess; + + public FloatNormalizeCompareNode(ValueNode x, ValueNode y, JavaKind kind, boolean isUnorderedLess) { + super(TYPE, kind, x, y); + this.isUnorderedLess = isUnorderedLess; + } + + public static ValueNode create(ValueNode x, ValueNode y, boolean isUnorderedLess, JavaKind kind, ConstantReflectionProvider constantReflection) { + ValueNode result = tryConstantFold(x, y, isUnorderedLess, false, kind, constantReflection); + if (result != null) { + return result; + } + + return new FloatNormalizeCompareNode(x, y, kind, isUnorderedLess); + } + + @Override + public ValueNode canonical(CanonicalizerTool tool, ValueNode forX, ValueNode forY) { + NodeView view = NodeView.from(tool); + ValueNode result = tryConstantFold(x, y, isUnorderedLess, false, stamp(view).getStackKind(), tool.getConstantReflection()); + if (result != null) { + return result; + } + return this; + } + + public boolean isUnorderedLess() { + return isUnorderedLess; + } + + @Override + public LogicNode createEqualComparison() { + return FloatEqualsNode.create(x, y, NodeView.DEFAULT); + } + + @Override + public LogicNode createEqualComparison(ConstantReflectionProvider constantReflection, MetaAccessProvider metaAccess, OptionValues options, Integer smallestCompareWidth, NodeView view) { + return FloatEqualsNode.create(constantReflection, metaAccess, options, smallestCompareWidth, x, y, NodeView.DEFAULT); + } + + @Override + public LogicNode createLowerComparison(boolean swapInputs) { + ValueNode a = swapInputs ? y : x; + ValueNode b = swapInputs ? x : y; + return FloatLessThanNode.create(a, b, isUnorderedLess() ^ swapInputs, NodeView.DEFAULT); + } + + @Override + public LogicNode createLowerComparison(boolean swapInputs, ConstantReflectionProvider constantReflection, MetaAccessProvider metaAccess, OptionValues options, Integer smallestCompareWidth, + NodeView view) { + ValueNode a = swapInputs ? y : x; + ValueNode b = swapInputs ? x : y; + return FloatLessThanNode.create(constantReflection, metaAccess, options, smallestCompareWidth, a, b, isUnorderedLess() ^ swapInputs, NodeView.DEFAULT); + } +} diff -r e47423f1318b -r ca19b94eac7a src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/calc/IntegerConvertNode.java --- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/calc/IntegerConvertNode.java Mon Sep 23 09:16:05 2019 -0700 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/calc/IntegerConvertNode.java Wed Sep 25 22:40:41 2019 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 2019, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -69,7 +69,7 @@ this.getReverseOp = getReverseOp; this.inputBits = inputBits; this.resultBits = resultBits; - assert ((PrimitiveStamp) input.stamp(NodeView.DEFAULT)).getBits() == inputBits; + assert PrimitiveStamp.getBits(input.stamp(NodeView.DEFAULT)) == 0 || PrimitiveStamp.getBits(input.stamp(NodeView.DEFAULT)) == inputBits; } public int getInputBits() { diff -r e47423f1318b -r ca19b94eac7a src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/calc/IntegerDivRemNode.java --- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/calc/IntegerDivRemNode.java Mon Sep 23 09:16:05 2019 -0700 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/calc/IntegerDivRemNode.java Wed Sep 25 22:40:41 2019 +0200 @@ -29,6 +29,7 @@ import org.graalvm.compiler.core.common.type.IntegerStamp; import org.graalvm.compiler.core.common.type.Stamp; +import org.graalvm.compiler.graph.IterableNodeType; import org.graalvm.compiler.graph.NodeClass; import org.graalvm.compiler.nodeinfo.InputType; import org.graalvm.compiler.nodeinfo.NodeInfo; @@ -39,7 +40,7 @@ import org.graalvm.compiler.nodes.spi.LoweringTool; @NodeInfo(cycles = CYCLES_32, size = SIZE_1) -public abstract class IntegerDivRemNode extends FixedBinaryNode implements Lowerable { +public abstract class IntegerDivRemNode extends FixedBinaryNode implements Lowerable, IterableNodeType { public static final NodeClass TYPE = NodeClass.create(IntegerDivRemNode.class); diff -r e47423f1318b -r ca19b94eac7a src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/calc/IntegerEqualsNode.java --- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/calc/IntegerEqualsNode.java Mon Sep 23 09:16:05 2019 -0700 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/calc/IntegerEqualsNode.java Wed Sep 25 22:40:41 2019 +0200 @@ -109,30 +109,15 @@ public static class IntegerEqualsOp extends CompareOp { @Override protected LogicNode optimizeNormalizeCompare(ConstantReflectionProvider constantReflection, MetaAccessProvider metaAccess, OptionValues options, Integer smallestCompareWidth, - Constant constant, NormalizeCompareNode normalizeNode, boolean mirrored, NodeView view) { + Constant constant, AbstractNormalizeCompareNode normalizeNode, boolean mirrored, NodeView view) { PrimitiveConstant primitive = (PrimitiveConstant) constant; - ValueNode a = normalizeNode.getX(); - ValueNode b = normalizeNode.getY(); long cst = primitive.asLong(); - if (cst == 0) { - if (normalizeNode.getX().getStackKind() == JavaKind.Double || normalizeNode.getX().getStackKind() == JavaKind.Float) { - return FloatEqualsNode.create(constantReflection, metaAccess, options, smallestCompareWidth, a, b, view); - } else { - return IntegerEqualsNode.create(constantReflection, metaAccess, options, smallestCompareWidth, a, b, view); - } + return normalizeNode.createEqualComparison(constantReflection, metaAccess, options, smallestCompareWidth, view); } else if (cst == 1) { - if (normalizeNode.getX().getStackKind() == JavaKind.Double || normalizeNode.getX().getStackKind() == JavaKind.Float) { - return FloatLessThanNode.create(b, a, !normalizeNode.isUnorderedLess, view); - } else { - return IntegerLessThanNode.create(constantReflection, metaAccess, options, smallestCompareWidth, b, a, view); - } + return normalizeNode.createLowerComparison(true, constantReflection, metaAccess, options, smallestCompareWidth, view); } else if (cst == -1) { - if (normalizeNode.getX().getStackKind() == JavaKind.Double || normalizeNode.getX().getStackKind() == JavaKind.Float) { - return FloatLessThanNode.create(a, b, normalizeNode.isUnorderedLess, view); - } else { - return IntegerLessThanNode.create(constantReflection, metaAccess, options, smallestCompareWidth, a, b, view); - } + return normalizeNode.createLowerComparison(false, constantReflection, metaAccess, options, smallestCompareWidth, view); } else { return LogicConstantNode.contradiction(); } diff -r e47423f1318b -r ca19b94eac7a src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/calc/IntegerLessThanNode.java --- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/calc/IntegerLessThanNode.java Mon Sep 23 09:16:05 2019 -0700 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/calc/IntegerLessThanNode.java Wed Sep 25 22:40:41 2019 +0200 @@ -114,7 +114,7 @@ @Override protected LogicNode optimizeNormalizeCompare(ConstantReflectionProvider constantReflection, MetaAccessProvider metaAccess, OptionValues options, Integer smallestCompareWidth, - Constant constant, NormalizeCompareNode normalizeNode, boolean mirrored, NodeView view) { + Constant constant, AbstractNormalizeCompareNode normalizeNode, boolean mirrored, NodeView view) { PrimitiveConstant primitive = (PrimitiveConstant) constant; /* @formatter:off * a NC b < c (not mirrored) @@ -136,25 +136,14 @@ * We can handle mirroring by swapping a & b and negating the constant. * @formatter:on */ - ValueNode a = mirrored ? normalizeNode.getY() : normalizeNode.getX(); - ValueNode b = mirrored ? normalizeNode.getX() : normalizeNode.getY(); long cst = mirrored ? -primitive.asLong() : primitive.asLong(); if (cst == 0) { - if (normalizeNode.getX().getStackKind() == JavaKind.Double || normalizeNode.getX().getStackKind() == JavaKind.Float) { - return FloatLessThanNode.create(constantReflection, metaAccess, options, smallestCompareWidth, a, b, mirrored ^ normalizeNode.isUnorderedLess, view); - } else { - return IntegerLessThanNode.create(constantReflection, metaAccess, options, smallestCompareWidth, a, b, view); - } + return normalizeNode.createLowerComparison(mirrored, constantReflection, metaAccess, options, smallestCompareWidth, view); } else if (cst == 1) { // a <= b <=> !(a > b) - LogicNode compare; - if (normalizeNode.getX().getStackKind() == JavaKind.Double || normalizeNode.getX().getStackKind() == JavaKind.Float) { - // since we negate, we have to reverse the unordered result - compare = FloatLessThanNode.create(constantReflection, metaAccess, options, smallestCompareWidth, b, a, mirrored == normalizeNode.isUnorderedLess, view); - } else { - compare = IntegerLessThanNode.create(constantReflection, metaAccess, options, smallestCompareWidth, b, a, view); - } + // since we negate, we have to reverse the unordered result + LogicNode compare = normalizeNode.createLowerComparison(!mirrored, constantReflection, metaAccess, options, smallestCompareWidth, view); return LogicNegationNode.create(compare); } else if (cst <= -1) { return LogicConstantNode.contradiction(); diff -r e47423f1318b -r ca19b94eac7a src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/calc/IntegerLowerThanNode.java --- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/calc/IntegerLowerThanNode.java Mon Sep 23 09:16:05 2019 -0700 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/calc/IntegerLowerThanNode.java Wed Sep 25 22:40:41 2019 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2019, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it diff -r e47423f1318b -r ca19b94eac7a src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/calc/IntegerNormalizeCompareNode.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/calc/IntegerNormalizeCompareNode.java Wed Sep 25 22:40:41 2019 +0200 @@ -0,0 +1,100 @@ +/* + * Copyright (c) 2009, 2018, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + + +package org.graalvm.compiler.nodes.calc; + +import org.graalvm.compiler.graph.NodeClass; +import org.graalvm.compiler.graph.spi.CanonicalizerTool; +import org.graalvm.compiler.nodeinfo.NodeInfo; +import org.graalvm.compiler.nodes.LogicNode; +import org.graalvm.compiler.nodes.NodeView; +import org.graalvm.compiler.nodes.ValueNode; +import org.graalvm.compiler.options.OptionValues; + +import jdk.vm.ci.meta.ConstantReflectionProvider; +import jdk.vm.ci.meta.JavaKind; +import jdk.vm.ci.meta.MetaAccessProvider; + +@NodeInfo +public final class IntegerNormalizeCompareNode extends AbstractNormalizeCompareNode { + public static final NodeClass TYPE = NodeClass.create(IntegerNormalizeCompareNode.class); + protected final boolean unsigned; + + public IntegerNormalizeCompareNode(ValueNode x, ValueNode y, JavaKind kind, boolean unsigned) { + super(TYPE, kind, x, y); + this.unsigned = unsigned; + } + + public static ValueNode create(ValueNode x, ValueNode y, boolean unsigned, JavaKind kind, ConstantReflectionProvider constantReflection) { + ValueNode result = tryConstantFold(x, y, false, unsigned, kind, constantReflection); + if (result != null) { + return result; + } + + return new IntegerNormalizeCompareNode(x, y, kind, unsigned); + } + + @Override + public ValueNode canonical(CanonicalizerTool tool, ValueNode forX, ValueNode forY) { + NodeView view = NodeView.from(tool); + ValueNode result = tryConstantFold(x, y, false, unsigned, stamp(view).getStackKind(), tool.getConstantReflection()); + if (result != null) { + return result; + } + return this; + } + + @Override + public LogicNode createLowerComparison(boolean swapInputs) { + ValueNode a = swapInputs ? y : x; + ValueNode b = swapInputs ? x : y; + if (unsigned) { + return IntegerBelowNode.create(a, b, NodeView.DEFAULT); + } else { + return IntegerLessThanNode.create(a, b, NodeView.DEFAULT); + } + } + + @Override + public LogicNode createLowerComparison(boolean swapInputs, ConstantReflectionProvider constantReflection, MetaAccessProvider metaAccess, OptionValues options, Integer smallestCompareWidth, + NodeView view) { + ValueNode a = swapInputs ? y : x; + ValueNode b = swapInputs ? x : y; + if (unsigned) { + return IntegerBelowNode.create(constantReflection, metaAccess, options, smallestCompareWidth, a, b, NodeView.DEFAULT); + } else { + return IntegerLessThanNode.create(constantReflection, metaAccess, options, smallestCompareWidth, a, b, NodeView.DEFAULT); + } + } + + @Override + public LogicNode createEqualComparison() { + return IntegerEqualsNode.create(x, y, NodeView.DEFAULT); + } + + @Override + public LogicNode createEqualComparison(ConstantReflectionProvider constantReflection, MetaAccessProvider metaAccess, OptionValues options, Integer smallestCompareWidth, NodeView view) { + return IntegerEqualsNode.create(constantReflection, metaAccess, options, smallestCompareWidth, x, y, view); + } +} diff -r e47423f1318b -r ca19b94eac7a src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/calc/IntegerTestNode.java --- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/calc/IntegerTestNode.java Mon Sep 23 09:16:05 2019 -0700 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/calc/IntegerTestNode.java Wed Sep 25 22:40:41 2019 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 2019, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -27,6 +27,8 @@ import static org.graalvm.compiler.nodeinfo.NodeCycles.CYCLES_2; import static org.graalvm.compiler.nodeinfo.NodeSize.SIZE_2; +import java.nio.ByteBuffer; + import org.graalvm.compiler.core.common.type.IntegerStamp; import org.graalvm.compiler.core.common.type.Stamp; import org.graalvm.compiler.graph.NodeClass; @@ -35,6 +37,7 @@ import org.graalvm.compiler.nodeinfo.NodeInfo; import org.graalvm.compiler.nodes.BinaryOpLogicNode; import org.graalvm.compiler.nodes.LogicConstantNode; +import org.graalvm.compiler.nodes.LogicNode; import org.graalvm.compiler.nodes.NodeView; import org.graalvm.compiler.nodes.ValueNode; @@ -53,11 +56,27 @@ super(TYPE, x, y); } - @Override - public ValueNode canonical(CanonicalizerTool tool, ValueNode forX, ValueNode forY) { - NodeView view = NodeView.from(tool); + public static LogicNode create(ValueNode x, ValueNode y, NodeView view) { + LogicNode value = canonical(x, y, view); + if (value != null) { + return value; + } + return new IntegerTestNode(x, y); + } + + private static LogicNode canonical(ValueNode forX, ValueNode forY, NodeView view) { if (forX.isConstant() && forY.isConstant()) { - return LogicConstantNode.forBoolean((forX.asJavaConstant().asLong() & forY.asJavaConstant().asLong()) == 0); + if (forX.isJavaConstant() && forY.isJavaConstant()) { + return LogicConstantNode.forBoolean((forX.asJavaConstant().asLong() & forY.asJavaConstant().asLong()) == 0); + } + if (forX.isSerializableConstant() && forY.isSerializableConstant()) { + int bufSize = Math.min(forX.asSerializableConstant().getSerializedSize(), forX.asSerializableConstant().getSerializedSize()); + ByteBuffer xBuf = ByteBuffer.allocate(bufSize); + ByteBuffer yBuf = ByteBuffer.allocate(bufSize); + forX.asSerializableConstant().serialize(xBuf); + forY.asSerializableConstant().serialize(yBuf); + return serializableToConst(xBuf, yBuf, bufSize); + } } if (forX.stamp(view) instanceof IntegerStamp && forY.stamp(view) instanceof IntegerStamp) { IntegerStamp xStamp = (IntegerStamp) forX.stamp(view); @@ -68,7 +87,22 @@ return LogicConstantNode.contradiction(); } } - return this; + return null; + } + + @Override + public ValueNode canonical(CanonicalizerTool tool, ValueNode forX, ValueNode forY) { + ValueNode value = canonical(forX, forY, NodeView.from(tool)); + return value != null ? value : this; + } + + private static LogicNode serializableToConst(ByteBuffer xBuf, ByteBuffer yBuf, int bufSize) { + for (int i = 0; i < bufSize; i++) { + if ((xBuf.get(i) & yBuf.get(i)) != 0) { + return LogicConstantNode.contradiction(); + } + } + return LogicConstantNode.tautology(); } @Override diff -r e47423f1318b -r ca19b94eac7a src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/calc/IsNullNode.java --- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/calc/IsNullNode.java Mon Sep 23 09:16:05 2019 -0700 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/calc/IsNullNode.java Wed Sep 25 22:40:41 2019 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2009, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2009, 2019, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it diff -r e47423f1318b -r ca19b94eac7a src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/calc/NarrowNode.java --- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/calc/NarrowNode.java Mon Sep 23 09:16:05 2019 -0700 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/calc/NarrowNode.java Wed Sep 25 22:40:41 2019 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 2019, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -26,12 +26,14 @@ import static org.graalvm.compiler.nodeinfo.NodeCycles.CYCLES_1; +import org.graalvm.compiler.core.common.calc.CanonicalCondition; import org.graalvm.compiler.core.common.type.ArithmeticOpTable; import org.graalvm.compiler.core.common.type.ArithmeticOpTable.IntegerConvertOp; import org.graalvm.compiler.core.common.type.ArithmeticOpTable.IntegerConvertOp.Narrow; import org.graalvm.compiler.core.common.type.ArithmeticOpTable.IntegerConvertOp.SignExtend; import org.graalvm.compiler.core.common.type.IntegerStamp; import org.graalvm.compiler.core.common.type.PrimitiveStamp; +import org.graalvm.compiler.core.common.type.Stamp; import org.graalvm.compiler.graph.NodeClass; import org.graalvm.compiler.graph.spi.CanonicalizerTool; import org.graalvm.compiler.lir.gen.ArithmeticLIRGeneratorTool; @@ -75,10 +77,33 @@ @Override public boolean isLossless() { + return checkLossless(this.getResultBits()); + } + + private boolean checkLossless(int bits) { + Stamp valueStamp = this.getValue().stamp(NodeView.DEFAULT); + if (bits > 0 && valueStamp instanceof IntegerStamp) { + IntegerStamp integerStamp = (IntegerStamp) valueStamp; + long valueUpMask = integerStamp.upMask(); + if ((valueUpMask & CodeUtil.mask(bits)) == valueUpMask) { + return true; + } + } return false; } @Override + public boolean preservesOrder(CanonicalCondition cond) { + switch (cond) { + case LT: + // Must guarantee that also sign bit does not flip. + return checkLossless(this.getResultBits() - 1); + default: + return checkLossless(this.getResultBits()); + } + } + + @Override public ValueNode canonical(CanonicalizerTool tool, ValueNode forValue) { NodeView view = NodeView.from(tool); ValueNode ret = super.canonical(tool, forValue); diff -r e47423f1318b -r ca19b94eac7a src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/calc/NormalizeCompareNode.java --- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/calc/NormalizeCompareNode.java Mon Sep 23 09:16:05 2019 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,113 +0,0 @@ -/* - * Copyright (c) 2009, 2018, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - - -package org.graalvm.compiler.nodes.calc; - -import static org.graalvm.compiler.nodeinfo.NodeSize.SIZE_2; - -import org.graalvm.compiler.core.common.calc.CanonicalCondition; -import org.graalvm.compiler.core.common.type.Stamp; -import org.graalvm.compiler.core.common.type.StampFactory; -import org.graalvm.compiler.graph.IterableNodeType; -import org.graalvm.compiler.graph.NodeClass; -import org.graalvm.compiler.graph.spi.CanonicalizerTool; -import org.graalvm.compiler.nodeinfo.NodeCycles; -import org.graalvm.compiler.nodeinfo.NodeInfo; -import org.graalvm.compiler.nodes.ConstantNode; -import org.graalvm.compiler.nodes.LogicConstantNode; -import org.graalvm.compiler.nodes.LogicNode; -import org.graalvm.compiler.nodes.NodeView; -import org.graalvm.compiler.nodes.ValueNode; - -import jdk.vm.ci.meta.ConstantReflectionProvider; -import jdk.vm.ci.meta.JavaKind; - -/** - * Returns -1, 0, or 1 if either x < y, x == y, or x > y. If the comparison is undecided (one - * of the inputs is NaN), the result is 1 if isUnorderedLess is false and -1 if isUnorderedLess is - * true. - */ -@NodeInfo(cycles = NodeCycles.CYCLES_2, size = SIZE_2) -public final class NormalizeCompareNode extends BinaryNode implements IterableNodeType { - - public static final NodeClass TYPE = NodeClass.create(NormalizeCompareNode.class); - protected final boolean isUnorderedLess; - - public NormalizeCompareNode(ValueNode x, ValueNode y, JavaKind kind, boolean isUnorderedLess) { - super(TYPE, StampFactory.forInteger(kind, -1, 1), x, y); - this.isUnorderedLess = isUnorderedLess; - } - - public static ValueNode create(ValueNode x, ValueNode y, boolean isUnorderedLess, JavaKind kind, ConstantReflectionProvider constantReflection) { - ValueNode result = tryConstantFold(x, y, isUnorderedLess, kind, constantReflection); - if (result != null) { - return result; - } - - return new NormalizeCompareNode(x, y, kind, isUnorderedLess); - } - - protected static ValueNode tryConstantFold(ValueNode x, ValueNode y, boolean isUnorderedLess, JavaKind kind, ConstantReflectionProvider constantReflection) { - LogicNode result = CompareNode.tryConstantFold(CanonicalCondition.EQ, x, y, null, false); - if (result instanceof LogicConstantNode) { - LogicConstantNode logicConstantNode = (LogicConstantNode) result; - LogicNode resultLT = CompareNode.tryConstantFold(CanonicalCondition.LT, x, y, constantReflection, isUnorderedLess); - if (resultLT instanceof LogicConstantNode) { - LogicConstantNode logicConstantNodeLT = (LogicConstantNode) resultLT; - if (logicConstantNodeLT.getValue()) { - return ConstantNode.forIntegerKind(kind, -1); - } else if (logicConstantNode.getValue()) { - return ConstantNode.forIntegerKind(kind, 0); - } else { - return ConstantNode.forIntegerKind(kind, 1); - } - } - } - return null; - } - - @Override - public ValueNode canonical(CanonicalizerTool tool, ValueNode forX, ValueNode forY) { - NodeView view = NodeView.from(tool); - ValueNode result = tryConstantFold(x, y, isUnorderedLess, stamp(view).getStackKind(), tool.getConstantReflection()); - if (result != null) { - return result; - } - return this; - } - - @Override - public boolean inferStamp() { - return false; - } - - @Override - public Stamp foldStamp(Stamp stampX, Stamp stampY) { - return stamp(NodeView.DEFAULT); - } - - public boolean isUnorderedLess() { - return isUnorderedLess; - } -} diff -r e47423f1318b -r ca19b94eac7a src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/calc/PointerEqualsNode.java --- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/calc/PointerEqualsNode.java Mon Sep 23 09:16:05 2019 -0700 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/calc/PointerEqualsNode.java Wed Sep 25 22:40:41 2019 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 2019, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it diff -r e47423f1318b -r ca19b94eac7a src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/calc/ReinterpretNode.java --- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/calc/ReinterpretNode.java Mon Sep 23 09:16:05 2019 -0700 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/calc/ReinterpretNode.java Wed Sep 25 22:40:41 2019 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2019, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it diff -r e47423f1318b -r ca19b94eac7a src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/cfg/Block.java --- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/cfg/Block.java Mon Sep 23 09:16:05 2019 -0700 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/cfg/Block.java Wed Sep 25 22:40:41 2019 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2009, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2009, 2019, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it diff -r e47423f1318b -r ca19b94eac7a src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/cfg/ControlFlowGraph.java --- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/cfg/ControlFlowGraph.java Mon Sep 23 09:16:05 2019 -0700 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/cfg/ControlFlowGraph.java Wed Sep 25 22:40:41 2019 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 2019, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it diff -r e47423f1318b -r ca19b94eac7a src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/extended/ArrayRangeWrite.java --- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/extended/ArrayRangeWrite.java Mon Sep 23 09:16:05 2019 -0700 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/extended/ArrayRangeWrite.java Wed Sep 25 22:40:41 2019 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2019, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it diff -r e47423f1318b -r ca19b94eac7a src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/extended/BranchProbabilityNode.java --- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/extended/BranchProbabilityNode.java Mon Sep 23 09:16:05 2019 -0700 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/extended/BranchProbabilityNode.java Wed Sep 25 22:40:41 2019 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2019, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -74,6 +74,8 @@ public static final double VERY_FAST_PATH_PROBABILITY = 0.999; public static final double VERY_SLOW_PATH_PROBABILITY = 1 - VERY_FAST_PATH_PROBABILITY; + public static final double DEOPT_PROBABILITY = 0.0; + /* * This probability may seem excessive, but it makes a difference in long running loops. Lets * say a loop is executed 100k times and it has a few null checks with probability 0.999. As diff -r e47423f1318b -r ca19b94eac7a src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/extended/ForeignCallNode.java --- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/extended/ForeignCallNode.java Mon Sep 23 09:16:05 2019 -0700 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/extended/ForeignCallNode.java Wed Sep 25 22:40:41 2019 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 2019, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it diff -r e47423f1318b -r ca19b94eac7a src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/extended/GuardedUnsafeLoadNode.java --- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/extended/GuardedUnsafeLoadNode.java Mon Sep 23 09:16:05 2019 -0700 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/extended/GuardedUnsafeLoadNode.java Wed Sep 25 22:40:41 2019 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2019, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it diff -r e47423f1318b -r ca19b94eac7a src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/extended/IntegerSwitchNode.java --- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/extended/IntegerSwitchNode.java Mon Sep 23 09:16:05 2019 -0700 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/extended/IntegerSwitchNode.java Wed Sep 25 22:40:41 2019 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2009, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2009, 2019, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it diff -r e47423f1318b -r ca19b94eac7a src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/extended/JavaWriteNode.java --- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/extended/JavaWriteNode.java Mon Sep 23 09:16:05 2019 -0700 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/extended/JavaWriteNode.java Wed Sep 25 22:40:41 2019 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 2019, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it diff -r e47423f1318b -r ca19b94eac7a src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/extended/LoadHubNode.java --- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/extended/LoadHubNode.java Mon Sep 23 09:16:05 2019 -0700 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/extended/LoadHubNode.java Wed Sep 25 22:40:41 2019 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 2019, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -28,6 +28,7 @@ import static org.graalvm.compiler.nodeinfo.NodeCycles.CYCLES_2; import static org.graalvm.compiler.nodeinfo.NodeSize.SIZE_1; +import org.graalvm.compiler.core.common.type.AbstractPointerStamp; import org.graalvm.compiler.core.common.type.ObjectStamp; import org.graalvm.compiler.core.common.type.Stamp; import org.graalvm.compiler.core.common.type.TypeReference; @@ -62,13 +63,17 @@ return value; } - private static Stamp hubStamp(StampProvider stampProvider, ValueNode value) { + private static AbstractPointerStamp hubStamp(StampProvider stampProvider, ValueNode value) { assert value.stamp(NodeView.DEFAULT) instanceof ObjectStamp; return stampProvider.createHubStamp(((ObjectStamp) value.stamp(NodeView.DEFAULT))); } public static ValueNode create(ValueNode value, StampProvider stampProvider, MetaAccessProvider metaAccess, ConstantReflectionProvider constantReflection) { - Stamp stamp = hubStamp(stampProvider, value); + final AbstractPointerStamp stamp = hubStamp(stampProvider, value); + return create(value, stamp, metaAccess, constantReflection); + } + + public static ValueNode create(ValueNode value, AbstractPointerStamp stamp, MetaAccessProvider metaAccess, ConstantReflectionProvider constantReflection) { ValueNode synonym = findSynonym(value, stamp, metaAccess, constantReflection); if (synonym != null) { return synonym; diff -r e47423f1318b -r ca19b94eac7a src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/extended/LoadHubOrNullNode.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/extended/LoadHubOrNullNode.java Wed Sep 25 22:40:41 2019 +0200 @@ -0,0 +1,129 @@ +/* + * Copyright (c) 2011, 2019, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + + +package org.graalvm.compiler.nodes.extended; + +import static org.graalvm.compiler.core.common.GraalOptions.GeneratePIC; +import static org.graalvm.compiler.nodeinfo.NodeCycles.CYCLES_2; +import static org.graalvm.compiler.nodeinfo.NodeSize.SIZE_1; + +import org.graalvm.compiler.core.common.type.AbstractPointerStamp; +import org.graalvm.compiler.core.common.type.ObjectStamp; +import org.graalvm.compiler.core.common.type.Stamp; +import org.graalvm.compiler.core.common.type.TypeReference; +import org.graalvm.compiler.graph.NodeClass; +import org.graalvm.compiler.graph.spi.Canonicalizable; +import org.graalvm.compiler.graph.spi.CanonicalizerTool; +import org.graalvm.compiler.nodeinfo.NodeInfo; +import org.graalvm.compiler.nodes.ConstantNode; +import org.graalvm.compiler.nodes.NodeView; +import org.graalvm.compiler.nodes.ValueNode; +import org.graalvm.compiler.nodes.calc.FloatingNode; +import org.graalvm.compiler.nodes.spi.Lowerable; +import org.graalvm.compiler.nodes.spi.LoweringTool; +import org.graalvm.compiler.nodes.spi.StampProvider; +import org.graalvm.compiler.nodes.spi.Virtualizable; +import org.graalvm.compiler.nodes.spi.VirtualizerTool; +import org.graalvm.compiler.nodes.type.StampTool; + +import jdk.vm.ci.meta.ConstantReflectionProvider; +import jdk.vm.ci.meta.MetaAccessProvider; + +/** + * Loads an object's hub, or null if the object is null. + */ +@NodeInfo(cycles = CYCLES_2, size = SIZE_1) +public final class LoadHubOrNullNode extends FloatingNode implements Lowerable, Canonicalizable, Virtualizable { + + public static final NodeClass TYPE = NodeClass.create(LoadHubOrNullNode.class); + @Input ValueNode value; + + public ValueNode getValue() { + return value; + } + + private static AbstractPointerStamp hubStamp(StampProvider stampProvider, ValueNode value) { + assert value.stamp(NodeView.DEFAULT) instanceof ObjectStamp; + return stampProvider.createHubStamp(((ObjectStamp) value.stamp(NodeView.DEFAULT))).asMaybeNull(); + } + + public static ValueNode create(ValueNode value, StampProvider stampProvider, MetaAccessProvider metaAccess, ConstantReflectionProvider constantReflection) { + AbstractPointerStamp stamp = hubStamp(stampProvider, value); + return create(value, stamp, metaAccess, constantReflection); + } + + public static ValueNode create(ValueNode value, AbstractPointerStamp stamp, MetaAccessProvider metaAccess, ConstantReflectionProvider constantReflection) { + ValueNode synonym = findSynonym(value, stamp, metaAccess, constantReflection); + if (synonym != null) { + return synonym; + } + return new LoadHubOrNullNode(stamp, value); + } + + public LoadHubOrNullNode(@InjectedNodeParameter StampProvider stampProvider, ValueNode value) { + this(hubStamp(stampProvider, value), value); + } + + public LoadHubOrNullNode(Stamp stamp, ValueNode value) { + super(TYPE, stamp); + this.value = value; + } + + @Override + public void lower(LoweringTool tool) { + tool.getLowerer().lower(this, tool); + } + + @Override + public ValueNode canonical(CanonicalizerTool tool) { + if (!GeneratePIC.getValue(tool.getOptions())) { + NodeView view = NodeView.from(tool); + MetaAccessProvider metaAccess = tool.getMetaAccess(); + ValueNode curValue = getValue(); + ValueNode newNode = findSynonym(curValue, (AbstractPointerStamp) stamp(view), metaAccess, tool.getConstantReflection()); + if (newNode != null) { + return newNode; + } + } + return this; + } + + public static ValueNode findSynonym(ValueNode curValue, AbstractPointerStamp stamp, MetaAccessProvider metaAccess, ConstantReflectionProvider constantReflection) { + if (StampTool.isPointerNonNull(stamp)) { + return LoadHubNode.create(curValue, stamp.asNonNull(), metaAccess, constantReflection); + } + return null; + } + + @Override + public void virtualize(VirtualizerTool tool) { + if (!GeneratePIC.getValue(tool.getOptions())) { + ValueNode alias = tool.getAlias(getValue()); + TypeReference type = StampTool.typeReferenceOrNull(alias); + if (type != null && type.isExact()) { + tool.replaceWithValue(ConstantNode.forConstant(stamp(NodeView.DEFAULT), tool.getConstantReflection().asObjectHub(type.getType()), tool.getMetaAccess(), graph())); + } + } + } +} diff -r e47423f1318b -r ca19b94eac7a src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/extended/MultiGuardNode.java --- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/extended/MultiGuardNode.java Mon Sep 23 09:16:05 2019 -0700 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/extended/MultiGuardNode.java Wed Sep 25 22:40:41 2019 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 2019, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -32,6 +32,8 @@ import org.graalvm.compiler.graph.Node; import org.graalvm.compiler.graph.NodeClass; import org.graalvm.compiler.graph.NodeInputList; +import org.graalvm.compiler.graph.spi.Canonicalizable; +import org.graalvm.compiler.graph.spi.CanonicalizerTool; import org.graalvm.compiler.graph.spi.Simplifiable; import org.graalvm.compiler.graph.spi.SimplifierTool; import org.graalvm.compiler.nodeinfo.NodeInfo; @@ -43,7 +45,7 @@ import org.graalvm.compiler.nodes.util.GraphUtil; @NodeInfo(allowedUsageTypes = Guard, cycles = CYCLES_0, size = SIZE_0) -public final class MultiGuardNode extends FloatingNode implements GuardingNode, LIRLowerable, Simplifiable, Node.ValueNumberable { +public final class MultiGuardNode extends FloatingNode implements GuardingNode, LIRLowerable, Simplifiable, Canonicalizable, Node.ValueNumberable { public static final NodeClass TYPE = NodeClass.create(MultiGuardNode.class); @OptionalInput(Guard) NodeInputList guards; @@ -58,6 +60,20 @@ } @Override + public Node canonical(CanonicalizerTool tool) { + // Make sure there are no nulls remaining in the set of guards references. + guards.trim(); + if (guards.size() == 0) { + // No guards left => can delete the multi-guard. + return null; + } else if (guards.size() == 1) { + // Only a single guard left => replace multi-guard with that single guard. + return guards.get(0); + } + return this; + } + + @Override public void simplify(SimplifierTool tool) { if (usages().filter(node -> node instanceof ValueAnchorNode).isNotEmpty()) { /* diff -r e47423f1318b -r ca19b94eac7a src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/extended/SwitchNode.java --- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/extended/SwitchNode.java Mon Sep 23 09:16:05 2019 -0700 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/extended/SwitchNode.java Wed Sep 25 22:40:41 2019 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2009, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2009, 2019, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it diff -r e47423f1318b -r ca19b94eac7a src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/graphbuilderconf/GeneratedInvocationPlugin.java --- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/graphbuilderconf/GeneratedInvocationPlugin.java Mon Sep 23 09:16:05 2019 -0700 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/graphbuilderconf/GeneratedInvocationPlugin.java Wed Sep 25 22:40:41 2019 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2019, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -109,4 +109,8 @@ throw new GraalError(e); } } + + public final boolean isGeneratedFromFoldOrNodeIntrinsic() { + return getSource().equals(Fold.class) || getSource().equals(NodeIntrinsic.class); + } } diff -r e47423f1318b -r ca19b94eac7a src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/graphbuilderconf/GraphBuilderConfiguration.java --- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/graphbuilderconf/GraphBuilderConfiguration.java Mon Sep 23 09:16:05 2019 -0700 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/graphbuilderconf/GraphBuilderConfiguration.java Wed Sep 25 22:40:41 2019 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 2019, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it diff -r e47423f1318b -r ca19b94eac7a src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/graphbuilderconf/GraphBuilderContext.java --- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/graphbuilderconf/GraphBuilderContext.java Mon Sep 23 09:16:05 2019 -0700 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/graphbuilderconf/GraphBuilderContext.java Wed Sep 25 22:40:41 2019 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2019, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -258,6 +258,13 @@ } /** + * Determines if a graph builder plugin is enabled under current context. + */ + default boolean isPluginEnabled(GraphBuilderPlugin plugin) { + return parsingIntrinsic() || !(plugin instanceof GeneratedInvocationPlugin && ((GeneratedInvocationPlugin) plugin).isGeneratedFromFoldOrNodeIntrinsic()); + } + + /** * Gets the intrinsic of the current parsing context or {@code null} if not * {@link #parsingIntrinsic() parsing an intrinsic}. */ diff -r e47423f1318b -r ca19b94eac7a src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/graphbuilderconf/GraphBuilderTool.java --- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/graphbuilderconf/GraphBuilderTool.java Mon Sep 23 09:16:05 2019 -0700 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/graphbuilderconf/GraphBuilderTool.java Wed Sep 25 22:40:41 2019 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2019, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it diff -r e47423f1318b -r ca19b94eac7a src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/graphbuilderconf/InlineInvokePlugin.java --- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/graphbuilderconf/InlineInvokePlugin.java Mon Sep 23 09:16:05 2019 -0700 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/graphbuilderconf/InlineInvokePlugin.java Wed Sep 25 22:40:41 2019 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2019, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it diff -r e47423f1318b -r ca19b94eac7a src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/graphbuilderconf/IntrinsicContext.java --- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/graphbuilderconf/IntrinsicContext.java Mon Sep 23 09:16:05 2019 -0700 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/graphbuilderconf/IntrinsicContext.java Wed Sep 25 22:40:41 2019 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2019, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it diff -r e47423f1318b -r ca19b94eac7a src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/graphbuilderconf/InvocationPlugins.java --- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/graphbuilderconf/InvocationPlugins.java Mon Sep 23 09:16:05 2019 -0700 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/graphbuilderconf/InvocationPlugins.java Wed Sep 25 22:40:41 2019 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2019, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -702,8 +702,10 @@ } if (res != null) { // A decorator plugin is trusted since it does not replace - // the method it intrinsifies. - if (res.isDecorator() || canBeIntrinsified(declaringClass)) { + // the method it intrinsifies. A GeneratedInvocationPlugin + // is trusted since it only exists for @NodeIntrinsics and + // @Fold annotated methods (i.e., trusted Graal code). + if (res.isDecorator() || res instanceof GeneratedInvocationPlugin || canBeIntrinsified(declaringClass)) { return res; } } diff -r e47423f1318b -r ca19b94eac7a src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/graphbuilderconf/MethodSubstitutionPlugin.java --- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/graphbuilderconf/MethodSubstitutionPlugin.java Mon Sep 23 09:16:05 2019 -0700 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/graphbuilderconf/MethodSubstitutionPlugin.java Wed Sep 25 22:40:41 2019 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2019, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it diff -r e47423f1318b -r ca19b94eac7a src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/java/AbstractNewObjectNode.java --- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/java/AbstractNewObjectNode.java Mon Sep 23 09:16:05 2019 -0700 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/java/AbstractNewObjectNode.java Wed Sep 25 22:40:41 2019 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2009, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2009, 2019, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it diff -r e47423f1318b -r ca19b94eac7a src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/java/ArrayLengthNode.java --- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/java/ArrayLengthNode.java Mon Sep 23 09:16:05 2019 -0700 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/java/ArrayLengthNode.java Wed Sep 25 22:40:41 2019 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2009, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2009, 2019, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it diff -r e47423f1318b -r ca19b94eac7a src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/java/LoadIndexedNode.java --- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/java/LoadIndexedNode.java Mon Sep 23 09:16:05 2019 -0700 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/java/LoadIndexedNode.java Wed Sep 25 22:40:41 2019 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2009, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2009, 2019, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it diff -r e47423f1318b -r ca19b94eac7a src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/java/MonitorExitNode.java --- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/java/MonitorExitNode.java Mon Sep 23 09:16:05 2019 -0700 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/java/MonitorExitNode.java Wed Sep 25 22:40:41 2019 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2009, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2009, 2019, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it diff -r e47423f1318b -r ca19b94eac7a src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/java/NewArrayNode.java --- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/java/NewArrayNode.java Mon Sep 23 09:16:05 2019 -0700 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/java/NewArrayNode.java Wed Sep 25 22:40:41 2019 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2009, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2009, 2019, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it diff -r e47423f1318b -r ca19b94eac7a src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/java/NewInstanceNode.java --- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/java/NewInstanceNode.java Mon Sep 23 09:16:05 2019 -0700 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/java/NewInstanceNode.java Wed Sep 25 22:40:41 2019 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2009, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2009, 2019, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it diff -r e47423f1318b -r ca19b94eac7a src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/java/StoreFieldNode.java --- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/java/StoreFieldNode.java Mon Sep 23 09:16:05 2019 -0700 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/java/StoreFieldNode.java Wed Sep 25 22:40:41 2019 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2009, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2009, 2019, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it diff -r e47423f1318b -r ca19b94eac7a src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/java/StoreIndexedNode.java --- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/java/StoreIndexedNode.java Mon Sep 23 09:16:05 2019 -0700 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/java/StoreIndexedNode.java Wed Sep 25 22:40:41 2019 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2009, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2009, 2019, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it diff -r e47423f1318b -r ca19b94eac7a src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/java/TypeSwitchNode.java --- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/java/TypeSwitchNode.java Mon Sep 23 09:16:05 2019 -0700 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/java/TypeSwitchNode.java Wed Sep 25 22:40:41 2019 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2009, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2009, 2019, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it diff -r e47423f1318b -r ca19b94eac7a src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/memory/AbstractWriteNode.java --- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/memory/AbstractWriteNode.java Mon Sep 23 09:16:05 2019 -0700 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/memory/AbstractWriteNode.java Wed Sep 25 22:40:41 2019 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 2019, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it diff -r e47423f1318b -r ca19b94eac7a src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/memory/FixedAccessNode.java --- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/memory/FixedAccessNode.java Mon Sep 23 09:16:05 2019 -0700 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/memory/FixedAccessNode.java Wed Sep 25 22:40:41 2019 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 2019, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -25,7 +25,6 @@ package org.graalvm.compiler.nodes.memory; import org.graalvm.compiler.core.common.type.Stamp; -import org.graalvm.compiler.graph.IterableNodeType; import org.graalvm.compiler.graph.NodeClass; import org.graalvm.compiler.nodeinfo.InputType; import org.graalvm.compiler.nodeinfo.NodeInfo; @@ -40,7 +39,7 @@ * does not include a null check on the object. */ @NodeInfo -public abstract class FixedAccessNode extends DeoptimizingFixedWithNextNode implements Access, IterableNodeType { +public abstract class FixedAccessNode extends DeoptimizingFixedWithNextNode implements Access { public static final NodeClass TYPE = NodeClass.create(FixedAccessNode.class); @OptionalInput(InputType.Guard) protected GuardingNode guard; diff -r e47423f1318b -r ca19b94eac7a src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/memory/HeapAccess.java --- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/memory/HeapAccess.java Mon Sep 23 09:16:05 2019 -0700 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/memory/HeapAccess.java Wed Sep 25 22:40:41 2019 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2019, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it diff -r e47423f1318b -r ca19b94eac7a src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/memory/address/IndexAddressNode.java --- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/memory/address/IndexAddressNode.java Mon Sep 23 09:16:05 2019 -0700 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/memory/address/IndexAddressNode.java Wed Sep 25 22:40:41 2019 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2019, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it diff -r e47423f1318b -r ca19b94eac7a src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/spi/DelegatingReplacements.java --- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/spi/DelegatingReplacements.java Mon Sep 23 09:16:05 2019 -0700 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/spi/DelegatingReplacements.java Wed Sep 25 22:40:41 2019 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2019, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it diff -r e47423f1318b -r ca19b94eac7a src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/spi/LoweringProvider.java --- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/spi/LoweringProvider.java Mon Sep 23 09:16:05 2019 -0700 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/spi/LoweringProvider.java Wed Sep 25 22:40:41 2019 +0200 @@ -53,7 +53,8 @@ Integer smallestCompareWidth(); /** - * Indicates whether the target platform supports bulk zeroing instruction. + * Returns the granularity in terms of bytes that this target platform's bulk zeroing supports. + * Returns 0 to indicate that this target platform does not support bulk zeroing instruction. */ - boolean supportBulkZeroing(); + int bulkZeroingStride(); } diff -r e47423f1318b -r ca19b94eac7a src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/spi/LoweringTool.java --- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/spi/LoweringTool.java Mon Sep 23 09:16:05 2019 -0700 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/spi/LoweringTool.java Wed Sep 25 22:40:41 2019 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 2019, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it diff -r e47423f1318b -r ca19b94eac7a src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/spi/Replacements.java --- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/spi/Replacements.java Mon Sep 23 09:16:05 2019 -0700 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/spi/Replacements.java Wed Sep 25 22:40:41 2019 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2019, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it diff -r e47423f1318b -r ca19b94eac7a src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/spi/StampProvider.java --- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/spi/StampProvider.java Mon Sep 23 09:16:05 2019 -0700 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/spi/StampProvider.java Wed Sep 25 22:40:41 2019 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 2019, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -24,8 +24,8 @@ package org.graalvm.compiler.nodes.spi; +import org.graalvm.compiler.core.common.type.AbstractPointerStamp; import org.graalvm.compiler.core.common.type.ObjectStamp; -import org.graalvm.compiler.core.common.type.Stamp; import org.graalvm.compiler.nodes.extended.LoadHubNode; /** @@ -36,10 +36,10 @@ /** * Create the stamp of the {@link LoadHubNode hub} of an object. */ - Stamp createHubStamp(ObjectStamp object); + AbstractPointerStamp createHubStamp(ObjectStamp object); /** * Create the stamp of a pointer to a method. */ - Stamp createMethodStamp(); + AbstractPointerStamp createMethodStamp(); } diff -r e47423f1318b -r ca19b94eac7a src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/type/NarrowOopStamp.java --- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/type/NarrowOopStamp.java Mon Sep 23 09:16:05 2019 -0700 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/type/NarrowOopStamp.java Wed Sep 25 22:40:41 2019 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 2019, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it diff -r e47423f1318b -r ca19b94eac7a src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/util/GraphUtil.java --- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/util/GraphUtil.java Mon Sep 23 09:16:05 2019 -0700 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/util/GraphUtil.java Wed Sep 25 22:40:41 2019 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 2019, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it diff -r e47423f1318b -r ca19b94eac7a src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/util/IntegerHelper.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/util/IntegerHelper.java Wed Sep 25 22:40:41 2019 +0200 @@ -0,0 +1,86 @@ +/* + * Copyright (c) 2018, 2019, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + + +package org.graalvm.compiler.nodes.util; + +import org.graalvm.compiler.core.common.type.IntegerStamp; +import org.graalvm.compiler.nodes.LogicNode; +import org.graalvm.compiler.nodes.NodeView; +import org.graalvm.compiler.nodes.ValueNode; + +public abstract class IntegerHelper { + protected final int bits; + + protected IntegerHelper(int bits) { + this.bits = bits; + } + + public abstract long upperBound(IntegerStamp stamp); + + public abstract long lowerBound(IntegerStamp stamp); + + public int compare(long a, long b) { + return rawCompare(cast(a), cast(b)); + } + + public boolean isGreater(long a, long b) { + return compare(a, b) > 0; + } + + public boolean isSmaller(long a, long b) { + return compare(a, b) < 0; + } + + public boolean isGreaterEqual(long a, long b) { + return compare(a, b) >= 0; + } + + public boolean isSmallerEqual(long a, long b) { + return compare(a, b) <= 0; + } + + public long min(long a, long b) { + return rawMin(cast(a), cast(b)); + } + + public long max(long a, long b) { + return rawMax(cast(a), cast(b)); + } + + public abstract long cast(long a); + + public abstract long minValue(); + + public abstract long maxValue(); + + public abstract IntegerStamp stamp(long min, long max); + + public abstract LogicNode createCompareNode(ValueNode x, ValueNode y, NodeView view); + + protected abstract int rawCompare(long a, long b); + + protected abstract long rawMin(long a, long b); + + protected abstract long rawMax(long a, long b); +} diff -r e47423f1318b -r ca19b94eac7a src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/util/SignedIntegerHelper.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/util/SignedIntegerHelper.java Wed Sep 25 22:40:41 2019 +0200 @@ -0,0 +1,93 @@ +/* + * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + + +package org.graalvm.compiler.nodes.util; + +import org.graalvm.compiler.core.common.NumUtil; +import org.graalvm.compiler.core.common.type.IntegerStamp; +import org.graalvm.compiler.core.common.type.StampFactory; +import org.graalvm.compiler.nodes.LogicNode; +import org.graalvm.compiler.nodes.NodeView; +import org.graalvm.compiler.nodes.ValueNode; +import org.graalvm.compiler.nodes.calc.IntegerLessThanNode; + +import jdk.vm.ci.code.CodeUtil; + +public class SignedIntegerHelper extends IntegerHelper { + public SignedIntegerHelper(int bits) { + super(bits); + } + + @Override + public long upperBound(IntegerStamp stamp) { + assert stamp.getBits() == bits; + return stamp.upperBound(); + } + + @Override + public long lowerBound(IntegerStamp stamp) { + assert stamp.getBits() == bits; + return stamp.lowerBound(); + } + + @Override + protected int rawCompare(long a, long b) { + return Long.compare(a, b); + } + + @Override + protected long rawMin(long a, long b) { + return Math.min(a, b); + } + + @Override + protected long rawMax(long a, long b) { + return Math.max(a, b); + } + + @Override + public long cast(long a) { + return CodeUtil.signExtend(a, bits); + } + + @Override + public long minValue() { + return NumUtil.minValue(bits); + } + + @Override + public long maxValue() { + return NumUtil.maxValue(bits); + } + + @Override + public IntegerStamp stamp(long min, long max) { + return StampFactory.forInteger(bits, cast(min), cast(max)); + } + + @Override + public LogicNode createCompareNode(ValueNode x, ValueNode y, NodeView view) { + return IntegerLessThanNode.create(x, y, view); + } +} diff -r e47423f1318b -r ca19b94eac7a src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/util/UnsignedIntegerHelper.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/util/UnsignedIntegerHelper.java Wed Sep 25 22:40:41 2019 +0200 @@ -0,0 +1,93 @@ +/* + * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + + +package org.graalvm.compiler.nodes.util; + +import org.graalvm.compiler.core.common.NumUtil; +import org.graalvm.compiler.core.common.type.IntegerStamp; +import org.graalvm.compiler.core.common.type.StampFactory; +import org.graalvm.compiler.nodes.LogicNode; +import org.graalvm.compiler.nodes.NodeView; +import org.graalvm.compiler.nodes.ValueNode; +import org.graalvm.compiler.nodes.calc.IntegerBelowNode; + +import jdk.vm.ci.code.CodeUtil; + +public class UnsignedIntegerHelper extends IntegerHelper { + public UnsignedIntegerHelper(int bits) { + super(bits); + } + + @Override + public long upperBound(IntegerStamp stamp) { + assert stamp.getBits() == bits; + return stamp.unsignedUpperBound(); + } + + @Override + public long lowerBound(IntegerStamp stamp) { + assert stamp.getBits() == bits; + return stamp.unsignedLowerBound(); + } + + @Override + protected int rawCompare(long a, long b) { + return Long.compareUnsigned(a, b); + } + + @Override + protected long rawMin(long a, long b) { + return NumUtil.minUnsigned(a, b); + } + + @Override + protected long rawMax(long a, long b) { + return NumUtil.maxUnsigned(a, b); + } + + @Override + public long cast(long a) { + return CodeUtil.zeroExtend(a, bits); + } + + @Override + public long minValue() { + return 0; + } + + @Override + public long maxValue() { + return NumUtil.maxValueUnsigned(bits); + } + + @Override + public IntegerStamp stamp(long min, long max) { + return StampFactory.forUnsignedInteger(bits, min, max); + } + + @Override + public LogicNode createCompareNode(ValueNode x, ValueNode y, NodeView view) { + return IntegerBelowNode.create(x, y, view); + } +} diff -r e47423f1318b -r ca19b94eac7a src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.options.processor/src/org/graalvm/compiler/options/processor/OptionProcessor.java --- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.options.processor/src/org/graalvm/compiler/options/processor/OptionProcessor.java Mon Sep 23 09:16:05 2019 -0700 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.options.processor/src/org/graalvm/compiler/options/processor/OptionProcessor.java Wed Sep 25 22:40:41 2019 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2019, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it diff -r e47423f1318b -r ca19b94eac7a src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.options/src/org/graalvm/compiler/options/ModuleSupport.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.options/src/org/graalvm/compiler/options/ModuleSupport.java Wed Sep 25 22:40:41 2019 +0200 @@ -0,0 +1,40 @@ +/* + * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + + +package org.graalvm.compiler.options; + +import java.util.ServiceLoader; + +public class ModuleSupport { + + static Iterable getOptionsLoader() { + /* + * The Graal module (i.e., jdk.internal.vm.compiler) is loaded by the platform class loader + * as of JDK 9. Modules that depend on and extend Graal are loaded by the app class loader. + * As such, we need to start the provider search at the app class loader instead of the + * platform class loader. + */ + return ServiceLoader.load(OptionDescriptors.class, ClassLoader.getSystemClassLoader()); + } +} diff -r e47423f1318b -r ca19b94eac7a src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.options/src/org/graalvm/compiler/options/Option.java --- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.options/src/org/graalvm/compiler/options/Option.java Mon Sep 23 09:16:05 2019 -0700 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.options/src/org/graalvm/compiler/options/Option.java Wed Sep 25 22:40:41 2019 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2019, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it diff -r e47423f1318b -r ca19b94eac7a src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.options/src/org/graalvm/compiler/options/OptionDescriptor.java --- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.options/src/org/graalvm/compiler/options/OptionDescriptor.java Mon Sep 23 09:16:05 2019 -0700 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.options/src/org/graalvm/compiler/options/OptionDescriptor.java Wed Sep 25 22:40:41 2019 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2019, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it diff -r e47423f1318b -r ca19b94eac7a src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.options/src/org/graalvm/compiler/options/OptionKey.java --- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.options/src/org/graalvm/compiler/options/OptionKey.java Mon Sep 23 09:16:05 2019 -0700 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.options/src/org/graalvm/compiler/options/OptionKey.java Wed Sep 25 22:40:41 2019 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2019, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it diff -r e47423f1318b -r ca19b94eac7a src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.options/src/org/graalvm/compiler/options/OptionValues.java --- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.options/src/org/graalvm/compiler/options/OptionValues.java Mon Sep 23 09:16:05 2019 -0700 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.options/src/org/graalvm/compiler/options/OptionValues.java Wed Sep 25 22:40:41 2019 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2019, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it diff -r e47423f1318b -r ca19b94eac7a src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.options/src/org/graalvm/compiler/options/OptionsParser.java --- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.options/src/org/graalvm/compiler/options/OptionsParser.java Mon Sep 23 09:16:05 2019 -0700 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.options/src/org/graalvm/compiler/options/OptionsParser.java Wed Sep 25 22:40:41 2019 +0200 @@ -36,8 +36,6 @@ import jdk.internal.vm.compiler.collections.EconomicMap; import jdk.internal.vm.compiler.collections.MapCursor; -import jdk.vm.ci.services.Services; - /** * This class contains methods for parsing Graal options and matching them against a set of * {@link OptionDescriptors}. The {@link OptionDescriptors} are loaded via a {@link ServiceLoader}. @@ -53,26 +51,12 @@ if (IS_IN_NATIVE_IMAGE || cachedOptionDescriptors != null) { return cachedOptionDescriptors; } - boolean java8OrEarlier = Services.getSavedProperties().get("java.specification.version").compareTo("1.9") < 0; - ClassLoader loader; - if (java8OrEarlier) { - // On JDK 8, Graal and its extensions are loaded by same class loader. - loader = OptionDescriptors.class.getClassLoader(); - } else { - /* - * The Graal module (i.e., jdk.internal.vm.compiler) is loaded by the platform class - * loader as of JDK 9. Modules that depend on and extend Graal are loaded by the app - * class loader. As such, we need to start the provider search at the app class loader - * instead of the platform class loader. - */ - loader = ClassLoader.getSystemClassLoader(); - } - return ServiceLoader.load(OptionDescriptors.class, loader); + return ModuleSupport.getOptionsLoader(); } - public static void setCachedOptionDescriptors(List cachedOptionDescriptors) { + public static void setCachedOptionDescriptors(List list) { assert IS_BUILDING_NATIVE_IMAGE : "Used to pre-initialize the option descriptors during native image generation"; - OptionsParser.cachedOptionDescriptors = cachedOptionDescriptors; + OptionsParser.cachedOptionDescriptors = list; } /** diff -r e47423f1318b -r ca19b94eac7a src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.phases.common/src/org/graalvm/compiler/phases/common/AddressLoweringByUsePhase.java --- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.phases.common/src/org/graalvm/compiler/phases/common/AddressLoweringByUsePhase.java Mon Sep 23 09:16:05 2019 -0700 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.phases.common/src/org/graalvm/compiler/phases/common/AddressLoweringByUsePhase.java Wed Sep 25 22:40:41 2019 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2019, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2017, Red Hat Inc. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -69,7 +69,7 @@ AddressNode lowered; if (node instanceof ReadNode) { ReadNode readNode = (ReadNode) node; - Stamp stamp = readNode.stamp(NodeView.DEFAULT); + Stamp stamp = readNode.getAccessStamp(); address = readNode.getAddress(); lowered = lowering.lower(readNode, stamp, address); } else if (node instanceof JavaReadNode) { @@ -79,12 +79,12 @@ lowered = lowering.lower(javaReadNode, stamp, address); } else if (node instanceof FloatingReadNode) { FloatingReadNode floatingReadNode = (FloatingReadNode) node; - Stamp stamp = floatingReadNode.stamp(NodeView.DEFAULT); + Stamp stamp = floatingReadNode.getAccessStamp(); address = floatingReadNode.getAddress(); lowered = lowering.lower(floatingReadNode, stamp, address); } else if (node instanceof AbstractWriteNode) { AbstractWriteNode abstractWriteNode = (AbstractWriteNode) node; - Stamp stamp = abstractWriteNode.value().stamp(NodeView.DEFAULT); + Stamp stamp = abstractWriteNode.getAccessStamp(); address = abstractWriteNode.getAddress(); lowered = lowering.lower(abstractWriteNode, stamp, address); } else if (node instanceof PrefetchAllocateNode) { diff -r e47423f1318b -r ca19b94eac7a src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.phases.common/src/org/graalvm/compiler/phases/common/CanonicalizerPhase.java --- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.phases.common/src/org/graalvm/compiler/phases/common/CanonicalizerPhase.java Mon Sep 23 09:16:05 2019 -0700 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.phases.common/src/org/graalvm/compiler/phases/common/CanonicalizerPhase.java Wed Sep 25 22:40:41 2019 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 2019, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it diff -r e47423f1318b -r ca19b94eac7a src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.phases.common/src/org/graalvm/compiler/phases/common/ConditionalEliminationPhase.java --- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.phases.common/src/org/graalvm/compiler/phases/common/ConditionalEliminationPhase.java Mon Sep 23 09:16:05 2019 -0700 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.phases.common/src/org/graalvm/compiler/phases/common/ConditionalEliminationPhase.java Wed Sep 25 22:40:41 2019 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2019, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -309,7 +309,7 @@ this.conditions = new ArrayDeque<>(); tool = GraphUtil.getDefaultSimplifier(context.getMetaAccess(), context.getConstantReflection(), context.getConstantFieldProvider(), false, graph.getAssumptions(), graph.getOptions(), context.getLowerer()); - mergeMaps = EconomicMap.create(); + mergeMaps = EconomicMap.create(Equivalence.IDENTITY); } protected void processConditionAnchor(ConditionAnchorNode node) { @@ -616,7 +616,7 @@ Stamp newStamp = infoElement.getStamp(); if (phi.stamp(NodeView.DEFAULT).tryImproveWith(newStamp) != null) { if (mergeMap == null) { - mergeMap = EconomicMap.create(); + mergeMap = EconomicMap.create(Equivalence.IDENTITY); mergeMaps.put(merge, mergeMap); } diff -r e47423f1318b -r ca19b94eac7a src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.phases.common/src/org/graalvm/compiler/phases/common/DeoptimizationGroupingPhase.java --- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.phases.common/src/org/graalvm/compiler/phases/common/DeoptimizationGroupingPhase.java Mon Sep 23 09:16:05 2019 -0700 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.phases.common/src/org/graalvm/compiler/phases/common/DeoptimizationGroupingPhase.java Wed Sep 25 22:40:41 2019 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2019, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it diff -r e47423f1318b -r ca19b94eac7a src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.phases.common/src/org/graalvm/compiler/phases/common/ExpandLogicPhase.java --- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.phases.common/src/org/graalvm/compiler/phases/common/ExpandLogicPhase.java Mon Sep 23 09:16:05 2019 -0700 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.phases.common/src/org/graalvm/compiler/phases/common/ExpandLogicPhase.java Wed Sep 25 22:40:41 2019 +0200 @@ -24,7 +24,6 @@ package org.graalvm.compiler.phases.common; -import org.graalvm.compiler.core.common.type.FloatStamp; import org.graalvm.compiler.core.common.type.Stamp; import org.graalvm.compiler.debug.DebugCloseable; import org.graalvm.compiler.debug.GraalError; @@ -42,12 +41,8 @@ import org.graalvm.compiler.nodes.ShortCircuitOrNode; import org.graalvm.compiler.nodes.StructuredGraph; import org.graalvm.compiler.nodes.ValueNode; +import org.graalvm.compiler.nodes.calc.AbstractNormalizeCompareNode; import org.graalvm.compiler.nodes.calc.ConditionalNode; -import org.graalvm.compiler.nodes.calc.FloatEqualsNode; -import org.graalvm.compiler.nodes.calc.FloatLessThanNode; -import org.graalvm.compiler.nodes.calc.IntegerEqualsNode; -import org.graalvm.compiler.nodes.calc.IntegerLessThanNode; -import org.graalvm.compiler.nodes.calc.NormalizeCompareNode; import org.graalvm.compiler.phases.Phase; public class ExpandLogicPhase extends Phase { @@ -61,7 +56,7 @@ } assert graph.getNodes(ShortCircuitOrNode.TYPE).isEmpty(); - for (NormalizeCompareNode logic : graph.getNodes(NormalizeCompareNode.TYPE)) { + for (AbstractNormalizeCompareNode logic : graph.getNodes(AbstractNormalizeCompareNode.TYPE)) { try (DebugCloseable context = logic.withNodeSourcePosition()) { processNormalizeCompareNode(logic); } @@ -69,23 +64,12 @@ graph.setAfterExpandLogic(); } - private static void processNormalizeCompareNode(NormalizeCompareNode normalize) { - LogicNode equalComp; - LogicNode lessComp; + private static void processNormalizeCompareNode(AbstractNormalizeCompareNode normalize) { StructuredGraph graph = normalize.graph(); - ValueNode x = normalize.getX(); - ValueNode y = normalize.getY(); - if (x.stamp(NodeView.DEFAULT) instanceof FloatStamp) { - equalComp = graph.addOrUniqueWithInputs(FloatEqualsNode.create(x, y, NodeView.DEFAULT)); - lessComp = graph.addOrUniqueWithInputs(FloatLessThanNode.create(x, y, normalize.isUnorderedLess(), NodeView.DEFAULT)); - } else { - equalComp = graph.addOrUniqueWithInputs(IntegerEqualsNode.create(x, y, NodeView.DEFAULT)); - lessComp = graph.addOrUniqueWithInputs(IntegerLessThanNode.create(x, y, NodeView.DEFAULT)); - } - + LogicNode equalComp = graph.addOrUniqueWithInputs(normalize.createEqualComparison()); + LogicNode lessComp = graph.addOrUniqueWithInputs(normalize.createLowerComparison()); Stamp stamp = normalize.stamp(NodeView.DEFAULT); - ConditionalNode equalValue = graph.unique( - new ConditionalNode(equalComp, ConstantNode.forIntegerStamp(stamp, 0, graph), ConstantNode.forIntegerStamp(stamp, 1, graph))); + ConditionalNode equalValue = graph.unique(new ConditionalNode(equalComp, ConstantNode.forIntegerStamp(stamp, 0, graph), ConstantNode.forIntegerStamp(stamp, 1, graph))); ConditionalNode value = graph.unique(new ConditionalNode(lessComp, ConstantNode.forIntegerStamp(stamp, -1, graph), equalValue)); normalize.replaceAtUsagesAndDelete(value); } diff -r e47423f1318b -r ca19b94eac7a src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.phases.common/src/org/graalvm/compiler/phases/common/FixReadsPhase.java --- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.phases.common/src/org/graalvm/compiler/phases/common/FixReadsPhase.java Mon Sep 23 09:16:05 2019 -0700 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.phases.common/src/org/graalvm/compiler/phases/common/FixReadsPhase.java Wed Sep 25 22:40:41 2019 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2019, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -25,6 +25,7 @@ package org.graalvm.compiler.phases.common; import jdk.internal.vm.compiler.collections.EconomicMap; +import jdk.internal.vm.compiler.collections.Equivalence; import jdk.internal.vm.compiler.collections.MapCursor; import org.graalvm.compiler.core.common.GraalOptions; import org.graalvm.compiler.core.common.cfg.BlockMap; @@ -209,7 +210,7 @@ this.schedule = schedule; this.metaAccess = metaAccess; blockActionStart = new BlockMap<>(schedule.getCFG()); - endMaps = EconomicMap.create(); + endMaps = EconomicMap.create(Equivalence.IDENTITY); stampMap = graph.createNodeMap(); undoOperations = new NodeStack(); replaceConstantInputs = replaceInputsWithConstants && GraalOptions.ReplaceInputsWithConstantsBasedOnStamps.getValue(graph.getOptions()); @@ -310,7 +311,7 @@ if (currentEndMap == null || !currentEndMap.isEmpty()) { - EconomicMap endMap = EconomicMap.create(); + EconomicMap endMap = EconomicMap.create(Equivalence.IDENTITY); // Process phis for (ValuePhiNode phi : merge.valuePhis()) { diff -r e47423f1318b -r ca19b94eac7a src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.phases.common/src/org/graalvm/compiler/phases/common/FrameStateAssignmentPhase.java --- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.phases.common/src/org/graalvm/compiler/phases/common/FrameStateAssignmentPhase.java Mon Sep 23 09:16:05 2019 -0700 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.phases.common/src/org/graalvm/compiler/phases/common/FrameStateAssignmentPhase.java Wed Sep 25 22:40:41 2019 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2019, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -86,7 +86,7 @@ if (node instanceof DeoptimizingNode.DeoptDuring) { DeoptimizingNode.DeoptDuring deopt = (DeoptimizingNode.DeoptDuring) node; - if (deopt.canDeoptimize()) { + if (deopt.canDeoptimize() && deopt.stateDuring() == null) { GraalError.guarantee(currentState != null, "no FrameState at DeoptimizingNode %s", deopt); deopt.computeStateDuring(currentState); } diff -r e47423f1318b -r ca19b94eac7a src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.phases.common/src/org/graalvm/compiler/phases/common/IncrementalCanonicalizerPhase.java --- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.phases.common/src/org/graalvm/compiler/phases/common/IncrementalCanonicalizerPhase.java Mon Sep 23 09:16:05 2019 -0700 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.phases.common/src/org/graalvm/compiler/phases/common/IncrementalCanonicalizerPhase.java Wed Sep 25 22:40:41 2019 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2019, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it diff -r e47423f1318b -r ca19b94eac7a src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.phases.common/src/org/graalvm/compiler/phases/common/LoweringPhase.java --- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.phases.common/src/org/graalvm/compiler/phases/common/LoweringPhase.java Mon Sep 23 09:16:05 2019 -0700 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.phases.common/src/org/graalvm/compiler/phases/common/LoweringPhase.java Wed Sep 25 22:40:41 2019 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 2019, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it diff -r e47423f1318b -r ca19b94eac7a src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.phases.common/src/org/graalvm/compiler/phases/common/NodeCounterPhase.java --- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.phases.common/src/org/graalvm/compiler/phases/common/NodeCounterPhase.java Mon Sep 23 09:16:05 2019 -0700 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.phases.common/src/org/graalvm/compiler/phases/common/NodeCounterPhase.java Wed Sep 25 22:40:41 2019 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2019, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it diff -r e47423f1318b -r ca19b94eac7a src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.phases.common/src/org/graalvm/compiler/phases/common/OptimizeDivPhase.java --- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.phases.common/src/org/graalvm/compiler/phases/common/OptimizeDivPhase.java Mon Sep 23 09:16:05 2019 -0700 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.phases.common/src/org/graalvm/compiler/phases/common/OptimizeDivPhase.java Wed Sep 25 22:40:41 2019 +0200 @@ -49,12 +49,12 @@ @Override protected void run(StructuredGraph graph) { - for (IntegerDivRemNode rem : graph.getNodes().filter(IntegerDivRemNode.class)) { + for (IntegerDivRemNode rem : graph.getNodes(IntegerDivRemNode.TYPE)) { if (rem instanceof SignedRemNode && divByNonZeroConstant(rem)) { optimizeRem(rem); } } - for (IntegerDivRemNode div : graph.getNodes().filter(IntegerDivRemNode.class)) { + for (IntegerDivRemNode div : graph.getNodes(IntegerDivRemNode.TYPE)) { if (div instanceof SignedDivNode && divByNonZeroConstant(div)) { optimizeSignedDiv((SignedDivNode) div); } diff -r e47423f1318b -r ca19b94eac7a src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.phases.common/src/org/graalvm/compiler/phases/common/PropagateDeoptimizeProbabilityPhase.java --- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.phases.common/src/org/graalvm/compiler/phases/common/PropagateDeoptimizeProbabilityPhase.java Mon Sep 23 09:16:05 2019 -0700 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.phases.common/src/org/graalvm/compiler/phases/common/PropagateDeoptimizeProbabilityPhase.java Wed Sep 25 22:40:41 2019 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2019, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -26,6 +26,7 @@ import jdk.internal.vm.compiler.collections.EconomicMap; import jdk.internal.vm.compiler.collections.EconomicSet; +import jdk.internal.vm.compiler.collections.Equivalence; import jdk.internal.vm.compiler.collections.MapCursor; import org.graalvm.compiler.graph.NodeStack; import org.graalvm.compiler.nodes.AbstractBeginNode; @@ -52,7 +53,7 @@ if (graph.hasNode(AbstractDeoptimizeNode.TYPE)) { NodeStack stack = new NodeStack(); - EconomicMap> reachableSplits = EconomicMap.create(); + EconomicMap> reachableSplits = EconomicMap.create(Equivalence.IDENTITY); // Mark all control flow nodes that are post-dominated by a deoptimization. for (AbstractDeoptimizeNode d : graph.getNodes(AbstractDeoptimizeNode.TYPE)) { diff -r e47423f1318b -r ca19b94eac7a src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.phases.common/src/org/graalvm/compiler/phases/common/RemoveValueProxyPhase.java --- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.phases.common/src/org/graalvm/compiler/phases/common/RemoveValueProxyPhase.java Mon Sep 23 09:16:05 2019 -0700 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.phases.common/src/org/graalvm/compiler/phases/common/RemoveValueProxyPhase.java Wed Sep 25 22:40:41 2019 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2019, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it diff -r e47423f1318b -r ca19b94eac7a src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.phases.common/src/org/graalvm/compiler/phases/common/UseTrappingNullChecksPhase.java --- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.phases.common/src/org/graalvm/compiler/phases/common/UseTrappingNullChecksPhase.java Mon Sep 23 09:16:05 2019 -0700 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.phases.common/src/org/graalvm/compiler/phases/common/UseTrappingNullChecksPhase.java Wed Sep 25 22:40:41 2019 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 2019, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -45,6 +45,7 @@ import org.graalvm.compiler.nodes.FixedNode; import org.graalvm.compiler.nodes.IfNode; import org.graalvm.compiler.nodes.LogicNode; +import org.graalvm.compiler.nodes.LoopExitNode; import org.graalvm.compiler.nodes.StructuredGraph; import org.graalvm.compiler.nodes.ValueNode; import org.graalvm.compiler.nodes.ValuePhiNode; @@ -165,7 +166,8 @@ private static void tryUseTrappingNullCheck(AbstractDeoptimizeNode deopt, Node predecessor, DeoptimizationReason deoptimizationReason, Speculation speculation, long implicitNullCheckLimit) { assert predecessor != null; - if (deoptimizationReason != DeoptimizationReason.NullCheckException && deoptimizationReason != DeoptimizationReason.UnreachedCode) { + if (deoptimizationReason != DeoptimizationReason.NullCheckException && deoptimizationReason != DeoptimizationReason.UnreachedCode && + deoptimizationReason != DeoptimizationReason.TypeCheckedInliningViolated) { deopt.getDebug().log(DebugContext.INFO_LEVEL, "Not a null check or unreached %s", predecessor); return; } @@ -174,17 +176,23 @@ deopt.getDebug().log(DebugContext.INFO_LEVEL, "Has a speculation %s", predecessor); return; } - if (predecessor instanceof AbstractMergeNode) { - AbstractMergeNode merge = (AbstractMergeNode) predecessor; + + // Skip over loop exit nodes. + Node pred = predecessor; + while (pred instanceof LoopExitNode) { + pred = pred.predecessor(); + } + if (pred instanceof AbstractMergeNode) { + AbstractMergeNode merge = (AbstractMergeNode) pred; if (merge.phis().isEmpty()) { for (AbstractEndNode end : merge.cfgPredecessors().snapshot()) { checkPredecessor(deopt, end.predecessor(), deoptimizationReason, implicitNullCheckLimit); } } - } else if (predecessor instanceof AbstractBeginNode) { - checkPredecessor(deopt, predecessor, deoptimizationReason, implicitNullCheckLimit); + } else if (pred instanceof AbstractBeginNode) { + checkPredecessor(deopt, pred, deoptimizationReason, implicitNullCheckLimit); } else { - deopt.getDebug().log(DebugContext.INFO_LEVEL, "Not a Begin or Merge %s", predecessor); + deopt.getDebug().log(DebugContext.INFO_LEVEL, "Not a Begin or Merge %s", pred); } } diff -r e47423f1318b -r ca19b94eac7a src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.phases.common/src/org/graalvm/compiler/phases/common/inlining/InliningUtil.java --- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.phases.common/src/org/graalvm/compiler/phases/common/inlining/InliningUtil.java Mon Sep 23 09:16:05 2019 -0700 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.phases.common/src/org/graalvm/compiler/phases/common/inlining/InliningUtil.java Wed Sep 25 22:40:41 2019 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2019, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -728,7 +728,7 @@ FrameState stateAtReturn = invoke.stateAfter(); FrameState outerFrameState = null; JavaKind invokeReturnKind = invoke.asNode().getStackKind(); - EconomicMap replacements = EconomicMap.create(); + EconomicMap replacements = EconomicMap.create(Equivalence.IDENTITY); for (FrameState original : inlineGraph.getNodes(FrameState.TYPE)) { FrameState frameState = (FrameState) duplicates.get(original); if (frameState != null && frameState.isAlive()) { diff -r e47423f1318b -r ca19b94eac7a src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.phases.common/src/org/graalvm/compiler/phases/common/inlining/info/elem/InlineableGraph.java --- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.phases.common/src/org/graalvm/compiler/phases/common/inlining/info/elem/InlineableGraph.java Mon Sep 23 09:16:05 2019 -0700 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.phases.common/src/org/graalvm/compiler/phases/common/inlining/info/elem/InlineableGraph.java Wed Sep 25 22:40:41 2019 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2019, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it diff -r e47423f1318b -r ca19b94eac7a src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.phases.common/src/org/graalvm/compiler/phases/common/inlining/policy/AbstractInliningPolicy.java --- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.phases.common/src/org/graalvm/compiler/phases/common/inlining/policy/AbstractInliningPolicy.java Mon Sep 23 09:16:05 2019 -0700 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.phases.common/src/org/graalvm/compiler/phases/common/inlining/policy/AbstractInliningPolicy.java Wed Sep 25 22:40:41 2019 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 2019, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it diff -r e47423f1318b -r ca19b94eac7a src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.phases.common/src/org/graalvm/compiler/phases/common/inlining/policy/GreedyInliningPolicy.java --- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.phases.common/src/org/graalvm/compiler/phases/common/inlining/policy/GreedyInliningPolicy.java Mon Sep 23 09:16:05 2019 -0700 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.phases.common/src/org/graalvm/compiler/phases/common/inlining/policy/GreedyInliningPolicy.java Wed Sep 25 22:40:41 2019 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 2019, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it diff -r e47423f1318b -r ca19b94eac7a src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.phases.common/src/org/graalvm/compiler/phases/common/inlining/policy/InlineEverythingPolicy.java --- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.phases.common/src/org/graalvm/compiler/phases/common/inlining/policy/InlineEverythingPolicy.java Mon Sep 23 09:16:05 2019 -0700 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.phases.common/src/org/graalvm/compiler/phases/common/inlining/policy/InlineEverythingPolicy.java Wed Sep 25 22:40:41 2019 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 2019, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it diff -r e47423f1318b -r ca19b94eac7a src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.phases.common/src/org/graalvm/compiler/phases/common/inlining/policy/InlineMethodSubstitutionsPolicy.java --- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.phases.common/src/org/graalvm/compiler/phases/common/inlining/policy/InlineMethodSubstitutionsPolicy.java Mon Sep 23 09:16:05 2019 -0700 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.phases.common/src/org/graalvm/compiler/phases/common/inlining/policy/InlineMethodSubstitutionsPolicy.java Wed Sep 25 22:40:41 2019 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2019, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it diff -r e47423f1318b -r ca19b94eac7a src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.phases.common/src/org/graalvm/compiler/phases/common/inlining/policy/InliningPolicy.java --- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.phases.common/src/org/graalvm/compiler/phases/common/inlining/policy/InliningPolicy.java Mon Sep 23 09:16:05 2019 -0700 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.phases.common/src/org/graalvm/compiler/phases/common/inlining/policy/InliningPolicy.java Wed Sep 25 22:40:41 2019 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 2019, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it diff -r e47423f1318b -r ca19b94eac7a src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.phases.common/src/org/graalvm/compiler/phases/common/util/EconomicSetNodeEventListener.java --- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.phases.common/src/org/graalvm/compiler/phases/common/util/EconomicSetNodeEventListener.java Mon Sep 23 09:16:05 2019 -0700 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.phases.common/src/org/graalvm/compiler/phases/common/util/EconomicSetNodeEventListener.java Wed Sep 25 22:40:41 2019 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2019, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it diff -r e47423f1318b -r ca19b94eac7a src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.phases/src/org/graalvm/compiler/phases/PhaseSuite.java --- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.phases/src/org/graalvm/compiler/phases/PhaseSuite.java Mon Sep 23 09:16:05 2019 -0700 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.phases/src/org/graalvm/compiler/phases/PhaseSuite.java Wed Sep 25 22:40:41 2019 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2019, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it diff -r e47423f1318b -r ca19b94eac7a src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.phases/src/org/graalvm/compiler/phases/VerifyPhase.java --- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.phases/src/org/graalvm/compiler/phases/VerifyPhase.java Mon Sep 23 09:16:05 2019 -0700 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.phases/src/org/graalvm/compiler/phases/VerifyPhase.java Wed Sep 25 22:40:41 2019 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2019, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it diff -r e47423f1318b -r ca19b94eac7a src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.phases/src/org/graalvm/compiler/phases/graph/ReentrantBlockIterator.java --- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.phases/src/org/graalvm/compiler/phases/graph/ReentrantBlockIterator.java Mon Sep 23 09:16:05 2019 -0700 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.phases/src/org/graalvm/compiler/phases/graph/ReentrantBlockIterator.java Wed Sep 25 22:40:41 2019 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 2019, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it diff -r e47423f1318b -r ca19b94eac7a src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.phases/src/org/graalvm/compiler/phases/tiers/HighTierContext.java --- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.phases/src/org/graalvm/compiler/phases/tiers/HighTierContext.java Mon Sep 23 09:16:05 2019 -0700 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.phases/src/org/graalvm/compiler/phases/tiers/HighTierContext.java Wed Sep 25 22:40:41 2019 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2019, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it diff -r e47423f1318b -r ca19b94eac7a src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.phases/src/org/graalvm/compiler/phases/tiers/LowTierContext.java --- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.phases/src/org/graalvm/compiler/phases/tiers/LowTierContext.java Mon Sep 23 09:16:05 2019 -0700 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.phases/src/org/graalvm/compiler/phases/tiers/LowTierContext.java Wed Sep 25 22:40:41 2019 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2019, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it diff -r e47423f1318b -r ca19b94eac7a src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.phases/src/org/graalvm/compiler/phases/tiers/MidTierContext.java --- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.phases/src/org/graalvm/compiler/phases/tiers/MidTierContext.java Mon Sep 23 09:16:05 2019 -0700 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.phases/src/org/graalvm/compiler/phases/tiers/MidTierContext.java Wed Sep 25 22:40:41 2019 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2019, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it diff -r e47423f1318b -r ca19b94eac7a src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.phases/src/org/graalvm/compiler/phases/util/GraphOrder.java --- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.phases/src/org/graalvm/compiler/phases/util/GraphOrder.java Mon Sep 23 09:16:05 2019 -0700 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.phases/src/org/graalvm/compiler/phases/util/GraphOrder.java Wed Sep 25 22:40:41 2019 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 2019, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -158,7 +158,7 @@ public static boolean assertSchedulableGraph(final StructuredGraph graph) { assert graph.getGuardsStage() != GuardsStage.AFTER_FSA : "Cannot use the BlockIteratorClosure after FrameState Assignment, HIR Loop Data Structures are no longer valid."; try (DebugContext.Scope s = graph.getDebug().scope("AssertSchedulableGraph")) { - final SchedulePhase schedulePhase = new SchedulePhase(SchedulingStrategy.LATEST_OUT_OF_LOOPS, true); + final SchedulePhase schedulePhase = new SchedulePhase(getSchedulingPolicy(graph), true); final EconomicMap loopEntryStates = EconomicMap.create(Equivalence.IDENTITY); schedulePhase.apply(graph, false); final ScheduleResult schedule = graph.getLastSchedule(); @@ -216,11 +216,11 @@ } } } - // loop contents are only accessible via proxies at the exit currentState.clearAll(); currentState.markAll(loopEntryStates.get(((LoopExitNode) node).loopBegin())); } + // Loop proxies aren't scheduled, so they need to be added // explicitly currentState.markAll(((LoopExitNode) node).proxies()); @@ -297,4 +297,14 @@ } return true; } + + /* + * Complexity of verification for LATEST_OUT_OF_LOOPS with value proxies exceeds the benefits. + * The problem are floating values that can be scheduled before the loop and have proxies only + * on some use edges after the loop. These values, which are hard to detect, get scheduled + * before the loop exit and are not visible in the state after the loop exit. + */ + private static SchedulingStrategy getSchedulingPolicy(StructuredGraph graph) { + return graph.hasValueProxies() ? SchedulingStrategy.EARLIEST : SchedulingStrategy.LATEST_OUT_OF_LOOPS; + } } diff -r e47423f1318b -r ca19b94eac7a src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.phases/src/org/graalvm/compiler/phases/util/Providers.java --- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.phases/src/org/graalvm/compiler/phases/util/Providers.java Mon Sep 23 09:16:05 2019 -0700 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.phases/src/org/graalvm/compiler/phases/util/Providers.java Wed Sep 25 22:40:41 2019 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2019, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it diff -r e47423f1318b -r ca19b94eac7a src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.printer/src/org/graalvm/compiler/printer/BinaryGraphPrinter.java --- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.printer/src/org/graalvm/compiler/printer/BinaryGraphPrinter.java Mon Sep 23 09:16:05 2019 -0700 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.printer/src/org/graalvm/compiler/printer/BinaryGraphPrinter.java Wed Sep 25 22:40:41 2019 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 2019, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it diff -r e47423f1318b -r ca19b94eac7a src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.printer/src/org/graalvm/compiler/printer/CFGPrinterObserver.java --- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.printer/src/org/graalvm/compiler/printer/CFGPrinterObserver.java Mon Sep 23 09:16:05 2019 -0700 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.printer/src/org/graalvm/compiler/printer/CFGPrinterObserver.java Wed Sep 25 22:40:41 2019 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 2019, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it diff -r e47423f1318b -r ca19b94eac7a src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.printer/src/org/graalvm/compiler/printer/GraalDebugHandlersFactory.java --- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.printer/src/org/graalvm/compiler/printer/GraalDebugHandlersFactory.java Mon Sep 23 09:16:05 2019 -0700 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.printer/src/org/graalvm/compiler/printer/GraalDebugHandlersFactory.java Wed Sep 25 22:40:41 2019 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2019, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it diff -r e47423f1318b -r ca19b94eac7a src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.printer/src/org/graalvm/compiler/printer/GraphPrinter.java --- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.printer/src/org/graalvm/compiler/printer/GraphPrinter.java Mon Sep 23 09:16:05 2019 -0700 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.printer/src/org/graalvm/compiler/printer/GraphPrinter.java Wed Sep 25 22:40:41 2019 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2019, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -28,8 +28,11 @@ import java.io.IOException; import java.lang.reflect.Array; import java.util.Arrays; +import java.util.Collections; +import java.util.IdentityHashMap; import java.util.List; import java.util.Map; +import java.util.Set; import org.graalvm.compiler.api.replacements.SnippetReflectionProvider; import org.graalvm.compiler.debug.DebugContext; @@ -106,7 +109,7 @@ /** * Use the real {@link Object#toString()} method for {@link JavaConstant JavaConstants} that are - * wrapping trusted types, other just return the results of {@link JavaConstant#toString()}. + * wrapping trusted types, otherwise just return the result of {@link JavaConstant#toString()}. */ @Override default String format(JavaConstant constant) { @@ -122,7 +125,8 @@ } catch (Throwable ex) { } if (obj != null) { - return GraphPrinter.constantToString(obj); + Set visited = Collections.newSetFromMap(new IdentityHashMap<>()); + return GraphPrinter.constantToString(obj, visited); } } } @@ -180,49 +184,61 @@ return s; } - static String constantToString(Object value) { - Class c = value.getClass(); - String suffix = ""; - if (c.isArray()) { - return constantArrayToString(value); - } else if (value instanceof Enum) { - return ((Enum) value).name(); - } else if (isToStringTrusted(c)) { - try { - return value.toString(); - } catch (Throwable t) { - suffix = "[toString error: " + t.getClass().getName() + "]"; - if (isToStringTrusted(t.getClass())) { - try { - suffix = "[toString error: " + t + "]"; - } catch (Throwable t2) { - // No point in going further + static String constantToString(Object value, Set visited) { + if (!visited.contains(value)) { + Class c = value.getClass(); + String suffix = ""; + if (c.isArray()) { + return constantArrayToString(value, visited); + } + visited.add(value); + if (value instanceof Enum) { + return ((Enum) value).name(); + } else if (isToStringTrusted(c)) { + try { + return value.toString(); + } catch (Throwable t) { + suffix = "[toString error: " + t.getClass().getName() + "]"; + if (isToStringTrusted(t.getClass())) { + try { + suffix = "[toString error: " + t + "]"; + } catch (Throwable t2) { + // No point in going further + } } } } + return MetaUtil.getSimpleName(c, true) + "@" + Integer.toHexString(System.identityHashCode(value)) + suffix; + } else { + return "..."; } - return MetaUtil.getSimpleName(c, true) + "@" + Integer.toHexString(System.identityHashCode(value)) + suffix; + } - static String constantArrayToString(Object array) { - Class componentType = array.getClass().getComponentType(); - assert componentType != null; - int arrayLength = Array.getLength(array); - StringBuilder buf = new StringBuilder(MetaUtil.getSimpleName(componentType, true)).append('[').append(arrayLength).append("]{"); - int length = arrayLength; - boolean primitive = componentType.isPrimitive(); - for (int i = 0; i < length; i++) { - if (primitive) { - buf.append(Array.get(array, i)); - } else { - Object o = ((Object[]) array)[i]; - buf.append(o == null ? "null" : constantToString(o)); + static String constantArrayToString(Object array, Set visited) { + if (!visited.contains(array)) { + visited.add(array); + Class componentType = array.getClass().getComponentType(); + assert componentType != null; + int arrayLength = Array.getLength(array); + StringBuilder buf = new StringBuilder(MetaUtil.getSimpleName(componentType, true)).append('[').append(arrayLength).append("]{"); + int length = arrayLength; + boolean primitive = componentType.isPrimitive(); + for (int i = 0; i < length; i++) { + if (primitive) { + buf.append(Array.get(array, i)); + } else { + Object o = ((Object[]) array)[i]; + buf.append(o == null ? "null" : constantToString(o, visited)); + } + if (i != length - 1) { + buf.append(", "); + } } - if (i != length - 1) { - buf.append(", "); - } + return buf.append('}').toString(); + } else { + return "..."; } - return buf.append('}').toString(); } @SuppressWarnings("try") diff -r e47423f1318b -r ca19b94eac7a src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.printer/src/org/graalvm/compiler/printer/GraphPrinterDumpHandler.java --- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.printer/src/org/graalvm/compiler/printer/GraphPrinterDumpHandler.java Mon Sep 23 09:16:05 2019 -0700 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.printer/src/org/graalvm/compiler/printer/GraphPrinterDumpHandler.java Wed Sep 25 22:40:41 2019 +0200 @@ -37,13 +37,14 @@ import java.util.Map; import java.util.WeakHashMap; +import org.graalvm.compiler.core.common.CompilationIdentifier; import org.graalvm.compiler.debug.DebugContext; import org.graalvm.compiler.debug.DebugDumpHandler; import org.graalvm.compiler.debug.DebugDumpScope; import org.graalvm.compiler.debug.DebugOptions; +import org.graalvm.compiler.debug.DebugOptions.PrintGraphTarget; import org.graalvm.compiler.debug.GraalError; import org.graalvm.compiler.debug.TTY; -import org.graalvm.compiler.debug.DebugOptions.PrintGraphTarget; import org.graalvm.compiler.graph.Graph; import org.graalvm.compiler.nodes.StructuredGraph; import org.graalvm.compiler.options.OptionValues; @@ -66,6 +67,7 @@ private final GraphPrinterSupplier printerSupplier; protected GraphPrinter printer; private List previousInlineContext; + private CompilationIdentifier previousCompilationID = CompilationIdentifier.INVALID_COMPILATION_ID; private int[] dumpIds = {}; private int failuresCount; private Map> inlineContextMap; @@ -136,6 +138,22 @@ // Get all current JavaMethod instances in the context. List inlineContext = getInlineContext(graph); + if (graph instanceof StructuredGraph) { + CompilationIdentifier compilationID = ((StructuredGraph) graph).compilationId(); + // If the graph to be dumped is with an invalid compilation id, it is likely derived + // from inlining. + if (compilationID != CompilationIdentifier.INVALID_COMPILATION_ID) { + if (previousCompilationID != CompilationIdentifier.INVALID_COMPILATION_ID && !compilationID.equals(previousCompilationID)) { + // Compilation ID does not match, close existing scopes. + for (int inlineDepth = previousInlineContext.size() - 1; inlineDepth >= 0; --inlineDepth) { + closeScope(debug, inlineDepth); + } + previousInlineContext = new ArrayList<>(); + } + previousCompilationID = compilationID; + } + } + if (!inlineContext.equals(previousInlineContext)) { Map properties = new HashMap<>(); properties.put("graph", graph.toString()); diff -r e47423f1318b -r ca19b94eac7a src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements.aarch64/src/org/graalvm/compiler/replacements/aarch64/AArch64GraphBuilderPlugins.java --- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements.aarch64/src/org/graalvm/compiler/replacements/aarch64/AArch64GraphBuilderPlugins.java Mon Sep 23 09:16:05 2019 -0700 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements.aarch64/src/org/graalvm/compiler/replacements/aarch64/AArch64GraphBuilderPlugins.java Wed Sep 25 22:40:41 2019 +0200 @@ -45,17 +45,24 @@ import org.graalvm.compiler.nodes.java.AtomicReadAndWriteNode; import org.graalvm.compiler.nodes.memory.address.AddressNode; import org.graalvm.compiler.nodes.memory.address.OffsetAddressNode; +import org.graalvm.compiler.replacements.TargetGraphBuilderPlugins; import org.graalvm.compiler.replacements.nodes.BinaryMathIntrinsicNode; import org.graalvm.compiler.replacements.nodes.UnaryMathIntrinsicNode; import org.graalvm.compiler.replacements.nodes.UnaryMathIntrinsicNode.UnaryOperation; import org.graalvm.compiler.serviceprovider.JavaVersionUtil; import jdk.internal.vm.compiler.word.LocationIdentity; +import jdk.vm.ci.code.Architecture; import jdk.vm.ci.meta.JavaKind; import jdk.vm.ci.meta.ResolvedJavaMethod; import sun.misc.Unsafe; -public class AArch64GraphBuilderPlugins { +public class AArch64GraphBuilderPlugins implements TargetGraphBuilderPlugins { + @Override + public void register(Plugins plugins, BytecodeProvider replacementsBytecodeProvider, Architecture arch, boolean explicitUnsafeNullChecks, boolean registerMathPlugins, + boolean emitJDK9StringSubstitutions, boolean useFMAIntrinsics) { + register(plugins, replacementsBytecodeProvider, explicitUnsafeNullChecks, registerMathPlugins, emitJDK9StringSubstitutions); + } public static void register(Plugins plugins, BytecodeProvider bytecodeProvider, boolean explicitUnsafeNullChecks, boolean registerMathPlugins) { diff -r e47423f1318b -r ca19b94eac7a src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements.aarch64/src/org/graalvm/compiler/replacements/aarch64/AArch64IntegerArithmeticSnippets.java --- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements.aarch64/src/org/graalvm/compiler/replacements/aarch64/AArch64IntegerArithmeticSnippets.java Mon Sep 23 09:16:05 2019 -0700 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements.aarch64/src/org/graalvm/compiler/replacements/aarch64/AArch64IntegerArithmeticSnippets.java Wed Sep 25 22:40:41 2019 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 2019, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2018, Red Hat Inc. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -44,6 +44,7 @@ import org.graalvm.compiler.nodes.calc.SignedRemNode; import org.graalvm.compiler.nodes.calc.UnsignedDivNode; import org.graalvm.compiler.nodes.calc.UnsignedRemNode; +import org.graalvm.compiler.nodes.extended.BranchProbabilityNode; import org.graalvm.compiler.nodes.spi.LoweringTool; import org.graalvm.compiler.nodes.spi.NodeLIRBuilderTool; import org.graalvm.compiler.options.OptionValues; @@ -183,14 +184,14 @@ } private static void checkForZero(int y) { - if (y == 0) { + if (BranchProbabilityNode.probability(BranchProbabilityNode.DEOPT_PROBABILITY, y == 0)) { // "/ by zero" DeoptimizeNode.deopt(DeoptimizationAction.InvalidateReprofile, DeoptimizationReason.ArithmeticException); } } private static void checkForZero(long y) { - if (y == 0) { + if (BranchProbabilityNode.probability(BranchProbabilityNode.DEOPT_PROBABILITY, y == 0)) { // "/ by zero" DeoptimizeNode.deopt(DeoptimizationAction.InvalidateReprofile, DeoptimizationReason.ArithmeticException); } diff -r e47423f1318b -r ca19b94eac7a src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements.amd64/src/org/graalvm/compiler/replacements/amd64/AMD64ArrayIndexOf.java --- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements.amd64/src/org/graalvm/compiler/replacements/amd64/AMD64ArrayIndexOf.java Mon Sep 23 09:16:05 2019 -0700 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements.amd64/src/org/graalvm/compiler/replacements/amd64/AMD64ArrayIndexOf.java Wed Sep 25 22:40:41 2019 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2019, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it diff -r e47423f1318b -r ca19b94eac7a src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements.amd64/src/org/graalvm/compiler/replacements/amd64/AMD64ArrayIndexOfNode.java --- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements.amd64/src/org/graalvm/compiler/replacements/amd64/AMD64ArrayIndexOfNode.java Mon Sep 23 09:16:05 2019 -0700 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements.amd64/src/org/graalvm/compiler/replacements/amd64/AMD64ArrayIndexOfNode.java Wed Sep 25 22:40:41 2019 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2019, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it diff -r e47423f1318b -r ca19b94eac7a src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements.amd64/src/org/graalvm/compiler/replacements/amd64/AMD64GraphBuilderPlugins.java --- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements.amd64/src/org/graalvm/compiler/replacements/amd64/AMD64GraphBuilderPlugins.java Mon Sep 23 09:16:05 2019 -0700 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements.amd64/src/org/graalvm/compiler/replacements/amd64/AMD64GraphBuilderPlugins.java Wed Sep 25 22:40:41 2019 +0200 @@ -54,6 +54,7 @@ import org.graalvm.compiler.replacements.StandardGraphBuilderPlugins.UnsafeAccessPlugin; import org.graalvm.compiler.replacements.StandardGraphBuilderPlugins.UnsafeGetPlugin; import org.graalvm.compiler.replacements.StandardGraphBuilderPlugins.UnsafePutPlugin; +import org.graalvm.compiler.replacements.TargetGraphBuilderPlugins; import org.graalvm.compiler.replacements.nodes.BinaryMathIntrinsicNode; import org.graalvm.compiler.replacements.nodes.BinaryMathIntrinsicNode.BinaryOperation; import org.graalvm.compiler.replacements.nodes.BitCountNode; @@ -64,11 +65,17 @@ import jdk.vm.ci.amd64.AMD64; import jdk.vm.ci.amd64.AMD64.CPUFeature; +import jdk.vm.ci.code.Architecture; import jdk.vm.ci.meta.JavaKind; import jdk.vm.ci.meta.ResolvedJavaMethod; import sun.misc.Unsafe; -public class AMD64GraphBuilderPlugins { +public class AMD64GraphBuilderPlugins implements TargetGraphBuilderPlugins { + @Override + public void register(Plugins plugins, BytecodeProvider replacementsBytecodeProvider, Architecture architecture, boolean explicitUnsafeNullChecks, + boolean registerMathPlugins, boolean emitJDK9StringSubstitutions, boolean useFMAIntrinsics) { + register(plugins, replacementsBytecodeProvider, (AMD64) architecture, explicitUnsafeNullChecks, emitJDK9StringSubstitutions, useFMAIntrinsics); + } public static void register(Plugins plugins, BytecodeProvider replacementsBytecodeProvider, AMD64 arch, boolean explicitUnsafeNullChecks, boolean emitJDK9StringSubstitutions, boolean useFMAIntrinsics) { diff -r e47423f1318b -r ca19b94eac7a src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements.amd64/src/org/graalvm/compiler/replacements/amd64/AMD64StringLatin1Substitutions.java --- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements.amd64/src/org/graalvm/compiler/replacements/amd64/AMD64StringLatin1Substitutions.java Mon Sep 23 09:16:05 2019 -0700 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements.amd64/src/org/graalvm/compiler/replacements/amd64/AMD64StringLatin1Substitutions.java Wed Sep 25 22:40:41 2019 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2019, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -134,8 +134,6 @@ } if (targetCount == 1) { return AMD64ArrayIndexOf.indexOf1Byte(source, sourceCount, fromIndex, target[0]); - } else if (targetCount == 2) { - return AMD64ArrayIndexOf.indexOfTwoConsecutiveBytes(source, sourceCount, fromIndex, target[0], target[1]); } else { int haystackLength = sourceCount - (targetCount - 2); int offset = fromIndex; @@ -147,7 +145,7 @@ offset = indexOfResult; Pointer cmpSourcePointer = byteOffsetPointer(source, offset); Pointer targetPointer = pointer(target); - if (ArrayRegionEqualsNode.regionEquals(cmpSourcePointer, targetPointer, targetCount, JavaKind.Byte)) { + if (targetCount == 2 || ArrayRegionEqualsNode.regionEquals(cmpSourcePointer, targetPointer, targetCount, JavaKind.Byte)) { return offset; } offset++; diff -r e47423f1318b -r ca19b94eac7a src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements.amd64/src/org/graalvm/compiler/replacements/amd64/AMD64StringSubstitutions.java --- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements.amd64/src/org/graalvm/compiler/replacements/amd64/AMD64StringSubstitutions.java Mon Sep 23 09:16:05 2019 -0700 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements.amd64/src/org/graalvm/compiler/replacements/amd64/AMD64StringSubstitutions.java Wed Sep 25 22:40:41 2019 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2019, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -85,8 +85,6 @@ if (targetCount == 1) { return AMD64ArrayIndexOf.indexOf1Char(source, sourceCount, totalOffset, target[targetOffset]); - } else if (targetCount == 2) { - return AMD64ArrayIndexOf.indexOfTwoConsecutiveChars(source, sourceCount, totalOffset, target[targetOffset], target[targetOffset + 1]); } else { int haystackLength = sourceCount - (targetCount - 2); while (totalOffset < haystackLength) { @@ -95,10 +93,14 @@ return -1; } totalOffset = indexOfResult; - Pointer cmpSourcePointer = Word.objectToTrackedPointer(source).add(charArrayBaseOffset(INJECTED)).add(totalOffset * charArrayIndexScale(INJECTED)); - Pointer targetPointer = Word.objectToTrackedPointer(target).add(charArrayBaseOffset(INJECTED)).add(targetOffset * charArrayIndexScale(INJECTED)); - if (ArrayRegionEqualsNode.regionEquals(cmpSourcePointer, targetPointer, targetCount, JavaKind.Char)) { + if (targetCount == 2) { return totalOffset; + } else { + Pointer cmpSourcePointer = Word.objectToTrackedPointer(source).add(charArrayBaseOffset(INJECTED)).add(totalOffset * charArrayIndexScale(INJECTED)); + Pointer targetPointer = Word.objectToTrackedPointer(target).add(charArrayBaseOffset(INJECTED)).add(targetOffset * charArrayIndexScale(INJECTED)); + if (ArrayRegionEqualsNode.regionEquals(cmpSourcePointer, targetPointer, targetCount, JavaKind.Char)) { + return totalOffset; + } } totalOffset++; } diff -r e47423f1318b -r ca19b94eac7a src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements.amd64/src/org/graalvm/compiler/replacements/amd64/AMD64StringUTF16Substitutions.java --- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements.amd64/src/org/graalvm/compiler/replacements/amd64/AMD64StringUTF16Substitutions.java Mon Sep 23 09:16:05 2019 -0700 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements.amd64/src/org/graalvm/compiler/replacements/amd64/AMD64StringUTF16Substitutions.java Wed Sep 25 22:40:41 2019 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2019, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -122,8 +122,6 @@ ReplacementsUtil.runtimeAssert(sourceCount >= targetCount, "StringUTF16.indexOfUnsafe invalid args: sourceCount < targetCount"); if (targetCount == 1) { return AMD64ArrayIndexOf.indexOf1Char(source, sourceCount, fromIndex, StringUTF16Substitutions.getChar(target, 0)); - } else if (targetCount == 2) { - return AMD64ArrayIndexOf.indexOfTwoConsecutiveChars(source, sourceCount, fromIndex, StringUTF16Substitutions.getChar(target, 0), StringUTF16Substitutions.getChar(target, 1)); } else { int haystackLength = sourceCount - (targetCount - 2); int offset = fromIndex; @@ -136,7 +134,7 @@ offset = indexOfResult; Pointer cmpSourcePointer = charOffsetPointer(source, offset); Pointer targetPointer = pointer(target); - if (ArrayRegionEqualsNode.regionEquals(cmpSourcePointer, targetPointer, targetCount, JavaKind.Char)) { + if (targetCount == 2 || ArrayRegionEqualsNode.regionEquals(cmpSourcePointer, targetPointer, targetCount, JavaKind.Char)) { return offset; } offset++; @@ -153,8 +151,6 @@ ReplacementsUtil.runtimeAssert(sourceCount >= targetCount, "StringUTF16.indexOfLatin1Unsafe invalid args: sourceCount < targetCount"); if (targetCount == 1) { return AMD64ArrayIndexOf.indexOf1Char(source, sourceCount, fromIndex, (char) Byte.toUnsignedInt(target[0])); - } else if (targetCount == 2) { - return AMD64ArrayIndexOf.indexOfTwoConsecutiveChars(source, sourceCount, fromIndex, (char) Byte.toUnsignedInt(target[0]), (char) Byte.toUnsignedInt(target[1])); } else { int haystackLength = sourceCount - (targetCount - 2); int offset = fromIndex; @@ -166,7 +162,7 @@ offset = indexOfResult; Pointer cmpSourcePointer = charOffsetPointer(source, offset); Pointer targetPointer = pointer(target); - if (ArrayRegionEqualsNode.regionEquals(cmpSourcePointer, targetPointer, targetCount, JavaKind.Char, JavaKind.Byte)) { + if (targetCount == 2 || ArrayRegionEqualsNode.regionEquals(cmpSourcePointer, targetPointer, targetCount, JavaKind.Char, JavaKind.Byte)) { return offset; } offset++; @@ -185,9 +181,7 @@ */ @MethodSubstitution public static int compress(char[] src, int srcIndex, byte[] dest, int destIndex, int len) { - if (len < 0 || srcIndex < 0 || (srcIndex + len > src.length) || destIndex < 0 || (destIndex + len > dest.length)) { - DeoptimizeNode.deopt(DeoptimizationAction.None, DeoptimizationReason.BoundsCheckException); - } + checkLimits(src.length, srcIndex, dest.length, destIndex, len); Pointer srcPointer = Word.objectToTrackedPointer(src).add(charArrayBaseOffset(INJECTED)).add(srcIndex * charArrayIndexScale(INJECTED)); Pointer destPointer = Word.objectToTrackedPointer(dest).add(byteArrayBaseOffset(INJECTED)).add(destIndex * byteArrayIndexScale(INJECTED)); @@ -208,13 +202,17 @@ */ @MethodSubstitution public static int compress(byte[] src, int srcIndex, byte[] dest, int destIndex, int len) { - if (len < 0 || srcIndex < 0 || (srcIndex * 2 + len * 2 > src.length) || destIndex < 0 || (destIndex + len > dest.length)) { - DeoptimizeNode.deopt(DeoptimizationAction.None, DeoptimizationReason.BoundsCheckException); - } + checkLimits(src.length >> 1, srcIndex, dest.length, destIndex, len); Pointer srcPointer = Word.objectToTrackedPointer(src).add(byteArrayBaseOffset(INJECTED)).add(srcIndex * 2 * byteArrayIndexScale(INJECTED)); Pointer destPointer = Word.objectToTrackedPointer(dest).add(byteArrayBaseOffset(INJECTED)).add(destIndex * byteArrayIndexScale(INJECTED)); return AMD64StringUTF16CompressNode.compress(srcPointer, destPointer, len, JavaKind.Byte); } + private static void checkLimits(int srcLen, int srcIndex, int destLen, int destIndex, int len) { + if (len < 0 || srcIndex < 0 || (srcIndex + len > srcLen) || destIndex < 0 || (destIndex + len > destLen)) { + DeoptimizeNode.deopt(DeoptimizationAction.None, DeoptimizationReason.BoundsCheckException); + } + } + } diff -r e47423f1318b -r ca19b94eac7a src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements.processor/src/org/graalvm/compiler/replacements/processor/GeneratedFoldPlugin.java --- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements.processor/src/org/graalvm/compiler/replacements/processor/GeneratedFoldPlugin.java Mon Sep 23 09:16:05 2019 -0700 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements.processor/src/org/graalvm/compiler/replacements/processor/GeneratedFoldPlugin.java Wed Sep 25 22:40:41 2019 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2019, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it diff -r e47423f1318b -r ca19b94eac7a src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements.processor/src/org/graalvm/compiler/replacements/processor/GeneratedPlugin.java --- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements.processor/src/org/graalvm/compiler/replacements/processor/GeneratedPlugin.java Mon Sep 23 09:16:05 2019 -0700 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements.processor/src/org/graalvm/compiler/replacements/processor/GeneratedPlugin.java Wed Sep 25 22:40:41 2019 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2019, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -73,6 +73,9 @@ out.printf("\n"); out.printf(" @Override\n"); out.printf(" public boolean execute(GraphBuilderContext b, ResolvedJavaMethod targetMethod, InvocationPlugin.Receiver receiver, ValueNode[] args) {\n"); + out.printf(" if (!b.isPluginEnabled(this)) {\n"); + out.printf(" return false;\n"); + out.printf(" }\n"); InjectedDependencies deps = createExecute(processor, out); out.printf(" }\n"); out.printf(" @Override\n"); diff -r e47423f1318b -r ca19b94eac7a src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements.test/src/org/graalvm/compiler/replacements/test/ArraysSubstitutionsTest.java --- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements.test/src/org/graalvm/compiler/replacements/test/ArraysSubstitutionsTest.java Mon Sep 23 09:16:05 2019 -0700 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements.test/src/org/graalvm/compiler/replacements/test/ArraysSubstitutionsTest.java Wed Sep 25 22:40:41 2019 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 2019, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it diff -r e47423f1318b -r ca19b94eac7a src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements.test/src/org/graalvm/compiler/replacements/test/DeoptimizeOnExceptionTest.java --- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements.test/src/org/graalvm/compiler/replacements/test/DeoptimizeOnExceptionTest.java Mon Sep 23 09:16:05 2019 -0700 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements.test/src/org/graalvm/compiler/replacements/test/DeoptimizeOnExceptionTest.java Wed Sep 25 22:40:41 2019 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 2019, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it diff -r e47423f1318b -r ca19b94eac7a src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements.test/src/org/graalvm/compiler/replacements/test/DeoptimizeOnIntegerExactTest.java --- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements.test/src/org/graalvm/compiler/replacements/test/DeoptimizeOnIntegerExactTest.java Mon Sep 23 09:16:05 2019 -0700 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements.test/src/org/graalvm/compiler/replacements/test/DeoptimizeOnIntegerExactTest.java Wed Sep 25 22:40:41 2019 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2019, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it diff -r e47423f1318b -r ca19b94eac7a src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements.test/src/org/graalvm/compiler/replacements/test/DerivedOopTest.java --- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements.test/src/org/graalvm/compiler/replacements/test/DerivedOopTest.java Mon Sep 23 09:16:05 2019 -0700 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements.test/src/org/graalvm/compiler/replacements/test/DerivedOopTest.java Wed Sep 25 22:40:41 2019 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2019, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it diff -r e47423f1318b -r ca19b94eac7a src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements.test/src/org/graalvm/compiler/replacements/test/FoldTest.java --- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements.test/src/org/graalvm/compiler/replacements/test/FoldTest.java Mon Sep 23 09:16:05 2019 -0700 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements.test/src/org/graalvm/compiler/replacements/test/FoldTest.java Wed Sep 25 22:40:41 2019 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2019, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it diff -r e47423f1318b -r ca19b94eac7a src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements.test/src/org/graalvm/compiler/replacements/test/IntegerExactExceptionTest.java --- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements.test/src/org/graalvm/compiler/replacements/test/IntegerExactExceptionTest.java Mon Sep 23 09:16:05 2019 -0700 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements.test/src/org/graalvm/compiler/replacements/test/IntegerExactExceptionTest.java Wed Sep 25 22:40:41 2019 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2019, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it diff -r e47423f1318b -r ca19b94eac7a src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements.test/src/org/graalvm/compiler/replacements/test/IntegerExactFoldTest.java --- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements.test/src/org/graalvm/compiler/replacements/test/IntegerExactFoldTest.java Mon Sep 23 09:16:05 2019 -0700 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements.test/src/org/graalvm/compiler/replacements/test/IntegerExactFoldTest.java Wed Sep 25 22:40:41 2019 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2019, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it diff -r e47423f1318b -r ca19b94eac7a src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements.test/src/org/graalvm/compiler/replacements/test/InvokerSignatureMismatchTest.java --- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements.test/src/org/graalvm/compiler/replacements/test/InvokerSignatureMismatchTest.java Mon Sep 23 09:16:05 2019 -0700 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements.test/src/org/graalvm/compiler/replacements/test/InvokerSignatureMismatchTest.java Wed Sep 25 22:40:41 2019 +0200 @@ -27,69 +27,47 @@ import static org.graalvm.compiler.test.SubprocessUtil.getVMCommandLine; import static org.graalvm.compiler.test.SubprocessUtil.withoutDebuggerArguments; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.util.List; + +import org.graalvm.compiler.core.test.CustomizedBytecodePatternTest; +import org.graalvm.compiler.serviceprovider.JavaVersionUtil; +import org.graalvm.compiler.test.SubprocessUtil; +import org.graalvm.compiler.test.SubprocessUtil.Subprocess; import org.junit.Test; import org.objectweb.asm.ClassWriter; import org.objectweb.asm.MethodVisitor; import org.objectweb.asm.Type; -import java.io.File; -import java.lang.invoke.MethodHandles; -import java.util.List; +public class InvokerSignatureMismatchTest extends CustomizedBytecodePatternTest { -import org.graalvm.compiler.core.test.CustomizedBytecodePatternTest; -import org.graalvm.compiler.test.SubprocessUtil; -import org.graalvm.compiler.test.SubprocessUtil.Subprocess; - -import jdk.vm.ci.meta.ResolvedJavaMethod; - -public class InvokerSignatureMismatchTest { - + @SuppressWarnings("try") @Test public void test() throws Throwable { List args = withoutDebuggerArguments(getVMCommandLine()); - String classPath = System.getProperty("java.class.path"); - classPath = classPath + File.pathSeparator + TestISMBL.class.getProtectionDomain().getCodeSource().getLocation().getPath(); - args.add("-Xbootclasspath/a:" + classPath); - args.add("-XX:-TieredCompilation"); - args.add("-XX:+EnableJVMCI"); - args.add("-XX:+UseJVMCICompiler"); - - args.add(TestISMBL.class.getName()); - Subprocess proc = SubprocessUtil.java(args); - if (proc.exitCode != 0) { - System.out.println(proc); - } - } -} - -class TestISMBL extends CustomizedBytecodePatternTest { + try (TemporaryDirectory temp = new TemporaryDirectory(null, getClass().getSimpleName())) { + if (JavaVersionUtil.JAVA_SPEC > 8) { + args.add("--class-path=" + temp); + args.add("--patch-module=java.base=" + temp); + } else { + args.add("-Xbootclasspath/a:" + temp); + } + args.add("-XX:-TieredCompilation"); + args.add("-XX:+UnlockExperimentalVMOptions"); + args.add("-XX:+EnableJVMCI"); + args.add("-XX:+UseJVMCICompiler"); - public static void main(String[] args) { - try { - new TestISMBL().test(); - } catch (Throwable e) { - e.printStackTrace(); - System.exit(1); - } - System.exit(0); - } + Path invokeDir = Files.createDirectories(temp.path.resolve(Paths.get("java", "lang", "invoke"))); + Files.write(temp.path.resolve("ISMTest.class"), generateClass("ISMTest")); + Files.write(invokeDir.resolve("MethodHandleHelper.class"), generateClass("java/lang/invoke/MethodHandleHelper")); - private void test() throws Throwable { - getClass("java/lang/invoke/MHHelper"); - Class testClass = getClass("ISMTest"); - - ResolvedJavaMethod mL = getResolvedJavaMethod(testClass, "mainLink"); - ResolvedJavaMethod mI = getResolvedJavaMethod(testClass, "mainInvoke"); - executeActual(mL, null, 100); - executeActual(mI, null, 100); - } - - @Override - protected Class getClass(String className) throws ClassNotFoundException { - if (className.equals("java/lang/invoke/MHHelper")) { - return super.getClassBL(className, MethodHandles.lookup()); - } else { - return super.getClass(className); + args.add("ISMTest"); + Subprocess proc = SubprocessUtil.java(args); + if (proc.exitCode != 0) { + throw new AssertionError(proc.toString()); + } } } @@ -99,7 +77,7 @@ ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_FRAMES); cw.visit(52, ACC_SUPER | ACC_PUBLIC, className, null, "java/lang/Object", null); - if (className.equals("java/lang/invoke/MHHelper")) { + if (className.equals("java/lang/invoke/MethodHandleHelper")) { MethodVisitor internalMemberName = cw.visitMethod(ACC_PUBLIC | ACC_STATIC, "internalMemberName", "(Ljava/lang/invoke/MethodHandle;)Ljava/lang/Object;", null, exceptions); internalMemberName.visitCode(); internalMemberName.visitVarInsn(ALOAD, 0); @@ -149,12 +127,12 @@ MethodVisitor mainLink = cw.visitMethod(ACC_PUBLIC | ACC_STATIC, "mainLink", "(I)I", null, exceptions); mainLink.visitCode(); mainLink.visitFieldInsn(GETSTATIC, className, "INT_MH", "Ljava/lang/invoke/MethodHandle;"); - mainLink.visitMethodInsn(INVOKESTATIC, "java/lang/invoke/MHHelper", "internalMemberName", "(Ljava/lang/invoke/MethodHandle;)Ljava/lang/Object;", false); + mainLink.visitMethodInsn(INVOKESTATIC, "java/lang/invoke/MethodHandleHelper", "internalMemberName", "(Ljava/lang/invoke/MethodHandle;)Ljava/lang/Object;", false); mainLink.visitVarInsn(ASTORE, 1); mainLink.visitVarInsn(ILOAD, 0); mainLink.visitInsn(I2F); mainLink.visitVarInsn(ALOAD, 1); - mainLink.visitMethodInsn(INVOKESTATIC, "java/lang/invoke/MHHelper", "linkToStatic", "(FLjava/lang/Object;)I", false); + mainLink.visitMethodInsn(INVOKESTATIC, "java/lang/invoke/MethodHandleHelper", "linkToStatic", "(FLjava/lang/Object;)I", false); mainLink.visitInsn(IRETURN); mainLink.visitMaxs(1, 1); mainLink.visitEnd(); @@ -164,7 +142,7 @@ mainInvoke.visitFieldInsn(GETSTATIC, className, "INT_MH", "Ljava/lang/invoke/MethodHandle;"); mainInvoke.visitVarInsn(ILOAD, 0); mainInvoke.visitInsn(I2F); - mainInvoke.visitMethodInsn(INVOKESTATIC, "java/lang/invoke/MHHelper", "invokeBasicI", "(Ljava/lang/invoke/MethodHandle;F)I", false); + mainInvoke.visitMethodInsn(INVOKESTATIC, "java/lang/invoke/MethodHandleHelper", "invokeBasicI", "(Ljava/lang/invoke/MethodHandle;F)I", false); mainInvoke.visitInsn(IRETURN); mainInvoke.visitMaxs(1, 1); mainInvoke.visitEnd(); @@ -177,6 +155,19 @@ bodyI.visitInsn(IRETURN); bodyI.visitMaxs(1, 1); bodyI.visitEnd(); + + MethodVisitor main = cw.visitMethod(ACC_PUBLIC | ACC_STATIC, "main", "([Ljava/lang/String;)V", null, exceptions); + main.visitCode(); + main.visitIntInsn(SIPUSH, 100); + main.visitMethodInsn(INVOKESTATIC, "ISMTest", "mainLink", "(I)I", false); + main.visitInsn(POP); + main.visitIntInsn(SIPUSH, 100); + main.visitMethodInsn(INVOKESTATIC, "ISMTest", "mainInvoke", "(I)I", false); + main.visitInsn(POP); + main.visitInsn(RETURN); + main.visitMaxs(1, 1); + main.visitEnd(); + } cw.visitEnd(); return cw.toByteArray(); diff -r e47423f1318b -r ca19b94eac7a src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements.test/src/org/graalvm/compiler/replacements/test/MethodSubstitutionTest.java --- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements.test/src/org/graalvm/compiler/replacements/test/MethodSubstitutionTest.java Mon Sep 23 09:16:05 2019 -0700 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements.test/src/org/graalvm/compiler/replacements/test/MethodSubstitutionTest.java Wed Sep 25 22:40:41 2019 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2019, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it diff -r e47423f1318b -r ca19b94eac7a src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements.test/src/org/graalvm/compiler/replacements/test/PEGraphDecoderTest.java --- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements.test/src/org/graalvm/compiler/replacements/test/PEGraphDecoderTest.java Mon Sep 23 09:16:05 2019 -0700 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements.test/src/org/graalvm/compiler/replacements/test/PEGraphDecoderTest.java Wed Sep 25 22:40:41 2019 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2019, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -26,6 +26,7 @@ import static org.graalvm.compiler.nodes.graphbuilderconf.InlineInvokePlugin.InlineInfo.createStandardInlineInfo; +import jdk.internal.vm.compiler.collections.EconomicMap; import org.graalvm.compiler.core.common.type.StampFactory; import org.graalvm.compiler.core.test.GraalCompilerTest; import org.graalvm.compiler.debug.DebugContext; @@ -138,7 +139,7 @@ registerPlugins(graphBuilderConfig.getPlugins().getInvocationPlugins()); targetGraph = new StructuredGraph.Builder(getInitialOptions(), debug, AllowAssumptions.YES).method(testMethod).build(); CachingPEGraphDecoder decoder = new CachingPEGraphDecoder(getTarget().arch, targetGraph, getProviders(), graphBuilderConfig, OptimisticOptimizations.NONE, AllowAssumptions.YES, - null, null, new InlineInvokePlugin[]{new InlineAll()}, null, null, null, null, null); + null, null, new InlineInvokePlugin[]{new InlineAll()}, null, null, null, null, null, null, EconomicMap.create()); decoder.decode(testMethod, false, false); debug.dump(DebugContext.BASIC_LEVEL, targetGraph, "Target Graph"); diff -r e47423f1318b -r ca19b94eac7a src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements.test/src/org/graalvm/compiler/replacements/test/ReplacementsParseTest.java --- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements.test/src/org/graalvm/compiler/replacements/test/ReplacementsParseTest.java Mon Sep 23 09:16:05 2019 -0700 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements.test/src/org/graalvm/compiler/replacements/test/ReplacementsParseTest.java Wed Sep 25 22:40:41 2019 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 2019, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it diff -r e47423f1318b -r ca19b94eac7a src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements.test/src/org/graalvm/compiler/replacements/test/SnippetsTest.java --- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements.test/src/org/graalvm/compiler/replacements/test/SnippetsTest.java Mon Sep 23 09:16:05 2019 -0700 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements.test/src/org/graalvm/compiler/replacements/test/SnippetsTest.java Wed Sep 25 22:40:41 2019 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2019, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it diff -r e47423f1318b -r ca19b94eac7a src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements.test/src/org/graalvm/compiler/replacements/test/StandardMethodSubstitutionsTest.java --- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements.test/src/org/graalvm/compiler/replacements/test/StandardMethodSubstitutionsTest.java Mon Sep 23 09:16:05 2019 -0700 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements.test/src/org/graalvm/compiler/replacements/test/StandardMethodSubstitutionsTest.java Wed Sep 25 22:40:41 2019 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2019, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it diff -r e47423f1318b -r ca19b94eac7a src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements.test/src/org/graalvm/compiler/replacements/test/StringCompareToAVX512Test.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements.test/src/org/graalvm/compiler/replacements/test/StringCompareToAVX512Test.java Wed Sep 25 22:40:41 2019 +0200 @@ -0,0 +1,71 @@ +/* + * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + + +package org.graalvm.compiler.replacements.test; + +import org.graalvm.compiler.core.test.GraalCompilerTest; +import org.junit.Test; + +// JDK-8228903 +public final class StringCompareToAVX512Test extends GraalCompilerTest { + + public static int compareTo(String str1, String str2) { + return str1.compareTo(str2); + } + + @Test + public void testLatin1VsUtf16BadStride() { + String latin1 = "000000001111111122222222333333334444444455555555666666667777777\u0099888888889"; + String utf16 = "000000001111111122222222333333334444444455555555666666667777777\u0699888888889"; + test("compareTo", latin1, utf16); + test("compareTo", utf16, latin1); + } + + @Test + public void testLatin1VsUtf16BadStride2() { + String latin1 = "00000000111111112222222233333333444444445555555566666666777777778888888\u008799999999AAAAAAAAB"; + String utf16 = "00000000111111112222222233333333444444445555555566666666777777778888888\u058799999999AAAAAAAAB"; + test("compareTo", latin1, utf16); + test("compareTo", utf16, latin1); + } + + @Test + public void testLatin1VsUtf16FalseEquality() { + // java.lang.AssertionError: expected:<-1536> but was:<0> + String latin1 = "00000000111111112222222233333333\u0099444444455555555"; + String utf16 = "00000000111111112222222233333333\u0699xxxxxxxxxxxxxxx"; + test("compareTo", latin1, utf16); + test("compareTo", utf16, latin1); + } + + @Test + public void testLatin1BeyondRange() { + StringBuilder latin1Builder = new StringBuilder(); + for (int j = 0; j <= 255; ++j) { + latin1Builder.append((char) j); + } + String latin1 = latin1Builder.toString(); + test("compareTo", latin1, String.valueOf(latin1.toCharArray())); + } +} diff -r e47423f1318b -r ca19b94eac7a src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements.test/src/org/graalvm/compiler/replacements/test/StringCompareToTest.java --- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements.test/src/org/graalvm/compiler/replacements/test/StringCompareToTest.java Mon Sep 23 09:16:05 2019 -0700 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements.test/src/org/graalvm/compiler/replacements/test/StringCompareToTest.java Wed Sep 25 22:40:41 2019 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2019, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it diff -r e47423f1318b -r ca19b94eac7a src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements.test/src/org/graalvm/compiler/replacements/test/StringCompressInflateTest.java --- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements.test/src/org/graalvm/compiler/replacements/test/StringCompressInflateTest.java Mon Sep 23 09:16:05 2019 -0700 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements.test/src/org/graalvm/compiler/replacements/test/StringCompressInflateTest.java Wed Sep 25 22:40:41 2019 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2019, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it diff -r e47423f1318b -r ca19b94eac7a src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements.test/src/org/graalvm/compiler/replacements/test/StringIndexOfCharTest.java --- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements.test/src/org/graalvm/compiler/replacements/test/StringIndexOfCharTest.java Mon Sep 23 09:16:05 2019 -0700 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements.test/src/org/graalvm/compiler/replacements/test/StringIndexOfCharTest.java Wed Sep 25 22:40:41 2019 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2019, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -32,11 +32,8 @@ import org.junit.runner.RunWith; import org.junit.runners.Parameterized; -@RunWith(value = Parameterized.class) +@RunWith(Parameterized.class) public class StringIndexOfCharTest extends GraalCompilerTest { - @Parameterized.Parameter(value = 0) public String sourceString; - @Parameterized.Parameter(value = 1) public int constantChar; - @Parameterized.Parameter(value = 2) public int fromIndex; @Parameterized.Parameters(name = "{0},{1},{2}") public static Collection data() { @@ -68,6 +65,16 @@ return tests; } + private final String sourceString; + private final int constantChar; + private final int fromIndex; + + public StringIndexOfCharTest(String sourceString, int constantChar, int fromIndex) { + this.sourceString = sourceString; + this.constantChar = constantChar; + this.fromIndex = fromIndex; + } + public int testStringIndexOf(String a, int b) { return a.indexOf(b); } diff -r e47423f1318b -r ca19b94eac7a src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements.test/src/org/graalvm/compiler/replacements/test/StringIndexOfConstantTest.java --- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements.test/src/org/graalvm/compiler/replacements/test/StringIndexOfConstantTest.java Mon Sep 23 09:16:05 2019 -0700 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements.test/src/org/graalvm/compiler/replacements/test/StringIndexOfConstantTest.java Wed Sep 25 22:40:41 2019 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2019, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -34,6 +34,10 @@ public class StringIndexOfConstantTest extends StringIndexOfTestBase { + public StringIndexOfConstantTest(String sourceString, String constantString) { + super(sourceString, constantString); + } + /* * These test definitions could live in the superclass except that the mx junit individual test * runner can't find tests in superclasses. @@ -87,6 +91,7 @@ @Override protected InstalledCode getCode(final ResolvedJavaMethod installedCodeOwner, StructuredGraph graph0, boolean ignoreForceCompile, boolean ignoreInstallAsDefault, OptionValues options) { // Force recompile if constant binding should be done - return super.getCode(installedCodeOwner, graph0, /* forceCompile */true, /* installAsDefault */false, options); + return super.getCode(installedCodeOwner, graph0, + /* forceCompile */ true, /* installAsDefault */ false, options); } } diff -r e47423f1318b -r ca19b94eac7a src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements.test/src/org/graalvm/compiler/replacements/test/StringIndexOfTest.java --- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements.test/src/org/graalvm/compiler/replacements/test/StringIndexOfTest.java Mon Sep 23 09:16:05 2019 -0700 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements.test/src/org/graalvm/compiler/replacements/test/StringIndexOfTest.java Wed Sep 25 22:40:41 2019 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2019, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -27,11 +27,15 @@ import org.junit.Test; public class StringIndexOfTest extends StringIndexOfTestBase { + + public StringIndexOfTest(String sourceString, String constantString) { + super(sourceString, constantString); + } + /* * These test definitions could live in the superclass except that the mx junit individual test * runner can't find tests in superclasses. */ - @Override @Test public void testStringIndexOfConstant() { diff -r e47423f1318b -r ca19b94eac7a src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements.test/src/org/graalvm/compiler/replacements/test/StringIndexOfTestBase.java --- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements.test/src/org/graalvm/compiler/replacements/test/StringIndexOfTestBase.java Mon Sep 23 09:16:05 2019 -0700 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements.test/src/org/graalvm/compiler/replacements/test/StringIndexOfTestBase.java Wed Sep 25 22:40:41 2019 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2019, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -26,19 +26,18 @@ import static org.junit.Assume.assumeFalse; +import java.util.ArrayList; +import java.util.Collection; + import org.graalvm.compiler.core.test.GraalCompilerTest; import org.junit.Test; import org.junit.runner.RunWith; import org.junit.runners.Parameterized; -import java.util.ArrayList; -import java.util.Collection; import jdk.vm.ci.aarch64.AArch64; @RunWith(value = Parameterized.class) public abstract class StringIndexOfTestBase extends GraalCompilerTest { - @Parameterized.Parameter(value = 0) public String sourceString; - @Parameterized.Parameter(value = 1) public String constantString; @Parameterized.Parameters(name = "{0},{1}") public static Collection data() { @@ -91,6 +90,14 @@ } } + protected final String sourceString; + protected final String constantString; + + public StringIndexOfTestBase(String sourceString, String constantString) { + this.sourceString = sourceString; + this.constantString = constantString; + } + public int testStringIndexOf(String a, String b) { return a.indexOf(b); } diff -r e47423f1318b -r ca19b94eac7a src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements.test/src/org/graalvm/compiler/replacements/test/StringSubstitutionTestBase.java --- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements.test/src/org/graalvm/compiler/replacements/test/StringSubstitutionTestBase.java Mon Sep 23 09:16:05 2019 -0700 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements.test/src/org/graalvm/compiler/replacements/test/StringSubstitutionTestBase.java Wed Sep 25 22:40:41 2019 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2019, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it diff -r e47423f1318b -r ca19b94eac7a src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements.test/src/org/graalvm/compiler/replacements/test/StringSubstitutionsTest.java --- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements.test/src/org/graalvm/compiler/replacements/test/StringSubstitutionsTest.java Mon Sep 23 09:16:05 2019 -0700 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements.test/src/org/graalvm/compiler/replacements/test/StringSubstitutionsTest.java Wed Sep 25 22:40:41 2019 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 2019, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it diff -r e47423f1318b -r ca19b94eac7a src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements.test/src/org/graalvm/compiler/replacements/test/SubstitutionNodeSourcePositionTest.java --- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements.test/src/org/graalvm/compiler/replacements/test/SubstitutionNodeSourcePositionTest.java Mon Sep 23 09:16:05 2019 -0700 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements.test/src/org/graalvm/compiler/replacements/test/SubstitutionNodeSourcePositionTest.java Wed Sep 25 22:40:41 2019 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2019, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it diff -r e47423f1318b -r ca19b94eac7a src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements.test/src/org/graalvm/compiler/replacements/test/SubstitutionsTest.java --- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements.test/src/org/graalvm/compiler/replacements/test/SubstitutionsTest.java Mon Sep 23 09:16:05 2019 -0700 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements.test/src/org/graalvm/compiler/replacements/test/SubstitutionsTest.java Wed Sep 25 22:40:41 2019 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2019, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it diff -r e47423f1318b -r ca19b94eac7a src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements.test/src/org/graalvm/compiler/replacements/test/classfile/ClassfileBytecodeProviderTest.java --- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements.test/src/org/graalvm/compiler/replacements/test/classfile/ClassfileBytecodeProviderTest.java Mon Sep 23 09:16:05 2019 -0700 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements.test/src/org/graalvm/compiler/replacements/test/classfile/ClassfileBytecodeProviderTest.java Wed Sep 25 22:40:41 2019 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2019, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -87,6 +87,7 @@ import java.util.zip.ZipEntry; import java.util.zip.ZipFile; +import org.graalvm.compiler.test.ModuleSupport; import org.graalvm.compiler.test.SubprocessUtil; import org.junit.Assert; import org.junit.Assume; @@ -146,6 +147,12 @@ */ private static final int CLASSES_PER_JAR = 250; + /** + * Magic token to denote the classes in the Java runtime image (i.e. in the {@code jrt:/} file + * system). + */ + public static final String JRT_CLASS_PATH_ENTRY = ""; + @Test public void test() { RuntimeProvider rt = Graal.getRequiredCapability(RuntimeProvider.class); @@ -153,42 +160,62 @@ MetaAccessProvider metaAccess = providers.getMetaAccess(); Assume.assumeTrue(VerifyPhase.class.desiredAssertionStatus()); - - String propertyName = JavaVersionUtil.JAVA_SPEC <= 8 ? "sun.boot.class.path" : "jdk.module.path"; - String bootclasspath = System.getProperty(propertyName); - Assert.assertNotNull("Cannot find value of " + propertyName, bootclasspath); + String bootclasspath; + if (JavaVersionUtil.JAVA_SPEC <= 8) { + String propertyName = "sun.boot.class.path"; + bootclasspath = System.getProperty(propertyName); + Assert.assertNotNull("Cannot find value of " + propertyName, bootclasspath); + } else { + bootclasspath = JRT_CLASS_PATH_ENTRY; + } for (String path : bootclasspath.split(File.pathSeparator)) { if (shouldProcess(path)) { try { - final ZipFile zipFile = new ZipFile(new File(path)); - int index = 0; - int step = zipFile.size() > CLASSES_PER_JAR ? zipFile.size() / CLASSES_PER_JAR : 1; - for (final Enumeration entry = zipFile.entries(); entry.hasMoreElements();) { - final ZipEntry zipEntry = entry.nextElement(); - if ((index % step) == 0) { - String name = zipEntry.getName(); - if (name.endsWith(".class") && !name.equals("module-info.class") && !name.startsWith("META-INF/versions/")) { - String className = name.substring(0, name.length() - ".class".length()).replace('/', '.'); - if (isInNativeImage(className)) { - /* - * Native image requires non-graalsdk classes to be present in - * the classpath. - */ - continue; - } - if (isGSON(className)) { - /* uses old class format */ - continue; - } - try { - checkClass(metaAccess, getSnippetReflection(), className); - } catch (ClassNotFoundException e) { - throw new AssertionError(e); + if (path.equals(JRT_CLASS_PATH_ENTRY)) { + for (String className : ModuleSupport.getJRTGraalClassNames()) { + if (isGSON(className)) { + /* + * GSON classes are compiled with old JDK + */ + continue; + } + try { + checkClass(metaAccess, getSnippetReflection(), className); + } catch (ClassNotFoundException e) { + throw new AssertionError(e); + } + } + } else { + final ZipFile zipFile = new ZipFile(new File(path)); + int index = 0; + int step = zipFile.size() > CLASSES_PER_JAR ? zipFile.size() / CLASSES_PER_JAR : 1; + for (final Enumeration entry = zipFile.entries(); entry.hasMoreElements();) { + final ZipEntry zipEntry = entry.nextElement(); + if ((index % step) == 0) { + String name = zipEntry.getName(); + if (name.endsWith(".class") && !name.equals("module-info.class") && !name.startsWith("META-INF/versions/")) { + String className = name.substring(0, name.length() - ".class".length()).replace('/', '.'); + if (isInNativeImage(className)) { + /* + * Native image requires non-graalsdk classes to be present + * in the classpath. + */ + continue; + } + if (isGSON(className)) { + /* uses old class format */ + continue; + } + try { + checkClass(metaAccess, getSnippetReflection(), className); + } catch (ClassNotFoundException e) { + throw new AssertionError(e); + } } } + index++; } - index++; } } catch (IOException ex) { Assert.fail(ex.toString()); diff -r e47423f1318b -r ca19b94eac7a src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements.test/src/org/graalvm/compiler/replacements/test/classfile/RedefineIntrinsicTest.java --- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements.test/src/org/graalvm/compiler/replacements/test/classfile/RedefineIntrinsicTest.java Mon Sep 23 09:16:05 2019 -0700 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements.test/src/org/graalvm/compiler/replacements/test/classfile/RedefineIntrinsicTest.java Wed Sep 25 22:40:41 2019 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 2019, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -55,6 +55,7 @@ import org.graalvm.compiler.nodes.graphbuilderconf.InvocationPlugins.Registration; import org.graalvm.compiler.replacements.test.ReplacementsTest; import org.graalvm.compiler.serviceprovider.JavaVersionUtil; +import org.graalvm.compiler.test.SubprocessUtil; import org.graalvm.compiler.test.SubprocessUtil.Subprocess; import org.junit.Assert; import org.junit.Test; @@ -116,6 +117,7 @@ } else { List vmArgs = withoutDebuggerArguments(getVMCommandLine()); vmArgs.add("-D" + recursionPropName + "=true"); + vmArgs.addAll(SubprocessUtil.getPackageOpeningOptions()); vmArgs.add("-Djdk.attach.allowAttachSelf=true"); Subprocess proc = java(vmArgs, "com.oracle.mxtool.junit.MxJUnitWrapper", getClass().getName()); if (proc.exitCode != 0) { diff -r e47423f1318b -r ca19b94eac7a src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/ArraySubstitutions.java --- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/ArraySubstitutions.java Mon Sep 23 09:16:05 2019 -0700 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/ArraySubstitutions.java Wed Sep 25 22:40:41 2019 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2019, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -29,6 +29,7 @@ import org.graalvm.compiler.api.replacements.ClassSubstitution; import org.graalvm.compiler.api.replacements.MethodSubstitution; import org.graalvm.compiler.nodes.DeoptimizeNode; +import org.graalvm.compiler.nodes.extended.BranchProbabilityNode; import org.graalvm.compiler.nodes.java.ArrayLengthNode; import jdk.vm.ci.meta.DeoptimizationAction; @@ -44,7 +45,7 @@ @MethodSubstitution public static int getLength(Object array) { - if (!array.getClass().isArray()) { + if (BranchProbabilityNode.probability(BranchProbabilityNode.DEOPT_PROBABILITY, !array.getClass().isArray())) { DeoptimizeNode.deopt(DeoptimizationAction.None, DeoptimizationReason.RuntimeConstraint); } return ArrayLengthNode.arrayLength(array); diff -r e47423f1318b -r ca19b94eac7a src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/CachingPEGraphDecoder.java --- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/CachingPEGraphDecoder.java Mon Sep 23 09:16:05 2019 -0700 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/CachingPEGraphDecoder.java Wed Sep 25 22:40:41 2019 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2019, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -71,17 +71,17 @@ public CachingPEGraphDecoder(Architecture architecture, StructuredGraph graph, Providers providers, GraphBuilderConfiguration graphBuilderConfig, OptimisticOptimizations optimisticOpts, AllowAssumptions allowAssumptions, LoopExplosionPlugin loopExplosionPlugin, InvocationPlugins invocationPlugins, InlineInvokePlugin[] inlineInvokePlugins, ParameterPlugin parameterPlugin, - NodePlugin[] nodePlugins, ResolvedJavaMethod callInlinedMethod, SourceLanguagePositionProvider sourceLanguagePositionProvider, - BasePhase postParsingPhase) { + NodePlugin[] nodePlugins, ResolvedJavaMethod callInlinedMethod, ResolvedJavaMethod callInlinedAgnosticMethod, SourceLanguagePositionProvider sourceLanguagePositionProvider, + BasePhase postParsingPhase, EconomicMap graphCache) { super(architecture, graph, providers, loopExplosionPlugin, - invocationPlugins, inlineInvokePlugins, parameterPlugin, nodePlugins, callInlinedMethod, sourceLanguagePositionProvider); + invocationPlugins, inlineInvokePlugins, parameterPlugin, nodePlugins, callInlinedMethod, callInlinedAgnosticMethod, sourceLanguagePositionProvider); this.providers = providers; this.graphBuilderConfig = graphBuilderConfig; this.optimisticOpts = optimisticOpts; this.allowAssumptions = allowAssumptions; + this.graphCache = graphCache; this.postParsingPhase = postParsingPhase; - this.graphCache = EconomicMap.create(); } protected GraphBuilderPhase.Instance createGraphBuilderPhaseInstance(IntrinsicContext initialIntrinsicContext) { diff -r e47423f1318b -r ca19b94eac7a src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/ConstantBindingParameterPlugin.java --- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/ConstantBindingParameterPlugin.java Mon Sep 23 09:16:05 2019 -0700 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/ConstantBindingParameterPlugin.java Wed Sep 25 22:40:41 2019 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2019, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it diff -r e47423f1318b -r ca19b94eac7a src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/ConstantStringIndexOfSnippets.java --- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/ConstantStringIndexOfSnippets.java Mon Sep 23 09:16:05 2019 -0700 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/ConstantStringIndexOfSnippets.java Wed Sep 25 22:40:41 2019 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2019, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it diff -r e47423f1318b -r ca19b94eac7a src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/DefaultJavaLoweringProvider.java --- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/DefaultJavaLoweringProvider.java Mon Sep 23 09:16:05 2019 -0700 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/DefaultJavaLoweringProvider.java Wed Sep 25 22:40:41 2019 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 2019, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -43,11 +43,13 @@ import java.util.BitSet; import java.util.List; +import jdk.vm.ci.meta.JavaConstant; import org.graalvm.compiler.api.directives.GraalDirectives; import org.graalvm.compiler.api.replacements.Snippet; import org.graalvm.compiler.api.replacements.SnippetReflectionProvider; import org.graalvm.compiler.core.common.LIRKind; import org.graalvm.compiler.core.common.spi.ForeignCallsProvider; +import org.graalvm.compiler.core.common.type.AbstractPointerStamp; import org.graalvm.compiler.core.common.type.IntegerStamp; import org.graalvm.compiler.core.common.type.ObjectStamp; import org.graalvm.compiler.core.common.type.Stamp; @@ -60,14 +62,20 @@ import org.graalvm.compiler.nodeinfo.InputType; import org.graalvm.compiler.nodes.CompressionNode.CompressionOp; import org.graalvm.compiler.nodes.ConstantNode; +import org.graalvm.compiler.nodes.EndNode; import org.graalvm.compiler.nodes.FieldLocationIdentity; import org.graalvm.compiler.nodes.FixedNode; +import org.graalvm.compiler.nodes.FixedWithNextNode; +import org.graalvm.compiler.nodes.IfNode; import org.graalvm.compiler.nodes.LogicNode; +import org.graalvm.compiler.nodes.MergeNode; import org.graalvm.compiler.nodes.NamedLocationIdentity; import org.graalvm.compiler.nodes.NodeView; +import org.graalvm.compiler.nodes.PhiNode; import org.graalvm.compiler.nodes.PiNode; import org.graalvm.compiler.nodes.StructuredGraph; import org.graalvm.compiler.nodes.ValueNode; +import org.graalvm.compiler.nodes.ValuePhiNode; import org.graalvm.compiler.nodes.calc.AddNode; import org.graalvm.compiler.nodes.calc.ConditionalNode; import org.graalvm.compiler.nodes.calc.IntegerBelowNode; @@ -91,6 +99,7 @@ import org.graalvm.compiler.nodes.extended.JavaWriteNode; import org.graalvm.compiler.nodes.extended.LoadArrayComponentHubNode; import org.graalvm.compiler.nodes.extended.LoadHubNode; +import org.graalvm.compiler.nodes.extended.LoadHubOrNullNode; import org.graalvm.compiler.nodes.extended.MembarNode; import org.graalvm.compiler.nodes.extended.RawLoadNode; import org.graalvm.compiler.nodes.extended.RawStoreNode; @@ -210,6 +219,8 @@ lowerArrayLengthNode((ArrayLengthNode) n, tool); } else if (n instanceof LoadHubNode) { lowerLoadHubNode((LoadHubNode) n, tool); + } else if (n instanceof LoadHubOrNullNode) { + lowerLoadHubOrNullNode((LoadHubOrNullNode) n, tool); } else if (n instanceof LoadArrayComponentHubNode) { lowerLoadArrayComponentHubNode((LoadArrayComponentHubNode) n); } else if (n instanceof MonitorEnterNode) { @@ -558,6 +569,36 @@ loadHub.replaceAtUsagesAndDelete(hub); } + protected void lowerLoadHubOrNullNode(LoadHubOrNullNode loadHubOrNullNode, LoweringTool tool) { + StructuredGraph graph = loadHubOrNullNode.graph(); + if (tool.getLoweringStage() != LoweringTool.StandardLoweringStage.LOW_TIER) { + return; + } + if (graph.getGuardsStage().allowsFloatingGuards()) { + return; + } + final FixedWithNextNode predecessor = tool.lastFixedNode(); + final ValueNode value = loadHubOrNullNode.getValue(); + AbstractPointerStamp stamp = (AbstractPointerStamp) value.stamp(NodeView.DEFAULT); + final LogicNode isNull = graph.addOrUniqueWithInputs(IsNullNode.create(value)); + final EndNode trueEnd = graph.add(new EndNode()); + final EndNode falseEnd = graph.add(new EndNode()); + final IfNode ifNode = graph.add(new IfNode(isNull, trueEnd, falseEnd, 0.5)); + final MergeNode merge = graph.add(new MergeNode()); + merge.addForwardEnd(trueEnd); + merge.addForwardEnd(falseEnd); + final AbstractPointerStamp hubStamp = (AbstractPointerStamp) loadHubOrNullNode.stamp(NodeView.DEFAULT); + ValueNode nullHub = ConstantNode.forConstant(hubStamp.asAlwaysNull(), JavaConstant.NULL_POINTER, tool.getMetaAccess(), graph); + final ValueNode nonNullValue = graph.addOrUniqueWithInputs(PiNode.create(value, stamp.asNonNull(), ifNode.falseSuccessor())); + ValueNode hub = createReadHub(graph, nonNullValue, tool); + ValueNode[] values = new ValueNode[]{nullHub, hub}; + final PhiNode hubPhi = graph.unique(new ValuePhiNode(hubStamp, merge, values)); + final FixedNode oldNext = predecessor.next(); + predecessor.setNext(ifNode); + merge.setNext(oldNext); + loadHubOrNullNode.replaceAtUsagesAndDelete(hubPhi); + } + protected void lowerLoadArrayComponentHubNode(LoadArrayComponentHubNode loadHub) { StructuredGraph graph = loadHub.graph(); ValueNode hub = createReadArrayComponentHub(graph, loadHub.getValue(), loadHub); diff -r e47423f1318b -r ca19b94eac7a src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/GraphKit.java --- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/GraphKit.java Mon Sep 23 09:16:05 2019 -0700 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/GraphKit.java Wed Sep 25 22:40:41 2019 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 2019, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it diff -r e47423f1318b -r ca19b94eac7a src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/InlineDuringParsingPlugin.java --- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/InlineDuringParsingPlugin.java Mon Sep 23 09:16:05 2019 -0700 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/InlineDuringParsingPlugin.java Wed Sep 25 22:40:41 2019 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2019, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it diff -r e47423f1318b -r ca19b94eac7a src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/IntrinsicGraphBuilder.java --- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/IntrinsicGraphBuilder.java Mon Sep 23 09:16:05 2019 -0700 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/IntrinsicGraphBuilder.java Wed Sep 25 22:40:41 2019 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 2019, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it diff -r e47423f1318b -r ca19b94eac7a src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/MethodHandlePlugin.java --- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/MethodHandlePlugin.java Mon Sep 23 09:16:05 2019 -0700 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/MethodHandlePlugin.java Wed Sep 25 22:40:41 2019 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2019, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -98,7 +98,7 @@ inlineEverything = args.length != argumentsList.size(); } ResolvedJavaMethod targetMethod = callTarget.targetMethod(); - if (inlineEverything && !targetMethod.hasBytecodes()) { + if (inlineEverything && !targetMethod.hasBytecodes() && !b.getReplacements().hasSubstitution(targetMethod, b.bci())) { // we need to force-inline but we can not, leave the invoke as-is return false; } diff -r e47423f1318b -r ca19b94eac7a src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/PEGraphDecoder.java --- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/PEGraphDecoder.java Mon Sep 23 09:16:05 2019 -0700 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/PEGraphDecoder.java Wed Sep 25 22:40:41 2019 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2019, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -274,7 +274,7 @@ int count = 0; PEGraphDecoder.PEMethodScope scope = methodScope; while (scope != null) { - if (scope.method.equals(callInlinedMethod)) { + if (scope.method.equals(callInlinedMethod) || scope.method.equals(callInlinedAgnosticMethod)) { count++; } scope = scope.caller; @@ -301,7 +301,7 @@ */ @Override public boolean canDeferPlugin(GeneratedInvocationPlugin plugin) { - return plugin.getSource().equals(Fold.class) || plugin.getSource().equals(Node.NodeIntrinsic.class); + return plugin.isGeneratedFromFoldOrNodeIntrinsic(); } @Override @@ -585,18 +585,20 @@ private final EconomicMap specialCallTargetCache; private final EconomicMap invocationPluginCache; private final ResolvedJavaMethod callInlinedMethod; + private final ResolvedJavaMethod callInlinedAgnosticMethod; protected final SourceLanguagePositionProvider sourceLanguagePositionProvider; public PEGraphDecoder(Architecture architecture, StructuredGraph graph, CoreProviders providers, LoopExplosionPlugin loopExplosionPlugin, InvocationPlugins invocationPlugins, InlineInvokePlugin[] inlineInvokePlugins, ParameterPlugin parameterPlugin, - NodePlugin[] nodePlugins, ResolvedJavaMethod callInlinedMethod, SourceLanguagePositionProvider sourceLanguagePositionProvider) { + NodePlugin[] nodePlugins, ResolvedJavaMethod callInlinedMethod, ResolvedJavaMethod callInlinedAgnosticMethod, SourceLanguagePositionProvider sourceLanguagePositionProvider) { super(architecture, graph, providers, true); this.loopExplosionPlugin = loopExplosionPlugin; this.invocationPlugins = invocationPlugins; this.inlineInvokePlugins = inlineInvokePlugins; this.parameterPlugin = parameterPlugin; this.nodePlugins = nodePlugins; + this.callInlinedAgnosticMethod = callInlinedAgnosticMethod; this.specialCallTargetCache = EconomicMap.create(Equivalence.DEFAULT); this.invocationPluginCache = EconomicMap.create(Equivalence.DEFAULT); this.callInlinedMethod = callInlinedMethod; diff -r e47423f1318b -r ca19b94eac7a src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/ReplacementsImpl.java --- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/ReplacementsImpl.java Mon Sep 23 09:16:05 2019 -0700 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/ReplacementsImpl.java Wed Sep 25 22:40:41 2019 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 2019, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it diff -r e47423f1318b -r ca19b94eac7a src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/SnippetCounter.java --- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/SnippetCounter.java Mon Sep 23 09:16:05 2019 -0700 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/SnippetCounter.java Wed Sep 25 22:40:41 2019 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2019, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it diff -r e47423f1318b -r ca19b94eac7a src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/SnippetCounterNode.java --- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/SnippetCounterNode.java Mon Sep 23 09:16:05 2019 -0700 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/SnippetCounterNode.java Wed Sep 25 22:40:41 2019 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2019, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it diff -r e47423f1318b -r ca19b94eac7a src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/SnippetTemplate.java --- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/SnippetTemplate.java Mon Sep 23 09:16:05 2019 -0700 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/SnippetTemplate.java Wed Sep 25 22:40:41 2019 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2019, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it diff -r e47423f1318b -r ca19b94eac7a src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/StandardGraphBuilderPlugins.java --- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/StandardGraphBuilderPlugins.java Mon Sep 23 09:16:05 2019 -0700 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/StandardGraphBuilderPlugins.java Wed Sep 25 22:40:41 2019 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2019, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it diff -r e47423f1318b -r ca19b94eac7a src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/TargetGraphBuilderPlugins.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/TargetGraphBuilderPlugins.java Wed Sep 25 22:40:41 2019 +0200 @@ -0,0 +1,35 @@ +/* + * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + + +package org.graalvm.compiler.replacements; + +import org.graalvm.compiler.bytecode.BytecodeProvider; +import org.graalvm.compiler.nodes.graphbuilderconf.GraphBuilderConfiguration.Plugins; + +import jdk.vm.ci.code.Architecture; + +public interface TargetGraphBuilderPlugins { + void register(Plugins plugins, BytecodeProvider replacementsBytecodeProvider, Architecture arch, boolean explicitUnsafeNullChecks, boolean registerMathPlugins, boolean emitJDK9StringSubstitutions, + boolean useFMAIntrinsics); +} diff -r e47423f1318b -r ca19b94eac7a src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/arraycopy/ArrayCopyCallNode.java --- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/arraycopy/ArrayCopyCallNode.java Mon Sep 23 09:16:05 2019 -0700 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/arraycopy/ArrayCopyCallNode.java Wed Sep 25 22:40:41 2019 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 2019, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it diff -r e47423f1318b -r ca19b94eac7a src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/arraycopy/ArrayCopySnippets.java --- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/arraycopy/ArrayCopySnippets.java Mon Sep 23 09:16:05 2019 -0700 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/arraycopy/ArrayCopySnippets.java Wed Sep 25 22:40:41 2019 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 2019, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -25,10 +25,12 @@ package org.graalvm.compiler.replacements.arraycopy; import static jdk.vm.ci.services.Services.IS_BUILDING_NATIVE_IMAGE; +import static org.graalvm.compiler.core.common.GraalOptions.GeneratePIC; import static org.graalvm.compiler.nodes.extended.BranchProbabilityNode.FREQUENT_PROBABILITY; import static org.graalvm.compiler.nodes.extended.BranchProbabilityNode.LIKELY_PROBABILITY; import static org.graalvm.compiler.nodes.extended.BranchProbabilityNode.NOT_FREQUENT_PROBABILITY; import static org.graalvm.compiler.nodes.extended.BranchProbabilityNode.SLOW_PATH_PROBABILITY; +import static org.graalvm.compiler.nodes.extended.BranchProbabilityNode.DEOPT_PROBABILITY; import static org.graalvm.compiler.nodes.extended.BranchProbabilityNode.probability; import java.util.EnumMap; @@ -210,7 +212,7 @@ Object nonNullDest = PiNode.asNonNullObject(dest); Pointer srcKlass = loadHub(nonNullSrc); Pointer destKlass = loadHub(nonNullDest); - if (probability(LIKELY_PROBABILITY, srcKlass == destKlass)) { + if (probability(LIKELY_PROBABILITY, srcKlass == destKlass) || probability(LIKELY_PROBABILITY, nonNullDest.getClass() == Object[].class)) { // no storecheck required. counters.objectCheckcastSameTypeCounter.inc(); counters.objectCheckcastSameTypeCopiedCounter.add(length); @@ -222,15 +224,7 @@ counters.objectCheckcastDifferentTypeCounter.inc(); counters.objectCheckcastDifferentTypeCopiedCounter.add(length); - int copiedElements = CheckcastArrayCopyCallNode.checkcastArraycopy(nonNullSrc, srcPos, nonNullDest, destPos, length, superCheckOffset, destElemKlass, false); - if (probability(SLOW_PATH_PROBABILITY, copiedElements != 0)) { - /* - * the stub doesn't throw the ArrayStoreException, but returns the number of - * copied elements (xor'd with -1). - */ - copiedElements ^= -1; - System.arraycopy(nonNullSrc, srcPos + copiedElements, nonNullDest, destPos + copiedElements, length - copiedElements); - } + System.arraycopy(nonNullSrc, srcPos, nonNullDest, destPos, length); } } } @@ -261,12 +255,27 @@ } } + /** + * Writing this as individual if statements to avoid a merge without a frame state. + */ private static void checkLimits(Object src, int srcPos, Object dest, int destPos, int length, Counters counters) { - if (probability(SLOW_PATH_PROBABILITY, srcPos < 0) || - probability(SLOW_PATH_PROBABILITY, destPos < 0) || - probability(SLOW_PATH_PROBABILITY, length < 0) || - probability(SLOW_PATH_PROBABILITY, srcPos > ArrayLengthNode.arrayLength(src) - length) || - probability(SLOW_PATH_PROBABILITY, destPos > ArrayLengthNode.arrayLength(dest) - length)) { + if (probability(DEOPT_PROBABILITY, srcPos < 0)) { + counters.checkAIOOBECounter.inc(); + DeoptimizeNode.deopt(DeoptimizationAction.None, DeoptimizationReason.RuntimeConstraint); + } + if (probability(DEOPT_PROBABILITY, destPos < 0)) { + counters.checkAIOOBECounter.inc(); + DeoptimizeNode.deopt(DeoptimizationAction.None, DeoptimizationReason.RuntimeConstraint); + } + if (probability(DEOPT_PROBABILITY, length < 0)) { + counters.checkAIOOBECounter.inc(); + DeoptimizeNode.deopt(DeoptimizationAction.None, DeoptimizationReason.RuntimeConstraint); + } + if (probability(DEOPT_PROBABILITY, srcPos > ArrayLengthNode.arrayLength(src) - length)) { + counters.checkAIOOBECounter.inc(); + DeoptimizeNode.deopt(DeoptimizationAction.None, DeoptimizationReason.RuntimeConstraint); + } + if (probability(DEOPT_PROBABILITY, destPos > ArrayLengthNode.arrayLength(dest) - length)) { counters.checkAIOOBECounter.inc(); DeoptimizeNode.deopt(DeoptimizationAction.None, DeoptimizationReason.RuntimeConstraint); } @@ -279,13 +288,13 @@ } else if (arrayTypeCheck == ArrayCopyTypeCheck.HUB_BASED_ARRAY_TYPE_CHECK) { Pointer srcHub = loadHub(nonNullSrc); Pointer destHub = loadHub(nonNullDest); - if (probability(SLOW_PATH_PROBABILITY, srcHub != destHub)) { + if (probability(DEOPT_PROBABILITY, srcHub != destHub)) { DeoptimizeNode.deopt(DeoptimizationAction.None, DeoptimizationReason.RuntimeConstraint); } } else if (arrayTypeCheck == ArrayCopyTypeCheck.LAYOUT_HELPER_BASED_ARRAY_TYPE_CHECK) { Pointer srcHub = loadHub(nonNullSrc); Pointer destHub = loadHub(nonNullDest); - if (probability(SLOW_PATH_PROBABILITY, getReadLayoutHelper(srcHub) != getReadLayoutHelper(destHub))) { + if (probability(DEOPT_PROBABILITY, getReadLayoutHelper(srcHub) != getReadLayoutHelper(destHub))) { DeoptimizeNode.deopt(DeoptimizationAction.None, DeoptimizationReason.RuntimeConstraint); } } else { @@ -413,6 +422,10 @@ snippetInfo = arraycopyGenericSnippet; // no need for additional type check to avoid duplicated work arrayTypeCheck = ArrayCopyTypeCheck.NO_ARRAY_TYPE_CHECK; + } else if (GeneratePIC.getValue(options)) { + // use generic copying for AOT compilation + snippetInfo = arraycopyGenericSnippet; + arrayTypeCheck = ArrayCopyTypeCheck.NO_ARRAY_TYPE_CHECK; } else if (srcComponentType != null && destComponentType != null) { if (!srcComponentType.isPrimitive() && !destComponentType.isPrimitive()) { // it depends on the array content if the copy succeeds - we need diff -r e47423f1318b -r ca19b94eac7a src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/classfile/ClassfileBytecodeProvider.java --- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/classfile/ClassfileBytecodeProvider.java Mon Sep 23 09:16:05 2019 -0700 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/classfile/ClassfileBytecodeProvider.java Wed Sep 25 22:40:41 2019 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2019, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it diff -r e47423f1318b -r ca19b94eac7a src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/nodes/ArrayEqualsNode.java --- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/nodes/ArrayEqualsNode.java Mon Sep 23 09:16:05 2019 -0700 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/nodes/ArrayEqualsNode.java Wed Sep 25 22:40:41 2019 +0200 @@ -232,12 +232,7 @@ return; } } - - int constantLength = -1; - if (length.isConstant()) { - constantLength = length.asJavaConstant().asInt(); - } - Value result = gen.getLIRGeneratorTool().emitArrayEquals(kind, gen.operand(array1), gen.operand(array2), gen.operand(length), constantLength, false); + Value result = gen.getLIRGeneratorTool().emitArrayEquals(kind, gen.operand(array1), gen.operand(array2), gen.operand(length), false); gen.setResult(this, result); } diff -r e47423f1318b -r ca19b94eac7a src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/nodes/ArrayRegionEqualsNode.java --- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/nodes/ArrayRegionEqualsNode.java Mon Sep 23 09:16:05 2019 -0700 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/nodes/ArrayRegionEqualsNode.java Wed Sep 25 22:40:41 2019 +0200 @@ -110,16 +110,11 @@ return; } } - - int constantLength = -1; - if (length.isConstant()) { - constantLength = length.asJavaConstant().asInt(); - } Value result; if (kind1 == kind2) { - result = gen.getLIRGeneratorTool().emitArrayEquals(kind1, gen.operand(array1), gen.operand(array2), gen.operand(length), constantLength, true); + result = gen.getLIRGeneratorTool().emitArrayEquals(kind1, gen.operand(array1), gen.operand(array2), gen.operand(length), true); } else { - result = gen.getLIRGeneratorTool().emitArrayEquals(kind1, kind2, gen.operand(array1), gen.operand(array2), gen.operand(length), constantLength, true); + result = gen.getLIRGeneratorTool().emitArrayEquals(kind1, kind2, gen.operand(array1), gen.operand(array2), gen.operand(length), true); } gen.setResult(this, result); } diff -r e47423f1318b -r ca19b94eac7a src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/nodes/BasicArrayCopyNode.java --- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/nodes/BasicArrayCopyNode.java Mon Sep 23 09:16:05 2019 -0700 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/nodes/BasicArrayCopyNode.java Wed Sep 25 22:40:41 2019 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2019, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -144,7 +144,8 @@ } private static boolean checkBounds(int position, int length, VirtualObjectNode virtualObject) { - return position >= 0 && position + length <= virtualObject.entryCount(); + assert length >= 0; + return position >= 0 && position <= virtualObject.entryCount() - length; } private static boolean checkEntryTypes(int srcPos, int length, VirtualObjectNode src, ResolvedJavaType destComponentType, VirtualizerTool tool) { diff -r e47423f1318b -r ca19b94eac7a src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/nodes/BasicObjectCloneNode.java --- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/nodes/BasicObjectCloneNode.java Mon Sep 23 09:16:05 2019 -0700 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/nodes/BasicObjectCloneNode.java Wed Sep 25 22:40:41 2019 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2019, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it diff -r e47423f1318b -r ca19b94eac7a src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/nodes/MacroNode.java --- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/nodes/MacroNode.java Mon Sep 23 09:16:05 2019 -0700 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/nodes/MacroNode.java Wed Sep 25 22:40:41 2019 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2019, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it diff -r e47423f1318b -r ca19b94eac7a src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/nodes/MethodHandleNode.java --- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/nodes/MethodHandleNode.java Mon Sep 23 09:16:05 2019 -0700 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/nodes/MethodHandleNode.java Wed Sep 25 22:40:41 2019 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2019, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it diff -r e47423f1318b -r ca19b94eac7a src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/nodes/ReadRegisterNode.java --- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/nodes/ReadRegisterNode.java Mon Sep 23 09:16:05 2019 -0700 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/nodes/ReadRegisterNode.java Wed Sep 25 22:40:41 2019 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2019, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it diff -r e47423f1318b -r ca19b94eac7a src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/nodes/WriteRegisterNode.java --- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/nodes/WriteRegisterNode.java Mon Sep 23 09:16:05 2019 -0700 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/nodes/WriteRegisterNode.java Wed Sep 25 22:40:41 2019 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2019, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it diff -r e47423f1318b -r ca19b94eac7a src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/nodes/ZeroMemoryNode.java --- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/nodes/ZeroMemoryNode.java Mon Sep 23 09:16:05 2019 -0700 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/nodes/ZeroMemoryNode.java Wed Sep 25 22:40:41 2019 +0200 @@ -60,7 +60,7 @@ @Override public void generate(NodeLIRBuilderTool gen) { - gen.getLIRGeneratorTool().getArithmetic().emitZeroMemory(gen.operand(getAddress()), gen.operand(length)); + gen.getLIRGeneratorTool().emitZeroMemory(gen.operand(getAddress()), gen.operand(length)); } @Override diff -r e47423f1318b -r ca19b94eac7a src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/nodes/arithmetic/IntegerAddExactNode.java --- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/nodes/arithmetic/IntegerAddExactNode.java Mon Sep 23 09:16:05 2019 -0700 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/nodes/arithmetic/IntegerAddExactNode.java Wed Sep 25 22:40:41 2019 +0200 @@ -33,6 +33,7 @@ import org.graalvm.compiler.core.common.type.IntegerStamp; import org.graalvm.compiler.core.common.type.Stamp; import org.graalvm.compiler.core.common.type.StampFactory; +import org.graalvm.compiler.graph.IterableNodeType; import org.graalvm.compiler.graph.NodeClass; import org.graalvm.compiler.graph.spi.CanonicalizerTool; import org.graalvm.compiler.nodeinfo.InputType; @@ -53,7 +54,7 @@ * case the addition would overflow the 32 bit range. */ @NodeInfo(cycles = CYCLES_2, size = SIZE_2) -public final class IntegerAddExactNode extends AddNode implements GuardedNode, IntegerExactArithmeticNode { +public final class IntegerAddExactNode extends AddNode implements GuardedNode, IntegerExactArithmeticNode, IterableNodeType { public static final NodeClass TYPE = NodeClass.create(IntegerAddExactNode.class); @Input(InputType.Guard) protected GuardingNode guard; diff -r e47423f1318b -r ca19b94eac7a src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/nodes/arithmetic/IntegerExactArithmeticSplitNode.java --- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/nodes/arithmetic/IntegerExactArithmeticSplitNode.java Mon Sep 23 09:16:05 2019 -0700 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/nodes/arithmetic/IntegerExactArithmeticSplitNode.java Wed Sep 25 22:40:41 2019 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2019, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it diff -r e47423f1318b -r ca19b94eac7a src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.serviceprovider/src/org/graalvm/compiler/serviceprovider/GraalServices.java --- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.serviceprovider/src/org/graalvm/compiler/serviceprovider/GraalServices.java Mon Sep 23 09:16:05 2019 -0700 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.serviceprovider/src/org/graalvm/compiler/serviceprovider/GraalServices.java Wed Sep 25 22:40:41 2019 +0200 @@ -89,13 +89,8 @@ synchronized (servicesCache) { ArrayList providersList = new ArrayList<>(); for (S provider : providers) { - /* - * When building libgraal, we want providers that comes from the Graal community - * and enterprise modules but not those available on the native-image class - * path. - */ Module module = provider.getClass().getModule(); - if (module.isNamed()) { + if (isHotSpotGraalModule(module.getName())) { providersList.add(provider); } } @@ -108,8 +103,29 @@ return providers; } + /** + * Determines if the module named by {@code name} is part of Graal when it is configured as a + * HotSpot JIT compiler. + */ + private static boolean isHotSpotGraalModule(String name) { + if (name != null) { + return name.equals("jdk.internal.vm.compiler") || + name.equals("jdk.internal.vm.compiler.management") || + name.equals("com.oracle.graal.graal_enterprise"); + } + return false; + } + protected static Iterable load0(Class service) { - Iterable iterable = ServiceLoader.load(service); + Module module = GraalServices.class.getModule(); + // Graal cannot know all the services used by another module + // (e.g. enterprise) so dynamically register the service use now. + if (!module.canUse(service)) { + module.addUses(service); + } + + ModuleLayer layer = module.getLayer(); + Iterable iterable = ServiceLoader.load(layer, service); return new Iterable<>() { @Override public Iterator iterator() { @@ -220,6 +236,10 @@ * trusted code. */ public static boolean isToStringTrusted(Class c) { + if (IS_IN_NATIVE_IMAGE) { + return true; + } + Module module = c.getModule(); Module jvmciModule = JVMCI_MODULE; assert jvmciModule.getPackages().contains("jdk.vm.ci.runtime"); diff -r e47423f1318b -r ca19b94eac7a src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.serviceprovider/src/org/graalvm/compiler/serviceprovider/SpeculationEncodingAdapter.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.serviceprovider/src/org/graalvm/compiler/serviceprovider/SpeculationEncodingAdapter.java Wed Sep 25 22:40:41 2019 +0200 @@ -0,0 +1,121 @@ +/* + * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + + +package org.graalvm.compiler.serviceprovider; + +import java.util.ArrayList; + +import jdk.vm.ci.code.BytecodePosition; + +class SpeculationEncodingAdapter implements SpeculationReasonGroup.SpeculationContextObject.Visitor { + private ArrayList objects; + + SpeculationEncodingAdapter() { + this.objects = null; + } + + Object[] flatten(Object[] context) { + boolean flatten = false; + for (Object c : context) { + if (c instanceof SpeculationReasonGroup.SpeculationContextObject || (c != null && c.getClass() == BytecodePosition.class)) { + // Needs extra work to flatten the representation + flatten = true; + break; + } + } + if (!flatten) { + return context; + } + objects = new ArrayList<>(); + for (Object c : context) { + if (c instanceof SpeculationReasonGroup.SpeculationContextObject) { + SpeculationReasonGroup.SpeculationContextObject sco = (SpeculationReasonGroup.SpeculationContextObject) c; + // These are compiler objects which all have the same class + // loader so the class name uniquely identifies the class. + objects.add(c.getClass().getName()); + sco.accept(this); + } else if (c != null && c.getClass() == BytecodePosition.class) { + BytecodePosition p = (BytecodePosition) c; + objects.add(c.getClass().getName()); + while (p != null) { + visitInt(p.getBCI()); + objects.add(p.getMethod()); + p = p.getCaller(); + } + } else { + objects.add(c); + } + } + return objects.toArray(); + } + + @Override + public void visitBoolean(boolean v) { + objects.add((byte) (v ? 1 : 0)); + } + + @Override + public void visitByte(byte v) { + objects.add(v); + } + + @Override + public void visitChar(char v) { + objects.add(v); + } + + @Override + public void visitShort(short v) { + objects.add(v); + } + + @Override + public void visitInt(int v) { + objects.add(v); + } + + @Override + public void visitLong(long v) { + objects.add(v); + } + + @Override + public void visitFloat(float v) { + objects.add(Float.floatToRawIntBits(v)); + } + + @Override + public void visitDouble(double v) { + objects.add(Double.doubleToRawLongBits(v)); + } + + @Override + public void visitObject(Object v) { + if (v == null) { + objects.add(0); + } else { + objects.add(v); + } + } +} diff -r e47423f1318b -r ca19b94eac7a src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.serviceprovider/src/org/graalvm/compiler/serviceprovider/UnencodedSpeculationReason.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.serviceprovider/src/org/graalvm/compiler/serviceprovider/UnencodedSpeculationReason.java Wed Sep 25 22:40:41 2019 +0200 @@ -0,0 +1,63 @@ +/* + * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + + +package org.graalvm.compiler.serviceprovider; + +import java.util.Arrays; + +import jdk.vm.ci.meta.SpeculationLog.SpeculationReason; + +/** + * An implementation of {@link SpeculationReason} based on direct, unencoded values. + */ +public final class UnencodedSpeculationReason implements SpeculationReason { + final int groupId; + final String groupName; + final Object[] context; + + UnencodedSpeculationReason(int groupId, String groupName, Object[] context) { + this.groupId = groupId; + this.groupName = groupName; + this.context = context; + } + + @Override + public boolean equals(Object obj) { + if (obj instanceof UnencodedSpeculationReason) { + UnencodedSpeculationReason that = (UnencodedSpeculationReason) obj; + return this.groupId == that.groupId && Arrays.equals(this.context, that.context); + } + return false; + } + + @Override + public int hashCode() { + return groupId + Arrays.hashCode(this.context); + } + + @Override + public String toString() { + return String.format("%s@%d%s", groupName, groupId, Arrays.toString(context)); + } +} diff -r e47423f1318b -r ca19b94eac7a src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.test/src/org/graalvm/compiler/test/ExportingClassLoader.java --- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.test/src/org/graalvm/compiler/test/ExportingClassLoader.java Mon Sep 23 09:16:05 2019 -0700 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.test/src/org/graalvm/compiler/test/ExportingClassLoader.java Wed Sep 25 22:40:41 2019 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2019, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -24,23 +24,17 @@ package org.graalvm.compiler.test; -import org.graalvm.compiler.serviceprovider.JavaVersionUtil; - /** * A class loader that exports all packages in the module defining the class loader to all classes * in the unnamed module associated with the loader. */ public class ExportingClassLoader extends ClassLoader { public ExportingClassLoader() { - if (JavaVersionUtil.JAVA_SPEC > 8) { - JLModule.fromClass(getClass()).exportAllPackagesTo(JLModule.getUnnamedModuleFor(this)); - } + ModuleSupport.exportAllPackagesTo(getClass(), this); } public ExportingClassLoader(ClassLoader parent) { super(parent); - if (JavaVersionUtil.JAVA_SPEC > 8) { - JLModule.fromClass(getClass()).exportAllPackagesTo(JLModule.getUnnamedModuleFor(this)); - } + ModuleSupport.exportAllPackagesTo(getClass(), this); } } diff -r e47423f1318b -r ca19b94eac7a src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.test/src/org/graalvm/compiler/test/GraalTest.java --- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.test/src/org/graalvm/compiler/test/GraalTest.java Mon Sep 23 09:16:05 2019 -0700 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.test/src/org/graalvm/compiler/test/GraalTest.java Wed Sep 25 22:40:41 2019 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2019, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -35,8 +35,10 @@ import java.nio.file.FileVisitResult; import java.nio.file.Files; import java.nio.file.Path; +import java.nio.file.Paths; import java.nio.file.SimpleFileVisitor; import java.nio.file.attribute.BasicFileAttributes; +import java.nio.file.attribute.FileAttribute; import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; @@ -458,7 +460,7 @@ Runtime.getRuntime().addShutdownHook(new Thread("GlobalMetricsPrinter") { @Override public void run() { - globalMetrics.print(new OptionValues(OptionValues.newOptionMap())); + // globalMetrics.print(new OptionValues(OptionValues.newOptionMap())); } }); } @@ -506,6 +508,30 @@ return createTimeout(milliseconds, TimeUnit.MILLISECONDS); } + public static class TemporaryDirectory implements AutoCloseable { + + public final Path path; + private IOException closeException; + + public TemporaryDirectory(Path dir, String prefix, FileAttribute... attrs) throws IOException { + path = Files.createTempDirectory(dir == null ? Paths.get(".") : dir, prefix, attrs); + } + + @Override + public void close() { + closeException = removeDirectory(path); + } + + public IOException getCloseException() { + return closeException; + } + + @Override + public String toString() { + return path.toString(); + } + } + /** * Tries to recursively remove {@code directory}. If it fails with an {@link IOException}, the * exception's {@code toString()} is printed to {@link System#err} and the exception is diff -r e47423f1318b -r ca19b94eac7a src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.test/src/org/graalvm/compiler/test/JLModule.java --- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.test/src/org/graalvm/compiler/test/JLModule.java Mon Sep 23 09:16:05 2019 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,221 +0,0 @@ -/* - * Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - - -package org.graalvm.compiler.test; - -import java.lang.reflect.AccessibleObject; -import java.lang.reflect.Method; -import java.util.Set; - -import org.graalvm.compiler.serviceprovider.JavaVersionUtil; - -/** - * Facade for the {@code java.lang.Module} class introduced in JDK9 that allows tests to be - * developed against JDK8 but use module logic if deployed on JDK9. - */ -public class JLModule { - - static { - if (JavaVersionUtil.JAVA_SPEC <= 8) { - throw new AssertionError("Use of " + JLModule.class + " only allowed if " + GraalTest.class.getName() + ".JDK8OrEarlier is false"); - } - } - - private final Object realModule; - - public JLModule(Object module) { - this.realModule = module; - } - - private static final Class moduleClass; - private static final Method getModuleMethod; - private static final Method getUnnamedModuleMethod; - private static final Method getPackagesMethod; - private static final Method isExportedMethod; - private static final Method isExported2Method; - private static final Method addExportsMethod; - /** - * {@code jdk.internal.module.Modules.addExports(Module, String, Module)}. - */ - private static final Method modulesAddExportsMethod; - - /** - * {@code jdk.internal.module.Modules.addOpens(Module, String, Module)}. - */ - private static final Method modulesAddOpensMethod; - - static { - try { - moduleClass = Class.forName("java.lang.Module"); - Class modulesClass = Class.forName("jdk.internal.module.Modules"); - getModuleMethod = Class.class.getMethod("getModule"); - getUnnamedModuleMethod = ClassLoader.class.getMethod("getUnnamedModule"); - getPackagesMethod = moduleClass.getMethod("getPackages"); - isExportedMethod = moduleClass.getMethod("isExported", String.class); - isExported2Method = moduleClass.getMethod("isExported", String.class, moduleClass); - addExportsMethod = moduleClass.getMethod("addExports", String.class, moduleClass); - modulesAddExportsMethod = modulesClass.getDeclaredMethod("addExports", moduleClass, String.class, moduleClass); - modulesAddOpensMethod = modulesClass.getDeclaredMethod("addOpens", moduleClass, String.class, moduleClass); - } catch (Exception e) { - throw new AssertionError(e); - } - } - - public static JLModule fromClass(Class cls) { - try { - return new JLModule(getModuleMethod.invoke(cls)); - } catch (Exception e) { - throw new AssertionError(e); - } - } - - public static JLModule getUnnamedModuleFor(ClassLoader cl) { - try { - return new JLModule(getUnnamedModuleMethod.invoke(cl)); - } catch (Exception e) { - throw new AssertionError(e); - } - } - - /** - * Exports all packages in this module to a given module. - */ - public void exportAllPackagesTo(JLModule module) { - if (this != module) { - for (String pkg : getPackages()) { - // Export all JVMCI packages dynamically instead - // of requiring a long list of -XaddExports - // options on the JVM command line. - if (!isExported(pkg, module)) { - addExports(pkg, module); - } - } - } - } - - @SuppressWarnings("unchecked") - public Set getPackages() { - try { - return (Set) getPackagesMethod.invoke(realModule); - } catch (Exception e) { - throw new AssertionError(e); - } - } - - public boolean isExported(String pn) { - try { - return (Boolean) isExportedMethod.invoke(realModule, pn); - } catch (Exception e) { - throw new AssertionError(e); - } - } - - public boolean isExported(String pn, JLModule other) { - try { - return (Boolean) isExported2Method.invoke(realModule, pn, other.realModule); - } catch (Exception e) { - throw new AssertionError(e); - } - } - - public void addExports(String pn, JLModule other) { - try { - addExportsMethod.invoke(realModule, pn, other.realModule); - } catch (Exception e) { - throw new AssertionError(e); - } - } - - private static Object unbox(Object obj) { - if (obj instanceof JLModule) { - return ((JLModule) obj).realModule; - } - return obj; - } - - /** - * Updates module m1 to export a package to module m2. Same as m1.addExports(pn, m2) but without - * a caller check - */ - public static void uncheckedAddExports(Object m1, String pn, Object m2) { - try { - modulesAddExportsMethod.invoke(null, unbox(m1), pn, unbox(m2)); - } catch (Exception e) { - throw new AssertionError(e); - } - } - - /** - * Opens all packages in {@code moduleMember}'s module for deep reflection (i.e., allow - * {@link AccessibleObject#setAccessible(boolean)} to be called for any class/method/field) by - * {@code requestor}'s module. - */ - public static void openAllPackagesForReflectionTo(Class moduleMember, Class requestor) { - try { - Object moduleToOpen = getModuleMethod.invoke(moduleMember); - Object requestorModule = getModuleMethod.invoke(requestor); - if (moduleToOpen != requestorModule) { - String[] packages = (String[]) getPackagesMethod.invoke(moduleToOpen); - for (String pkg : packages) { - modulesAddOpensMethod.invoke(moduleToOpen, pkg, requestorModule); - } - } - } catch (Exception e) { - throw new AssertionError(e); - } - } - - /** - * Opens {@code declaringClass}'s package to allow a method declared in {@code accessor} to call - * {@link AccessibleObject#setAccessible(boolean)} on an {@link AccessibleObject} representing a - * field or method declared by {@code declaringClass}. - */ - public static void openForReflectionTo(Class declaringClass, Class accessor) { - try { - Object moduleToOpen = getModuleMethod.invoke(declaringClass); - Object accessorModule = getModuleMethod.invoke(accessor); - if (moduleToOpen != accessorModule) { - modulesAddOpensMethod.invoke(null, moduleToOpen, declaringClass.getPackage().getName(), accessorModule); - } - } catch (Exception e) { - throw new AssertionError(e); - } - } - - /** - * Exports the package named {@code packageName} declared in {@code moduleMember}'s module to - * {@code requestor}'s module. - */ - public static void exportPackageTo(Class moduleMember, String packageName, Class requestor) { - try { - Object moduleToExport = getModuleMethod.invoke(moduleMember); - Object requestorModule = getModuleMethod.invoke(requestor); - if (moduleToExport != requestorModule) { - modulesAddExportsMethod.invoke(null, moduleToExport, packageName, requestorModule); - } - } catch (Exception e) { - throw new AssertionError(e); - } - } -} diff -r e47423f1318b -r ca19b94eac7a src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.test/src/org/graalvm/compiler/test/ModuleSupport.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.test/src/org/graalvm/compiler/test/ModuleSupport.java Wed Sep 25 22:40:41 2019 +0200 @@ -0,0 +1,129 @@ +/* + * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + + +package org.graalvm.compiler.test; + +import java.io.IOException; +import java.lang.module.ModuleDescriptor.Requires; +import java.net.URI; +import java.nio.file.FileSystem; +import java.nio.file.FileSystems; +import java.nio.file.Files; +import java.nio.file.Path; +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashSet; +import java.util.List; +import java.util.Set; + +import org.graalvm.compiler.debug.DebugOptions; + +import jdk.internal.module.Modules; + +public class ModuleSupport { + + public static void exportPackageTo(Class moduleMember, String packageName, Class requestor) { + Module moduleToExport = moduleMember.getModule(); + Module requestorModule = requestor.getModule(); + if (moduleToExport != requestorModule) { + Modules.addExports(moduleToExport, packageName, requestorModule); + } + } + + public static void exportAllPackagesTo(Class moduleMember, Class requestor) { + Module moduleToExport = moduleMember.getModule(); + Module requestorModule = requestor.getModule(); + if (moduleToExport != requestorModule) { + for (String packageName : moduleToExport.getPackages()) { + Modules.addExports(moduleToExport, packageName, requestorModule); + } + } + } + + public static void exportAllPackagesTo(Class moduleMember, ClassLoader cl) { + Module moduleToExport = moduleMember.getModule(); + Module unnamedModule = cl.getUnnamedModule(); + for (String packageName : moduleToExport.getPackages()) { + Modules.addExports(moduleToExport, packageName, unnamedModule); + } + } + + @SuppressWarnings("unused") + public static void exportAndOpenAllPackagesToUnnamed(String name) { + Module module = ModuleLayer.boot().findModule(name).orElseThrow(); + Set packages = module.getPackages(); + for (String pkg : packages) { + Modules.addExportsToAllUnnamed(module, pkg); + Modules.addOpensToAllUnnamed(module, pkg); + } + } + + public static List getJRTGraalClassNames() throws IOException { + List classNames = new ArrayList<>(); + FileSystem fs = FileSystems.newFileSystem(URI.create("jrt:/"), Collections.emptyMap()); + Module graalModule = DebugOptions.class.getModule(); + Set graalModuleSet = new HashSet<>(); + graalModuleSet.add(graalModule.getName()); + for (Module module : graalModule.getLayer().modules()) { + if (requires(module, graalModule)) { + graalModuleSet.add(module.getName()); + } + } + + Path top = fs.getPath("/modules/"); + Files.find(top, Integer.MAX_VALUE, + (path, attrs) -> attrs.isRegularFile()).forEach(p -> { + int nameCount = p.getNameCount(); + if (nameCount > 2) { + String base = p.getName(nameCount - 1).toString(); + if (base.endsWith(".class") && !base.equals("module-info.class")) { + String module = p.getName(1).toString(); + if (graalModuleSet.contains(module)) { + // Strip module prefix and convert to dotted + // form + String className = p.subpath(2, nameCount).toString().replace('/', '.'); + // Strip ".class" suffix + className = className.replace('/', '.').substring(0, className.length() - ".class".length()); + classNames.add(className); + } + } + } + }); + return classNames; + } + + private static boolean requires(Module module, Module graalModule) { + ModuleLayer graalLayer = graalModule.getLayer(); + for (Requires r : module.getDescriptor().requires()) { + if (r.name().equals(graalModule.getName())) { + return true; + } + Module dep = graalLayer.findModule(r.name()).get(); + if (requires(dep, graalModule)) { + return true; + } + } + return false; + } +} diff -r e47423f1318b -r ca19b94eac7a src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.test/src/org/graalvm/compiler/test/SubprocessUtil.java --- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.test/src/org/graalvm/compiler/test/SubprocessUtil.java Mon Sep 23 09:16:05 2019 -0700 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.test/src/org/graalvm/compiler/test/SubprocessUtil.java Wed Sep 25 22:40:41 2019 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2019, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -34,6 +34,7 @@ import java.util.Formatter; import java.util.List; import java.util.Map; +import java.util.function.Predicate; import java.util.regex.Matcher; import java.util.regex.Pattern; @@ -102,6 +103,26 @@ } /** + * Gets the command line options to do the same package opening and exporting specified by the + * {@code --open-packages} option to the {@code mx unittest} command. + * + * Properties defined in {@code com.oracle.mxtool.junit.MxJUnitWrapper}. + */ + public static List getPackageOpeningOptions() { + List result = new ArrayList<>(); + String[] actions = {"opens", "exports"}; + for (String action : actions) { + String opens = System.getProperty("com.oracle.mxtool.junit." + action); + if (opens != null && !opens.isEmpty()) { + for (String value : opens.split(System.lineSeparator())) { + result.add("--add-" + action + "=" + value); + } + } + } + return result; + } + + /** * Gets the command line used to start the current Java VM, including all VM arguments, but not * including the main class or any Java arguments. This can be used to spawn an identical VM, * but running different Java code. @@ -117,10 +138,30 @@ } /** - * Detects whether a java agent is attached. + * Detects whether a Java agent matching {@code agentPredicate} is specified in the VM + * arguments. + * + * @param agentPredicate a predicate that is given the value of a {@code -javaagent} VM argument + */ + public static boolean isJavaAgentAttached(Predicate agentPredicate) { + return SubprocessUtil.getVMCommandLine().stream().// + filter(args -> args.startsWith("-javaagent:")).// + map(s -> s.substring("-javaagent:".length())).// + anyMatch(agentPredicate); + } + + /** + * Detects whether a Java agent is specified in the VM arguments. */ public static boolean isJavaAgentAttached() { - return SubprocessUtil.getVMCommandLine().stream().anyMatch(args -> args.startsWith("-javaagent")); + return isJavaAgentAttached(javaAgentValue -> true); + } + + /** + * Detects whether the JaCoCo Java agent is specified in the VM arguments. + */ + public static boolean isJaCoCoAttached() { + return isJavaAgentAttached(s -> s.toLowerCase().contains("jacoco")); } /** @@ -278,7 +319,11 @@ while (i < commandLine.size()) { String s = commandLine.get(i); if (s.charAt(0) != '-') { - return i; + // https://bugs.openjdk.java.net/browse/JDK-8027634 + if (isJava8OrEarlier || s.charAt(0) != '@') { + return i; + } + i++; } else if (hasArg(s)) { i += 2; } else { diff -r e47423f1318b -r ca19b94eac7a src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.virtual/src/org/graalvm/compiler/virtual/phases/ea/EarlyReadEliminationPhase.java --- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.virtual/src/org/graalvm/compiler/virtual/phases/ea/EarlyReadEliminationPhase.java Mon Sep 23 09:16:05 2019 -0700 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.virtual/src/org/graalvm/compiler/virtual/phases/ea/EarlyReadEliminationPhase.java Wed Sep 25 22:40:41 2019 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 2019, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it diff -r e47423f1318b -r ca19b94eac7a src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.virtual/src/org/graalvm/compiler/virtual/phases/ea/EffectsClosure.java --- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.virtual/src/org/graalvm/compiler/virtual/phases/ea/EffectsClosure.java Mon Sep 23 09:16:05 2019 -0700 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.virtual/src/org/graalvm/compiler/virtual/phases/ea/EffectsClosure.java Wed Sep 25 22:40:41 2019 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 2019, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -357,6 +357,12 @@ lastMergedState = mergeProcessor.newState; for (Block block : loop.getBlocks()) { blockEffects.get(block).clear(); + if (block.isLoopHeader()) { + final GraphEffectList loopEffects = loopMergeEffects.get(block.getLoop()); + if (loopEffects != null) { + loopEffects.clear(); + } + } } } } diff -r e47423f1318b -r ca19b94eac7a src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.virtual/src/org/graalvm/compiler/virtual/phases/ea/EffectsPhase.java --- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.virtual/src/org/graalvm/compiler/virtual/phases/ea/EffectsPhase.java Mon Sep 23 09:16:05 2019 -0700 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.virtual/src/org/graalvm/compiler/virtual/phases/ea/EffectsPhase.java Wed Sep 25 22:40:41 2019 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 2019, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it diff -r e47423f1318b -r ca19b94eac7a src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.virtual/src/org/graalvm/compiler/virtual/phases/ea/GraphEffectList.java --- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.virtual/src/org/graalvm/compiler/virtual/phases/ea/GraphEffectList.java Mon Sep 23 09:16:05 2019 -0700 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.virtual/src/org/graalvm/compiler/virtual/phases/ea/GraphEffectList.java Wed Sep 25 22:40:41 2019 +0200 @@ -132,7 +132,7 @@ */ public void initializePhiInput(PhiNode node, int index, ValueNode value) { add("set phi input", (graph, obsoleteNodes) -> { - assert node.isAlive() && index >= 0; + assert node.isAlive() && index >= 0 : node; node.initializeValueAt(index, graph.addOrUniqueWithInputs(value)); }); } diff -r e47423f1318b -r ca19b94eac7a src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.virtual/src/org/graalvm/compiler/virtual/phases/ea/PEReadEliminationClosure.java --- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.virtual/src/org/graalvm/compiler/virtual/phases/ea/PEReadEliminationClosure.java Mon Sep 23 09:16:05 2019 -0700 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.virtual/src/org/graalvm/compiler/virtual/phases/ea/PEReadEliminationClosure.java Wed Sep 25 22:40:41 2019 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 2019, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it diff -r e47423f1318b -r ca19b94eac7a src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.virtual/src/org/graalvm/compiler/virtual/phases/ea/PartialEscapeClosure.java --- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.virtual/src/org/graalvm/compiler/virtual/phases/ea/PartialEscapeClosure.java Mon Sep 23 09:16:05 2019 -0700 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.virtual/src/org/graalvm/compiler/virtual/phases/ea/PartialEscapeClosure.java Wed Sep 25 22:40:41 2019 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 2019, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it diff -r e47423f1318b -r ca19b94eac7a src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.virtual/src/org/graalvm/compiler/virtual/phases/ea/PartialEscapePhase.java --- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.virtual/src/org/graalvm/compiler/virtual/phases/ea/PartialEscapePhase.java Mon Sep 23 09:16:05 2019 -0700 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.virtual/src/org/graalvm/compiler/virtual/phases/ea/PartialEscapePhase.java Wed Sep 25 22:40:41 2019 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 2019, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it diff -r e47423f1318b -r ca19b94eac7a src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.virtual/src/org/graalvm/compiler/virtual/phases/ea/VirtualizerToolImpl.java --- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.virtual/src/org/graalvm/compiler/virtual/phases/ea/VirtualizerToolImpl.java Mon Sep 23 09:16:05 2019 -0700 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.virtual/src/org/graalvm/compiler/virtual/phases/ea/VirtualizerToolImpl.java Wed Sep 25 22:40:41 2019 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 2019, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it diff -r e47423f1318b -r ca19b94eac7a src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.word/src/org/graalvm/compiler/word/Word.java --- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.word/src/org/graalvm/compiler/word/Word.java Mon Sep 23 09:16:05 2019 -0700 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.word/src/org/graalvm/compiler/word/Word.java Wed Sep 25 22:40:41 2019 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2019, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it diff -r e47423f1318b -r ca19b94eac7a src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.word/src/org/graalvm/compiler/word/WordOperationPlugin.java --- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.word/src/org/graalvm/compiler/word/WordOperationPlugin.java Mon Sep 23 09:16:05 2019 -0700 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.word/src/org/graalvm/compiler/word/WordOperationPlugin.java Wed Sep 25 22:40:41 2019 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2019, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it diff -r e47423f1318b -r ca19b94eac7a src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.word/src/org/graalvm/compiler/word/WordTypes.java --- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.word/src/org/graalvm/compiler/word/WordTypes.java Mon Sep 23 09:16:05 2019 -0700 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.word/src/org/graalvm/compiler/word/WordTypes.java Wed Sep 25 22:40:41 2019 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2019, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it diff -r e47423f1318b -r ca19b94eac7a src/jdk.internal.vm.compiler/share/classes/org.graalvm.graphio/src/org/graalvm/graphio/GraphOutput.java --- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.graphio/src/org/graalvm/graphio/GraphOutput.java Mon Sep 23 09:16:05 2019 -0700 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.graphio/src/org/graalvm/graphio/GraphOutput.java Wed Sep 25 22:40:41 2019 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 2019, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it diff -r e47423f1318b -r ca19b94eac7a src/jdk.internal.vm.compiler/share/classes/org.graalvm.graphio/src/org/graalvm/graphio/GraphProtocol.java --- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.graphio/src/org/graalvm/graphio/GraphProtocol.java Mon Sep 23 09:16:05 2019 -0700 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.graphio/src/org/graalvm/graphio/GraphProtocol.java Wed Sep 25 22:40:41 2019 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 2019, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it diff -r e47423f1318b -r ca19b94eac7a src/jdk.internal.vm.compiler/share/classes/org.graalvm.graphio/src/org/graalvm/graphio/ProtocolImpl.java --- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.graphio/src/org/graalvm/graphio/ProtocolImpl.java Mon Sep 23 09:16:05 2019 -0700 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.graphio/src/org/graalvm/graphio/ProtocolImpl.java Wed Sep 25 22:40:41 2019 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 2019, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it diff -r e47423f1318b -r ca19b94eac7a src/jdk.internal.vm.compiler/share/classes/org.graalvm.graphio/src/org/graalvm/graphio/package-info.java --- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.graphio/src/org/graalvm/graphio/package-info.java Mon Sep 23 09:16:05 2019 -0700 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.graphio/src/org/graalvm/graphio/package-info.java Wed Sep 25 22:40:41 2019 +0200 @@ -1,6 +1,5 @@ - /* - * Copyright (c) 2017, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2019, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it diff -r e47423f1318b -r ca19b94eac7a src/jdk.internal.vm.compiler/share/classes/org.graalvm.util.test/src/org/graalvm/util/test/CollectionSizeTest.java --- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.util.test/src/org/graalvm/util/test/CollectionSizeTest.java Mon Sep 23 09:16:05 2019 -0700 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.util.test/src/org/graalvm/util/test/CollectionSizeTest.java Wed Sep 25 22:40:41 2019 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2019, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it diff -r e47423f1318b -r ca19b94eac7a src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/TagletWriterImpl.java --- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/TagletWriterImpl.java Mon Sep 23 09:16:05 2019 -0700 +++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/TagletWriterImpl.java Wed Sep 25 22:40:41 2019 +0200 @@ -110,7 +110,8 @@ String tagText = ch.getText(itt.getSearchTerm()); if (tagText.charAt(0) == '"' && tagText.charAt(tagText.length() - 1) == '"') { - tagText = tagText.substring(1, tagText.length() - 1); + tagText = tagText.substring(1, tagText.length() - 1) + .replaceAll("\\s+", " "); } String desc = ch.getText(itt.getDescription()); diff -r e47423f1318b -r ca19b94eac7a src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/markup/Links.java --- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/markup/Links.java Mon Sep 23 09:16:05 2019 -0700 +++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/markup/Links.java Wed Sep 25 22:40:41 2019 +0200 @@ -312,7 +312,7 @@ * @return a valid HTML name */ public String getName(String name) { - return name.replaceAll(" +", ""); + return name.replaceAll("\\s+", ""); } } diff -r e47423f1318b -r ca19b94eac7a src/jdk.jcmd/linux/classes/sun/tools/ProcessHelper.java --- a/src/jdk.jcmd/linux/classes/sun/tools/ProcessHelper.java Mon Sep 23 09:16:05 2019 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,149 +0,0 @@ -/* - * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -package sun.tools; - -import java.io.IOException; -import java.io.UncheckedIOException; -import java.nio.file.Files; -import java.nio.file.Paths; -import java.util.jar.Attributes; -import java.util.jar.JarFile; -import java.util.stream.Stream; - -/** - * A helper class that retrieves the main class name for - * a running Java process using the proc filesystem (procfs) - */ -public class ProcessHelper implements sun.tools.common.ProcessHelper { - - - private static final String CMD_PREFIX = "cmd:"; - private static final ProcessHelper INSTANCE = new ProcessHelper(); - - public static ProcessHelper getInstance() { - return INSTANCE; - } - - /** - * Gets the main class name for the given Java process by parsing the - * process command line. If the application was started with the -jar - * option this method returns the name of the jar file. If the application - * was started with -m or --module option, the method returns - * the module name and the main class name. - * @param pid - process ID (pid) - * @return the main class name or null if the process no longer exists or - * was started with a native launcher (e.g. jcmd etc) - */ - - public String getMainClass(String pid) { - String cmdLine = getCommandLine(pid); - if (cmdLine == null) { - return null; - } - if (cmdLine.startsWith(CMD_PREFIX)) { - cmdLine = cmdLine.substring(CMD_PREFIX.length()); - } - String[] parts = cmdLine.split("\0"); - String mainClass = null; - - if(parts.length == 0) { - return null; - } - - // Check the executable - String[] executablePath = parts[0].split("/"); - if (executablePath.length > 0) { - String binaryName = executablePath[executablePath.length - 1]; - if (!"java".equals(binaryName)) { - // Skip the process if it is not started with java launcher - return null; - } - } - - // To be consistent with the behavior on other platforms, if -jar, -m, or --module - // options are used then just return the value (the path to the jar file or module - // name with a main class). Otherwise, the main class name is the first part that - // is not a Java option (doesn't start with '-' and is not a classpath or a module - // whitespace option). - - for (int i = 1; i < parts.length && mainClass == null; i++) { - if (i < parts.length - 1) { - if (parts[i].equals("-m") || parts[i].equals("--module") || parts[i].equals("-jar")) { - return parts[i + 1]; - } - } - - if (parts[i].startsWith("--module=")) { - return parts[i].substring("--module=".length()); - } - - // If this is a classpath or a module whitespace option then skip the next part - // (the classpath or the option value itself) - if (parts[i].equals("-cp") || parts[i].equals("-classpath") || parts[i].equals("--class-path") || - isModuleWhiteSpaceOption(parts[i])) { - i++; - continue; - } - // Skip all other Java options - if (parts[i].startsWith("-")) { - continue; - } - - // If it is a source-file mode then return null - if (parts[i].endsWith(".java")) { - return null; - } - - mainClass = parts[i]; - } - return mainClass; - - } - - private static String getCommandLine(String pid) { - try (Stream lines = - Files.lines(Paths.get("/proc/" + pid + "/cmdline"))) { - return lines.findFirst().orElse(null); - } catch (IOException | UncheckedIOException e) { - return null; - } - } - - private static boolean isModuleWhiteSpaceOption(String option) { - return option.equals("-p") || - option.equals("--module-path") || - option.equals("--upgrade-module-path") || - option.equals("--add-modules") || - option.equals("--limit-modules") || - option.equals("--add-exports") || - option.equals("--add-opens") || - option.equals("--add-reads") || - option.equals("--patch-module"); - } - -} - - diff -r e47423f1318b -r ca19b94eac7a src/jdk.jcmd/linux/classes/sun/tools/common/ProcessHelper.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/jdk.jcmd/linux/classes/sun/tools/common/ProcessHelper.java Wed Sep 25 22:40:41 2019 +0200 @@ -0,0 +1,136 @@ +/* + * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package sun.tools.common; + +import java.io.IOException; +import java.io.UncheckedIOException; +import java.nio.file.Files; +import java.nio.file.Paths; +import java.util.stream.Stream; + +/** + * A helper class that retrieves the main class name for + * a running Java process using the proc filesystem (procfs) + */ +final class ProcessHelper { + + private static final String CMD_PREFIX = "cmd:"; + + /** + * Gets the main class name for the given Java process by parsing the + * process command line. If the application was started with the -jar + * option this method returns the name of the jar file. If the application + * was started with -m or --module option, the method returns + * the module name and the main class name. + * @param pid - process ID (pid) + * @return the main class name or null if the process no longer exists or + * was started with a native launcher (e.g. jcmd etc) + */ + static String getMainClass(String pid) { + String cmdLine = getCommandLine(pid); + if (cmdLine == null) { + return null; + } + if (cmdLine.startsWith(CMD_PREFIX)) { + cmdLine = cmdLine.substring(CMD_PREFIX.length()); + } + String[] parts = cmdLine.split("\0"); + String mainClass = null; + + if (parts.length == 0) { + return null; + } + + // Check the executable + String[] executablePath = parts[0].split("/"); + if (executablePath.length > 0) { + String binaryName = executablePath[executablePath.length - 1]; + if (!"java".equals(binaryName)) { + // Skip the process if it is not started with java launcher + return null; + } + } + + // To be consistent with the behavior on other platforms, if -jar, -m, or --module + // options are used then just return the value (the path to the jar file or module + // name with a main class). Otherwise, the main class name is the first part that + // is not a Java option (doesn't start with '-' and is not a classpath or a module + // whitespace option). + + for (int i = 1; i < parts.length && mainClass == null; i++) { + if (i < parts.length - 1) { + if (parts[i].equals("-m") || parts[i].equals("--module") || parts[i].equals("-jar")) { + return parts[i + 1]; + } + } + + if (parts[i].startsWith("--module=")) { + return parts[i].substring("--module=".length()); + } + + // If this is a classpath or a module whitespace option then skip the next part + // (the classpath or the option value itself) + if (parts[i].equals("-cp") || parts[i].equals("-classpath") || parts[i].equals("--class-path") || + isModuleWhiteSpaceOption(parts[i])) { + i++; + continue; + } + // Skip all other Java options + if (parts[i].startsWith("-")) { + continue; + } + + // If it is a source-file mode then return null + if (parts[i].endsWith(".java")) { + return null; + } + + mainClass = parts[i]; + } + return mainClass; + } + + private static String getCommandLine(String pid) { + try (Stream lines = + Files.lines(Paths.get("/proc/" + pid + "/cmdline"))) { + return lines.findFirst().orElse(null); + } catch (IOException | UncheckedIOException e) { + return null; + } + } + + private static boolean isModuleWhiteSpaceOption(String option) { + return option.equals("-p") || + option.equals("--module-path") || + option.equals("--upgrade-module-path") || + option.equals("--add-modules") || + option.equals("--limit-modules") || + option.equals("--add-exports") || + option.equals("--add-opens") || + option.equals("--add-reads") || + option.equals("--patch-module"); + } +} diff -r e47423f1318b -r ca19b94eac7a src/jdk.jcmd/share/classes/sun/tools/common/ProcessArgumentMatcher.java --- a/src/jdk.jcmd/share/classes/sun/tools/common/ProcessArgumentMatcher.java Mon Sep 23 09:16:05 2019 -0700 +++ b/src/jdk.jcmd/share/classes/sun/tools/common/ProcessArgumentMatcher.java Wed Sep 25 22:40:41 2019 +0200 @@ -79,15 +79,10 @@ private static boolean check(VirtualMachineDescriptor vmd, String excludeClass, String partialMatch) { - String mainClass = null; + // Try to get the main class name using (platform specific) ProcessHelper + String mainClass = ProcessHelper.getMainClass(vmd.id()); - // Get the main class name using platform specific helper - ProcessHelper helper = ProcessHelper.platformProcessHelper(); - if (helper != null) { - mainClass = helper.getMainClass(vmd.id()); - } - - // If the main class name is still unset then retrieve it with the attach mechanism + // If the main class name could not be retrieved by ProcessHelper, get it with the attach mechanism if (mainClass == null) { try { VmIdentifier vmId = new VmIdentifier(vmd.id()); diff -r e47423f1318b -r ca19b94eac7a src/jdk.jcmd/share/classes/sun/tools/common/ProcessHelper.java --- a/src/jdk.jcmd/share/classes/sun/tools/common/ProcessHelper.java Mon Sep 23 09:16:05 2019 -0700 +++ b/src/jdk.jcmd/share/classes/sun/tools/common/ProcessHelper.java Wed Sep 25 22:40:41 2019 +0200 @@ -25,33 +25,12 @@ package sun.tools.common; -import java.lang.reflect.Method; - /** * A helper class to retrieve the main class name for a running - * Java process. + * Java process. Default implementation returns null. Platform specific + * implementation currently available for Linux only. */ - -public interface ProcessHelper { - - /** - * Returns an instance of the ProcessHelper class. - * - * @return ProcessHelper object or null if not supported on this platform. - */ - public static ProcessHelper platformProcessHelper() { - try { - Class c = Class.forName("sun.tools.ProcessHelper"); - @SuppressWarnings("unchecked") - Method m = c.getMethod("getInstance"); - return (ProcessHelper) m.invoke(null); - } catch (ClassNotFoundException e) { - return null; - } catch (ReflectiveOperationException e) { - throw new InternalError(e); - } - } - +final class ProcessHelper { /** * Returns the main class name for the given Java process @@ -59,6 +38,7 @@ * @param pid - process ID (pid) * @return main class name or null if the main class could not be retrieved */ - - String getMainClass(String pid); + static String getMainClass(String pid) { + return null; + } } diff -r e47423f1318b -r ca19b94eac7a src/jdk.naming.dns/share/classes/com/sun/jndi/dns/DnsClient.java --- a/src/jdk.naming.dns/share/classes/com/sun/jndi/dns/DnsClient.java Mon Sep 23 09:16:05 2019 -0700 +++ b/src/jdk.naming.dns/share/classes/com/sun/jndi/dns/DnsClient.java Wed Sep 25 22:40:41 2019 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2017, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 2019, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -29,7 +29,9 @@ import java.net.DatagramSocket; import java.net.DatagramPacket; import java.net.InetAddress; +import java.net.InetSocketAddress; import java.net.Socket; +import java.net.SocketTimeoutException; import java.security.SecureRandom; import javax.naming.*; @@ -82,7 +84,7 @@ private static final SecureRandom random = JCAUtil.getSecureRandom(); private InetAddress[] servers; private int[] serverPorts; - private int timeout; // initial timeout on UDP queries in ms + private int timeout; // initial timeout on UDP and TCP queries in ms private int retries; // number of UDP retries private final Object udpSocketLock = new Object(); @@ -100,7 +102,7 @@ /* * Each server is of the form "server[:port]". IPv6 literal host names * include delimiting brackets. - * "timeout" is the initial timeout interval (in ms) for UDP queries, + * "timeout" is the initial timeout interval (in ms) for queries, * and "retries" gives the number of retries per server. */ public DnsClient(String[] servers, int timeout, int retries) @@ -237,6 +239,7 @@ // Try each server, starting with the one that just // provided the truncated message. + int retryTimeout = (timeout * (1 << retry)); for (int j = 0; j < servers.length; j++) { int ij = (i + j) % servers.length; if (doNotRetry[ij]) { @@ -244,7 +247,7 @@ } try { Tcp tcp = - new Tcp(servers[ij], serverPorts[ij]); + new Tcp(servers[ij], serverPorts[ij], retryTimeout); byte[] msg2; try { msg2 = doTcpQuery(tcp, pkt); @@ -327,7 +330,7 @@ // Try each name server. for (int i = 0; i < servers.length; i++) { try { - Tcp tcp = new Tcp(servers[i], serverPorts[i]); + Tcp tcp = new Tcp(servers[i], serverPorts[i], timeout); byte[] msg; try { msg = doTcpQuery(tcp, pkt); @@ -462,11 +465,11 @@ */ private byte[] continueTcpQuery(Tcp tcp) throws IOException { - int lenHi = tcp.in.read(); // high-order byte of response length + int lenHi = tcp.read(); // high-order byte of response length if (lenHi == -1) { return null; // EOF } - int lenLo = tcp.in.read(); // low-order byte of response length + int lenLo = tcp.read(); // low-order byte of response length if (lenLo == -1) { throw new IOException("Corrupted DNS response: bad length"); } @@ -474,7 +477,7 @@ byte[] msg = new byte[len]; int pos = 0; // next unfilled position in msg while (len > 0) { - int n = tcp.in.read(msg, pos, len); + int n = tcp.read(msg, pos, len); if (n == -1) { throw new IOException( "Corrupted DNS response: too little data"); @@ -682,20 +685,62 @@ class Tcp { - private Socket sock; - java.io.InputStream in; - java.io.OutputStream out; + private final Socket sock; + private final java.io.InputStream in; + final java.io.OutputStream out; + private int timeoutLeft; - Tcp(InetAddress server, int port) throws IOException { - sock = new Socket(server, port); - sock.setTcpNoDelay(true); - out = new java.io.BufferedOutputStream(sock.getOutputStream()); - in = new java.io.BufferedInputStream(sock.getInputStream()); + Tcp(InetAddress server, int port, int timeout) throws IOException { + sock = new Socket(); + try { + long start = System.currentTimeMillis(); + sock.connect(new InetSocketAddress(server, port), timeout); + timeoutLeft = (int) (timeout - (System.currentTimeMillis() - start)); + if (timeoutLeft <= 0) + throw new SocketTimeoutException(); + + sock.setTcpNoDelay(true); + out = new java.io.BufferedOutputStream(sock.getOutputStream()); + in = new java.io.BufferedInputStream(sock.getInputStream()); + } catch (Exception e) { + try { + sock.close(); + } catch (IOException ex) { + e.addSuppressed(ex); + } + throw e; + } } void close() throws IOException { sock.close(); } + + private interface SocketReadOp { + int read() throws IOException; + } + + private int readWithTimeout(SocketReadOp reader) throws IOException { + if (timeoutLeft <= 0) + throw new SocketTimeoutException(); + + sock.setSoTimeout(timeoutLeft); + long start = System.currentTimeMillis(); + try { + return reader.read(); + } + finally { + timeoutLeft -= System.currentTimeMillis() - start; + } + } + + int read() throws IOException { + return readWithTimeout(() -> in.read()); + } + + int read(byte b[], int off, int len) throws IOException { + return readWithTimeout(() -> in.read(b, off, len)); + } } /* diff -r e47423f1318b -r ca19b94eac7a src/jdk.naming.dns/share/classes/module-info.java --- a/src/jdk.naming.dns/share/classes/module-info.java Mon Sep 23 09:16:05 2019 -0700 +++ b/src/jdk.naming.dns/share/classes/module-info.java Wed Sep 25 22:40:41 2019 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 2019, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -26,7 +26,38 @@ /** * Provides the implementation of the DNS Java Naming provider. * + *

Environment Properties

+ * + *

The following JNDI environment properties may be used when creating + * the initial context. + * + *

    + *
  • com.sun.jndi.dns.timeout.initial
  • + *
  • com.sun.jndi.dns.timeout.retries
  • + *
+ * + *

These properties are used to alter the timeout-related defaults that the + * DNS provider uses when submitting queries. The DNS provider submits queries + * using the following exponential backoff algorithm. The provider submits a + * query to a DNS server and waits for a response to arrive within a timeout + * period (1 second by default). If it receives no response within the timeout + * period, it queries the next server, and so on. If the provider receives no + * response from any server, it doubles the timeout period and repeats the + * process of submitting the query to each server, up to a maximum number of + * retries (4 by default). + * + *

The {@code com.sun.jndi.dns.timeout.initial} property, if set, specifies + * the number of milliseconds to use as the initial timeout period (i.e., before + * any doubling). If this property has not been set, the default initial timeout + * is 1000 milliseconds. + * + *

The {@code com.sun.jndi.dns.timeout.retries} property, if set, specifies + * the number of times to retry each server using the exponential backoff + * algorithm described previously. If this property has not been set, the + * default number of retries is 4. + * * @provides javax.naming.spi.InitialContextFactory + * * @moduleGraph * @since 9 */ diff -r e47423f1318b -r ca19b94eac7a src/jdk.security.auth/share/classes/com/sun/security/auth/module/NTSystem.java --- a/src/jdk.security.auth/share/classes/com/sun/security/auth/module/NTSystem.java Mon Sep 23 09:16:05 2019 -0700 +++ b/src/jdk.security.auth/share/classes/com/sun/security/auth/module/NTSystem.java Wed Sep 25 22:40:41 2019 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 2019, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -35,12 +35,14 @@ private native void getCurrent(boolean debug); private native long getImpersonationToken0(); + // Warning: the next 6 fields are used by nt.c private String userName; private String domain; private String domainSID; private String userSID; private String[] groupIDs; private String primaryGroupID; + private long impersonationToken; /** diff -r e47423f1318b -r ca19b94eac7a src/jdk.security.auth/share/classes/com/sun/security/auth/module/UnixSystem.java --- a/src/jdk.security.auth/share/classes/com/sun/security/auth/module/UnixSystem.java Mon Sep 23 09:16:05 2019 -0700 +++ b/src/jdk.security.auth/share/classes/com/sun/security/auth/module/UnixSystem.java Wed Sep 25 22:40:41 2019 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 2019, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -33,6 +33,7 @@ private native void getUnixInfo(); + // Warning: the following 4 fields are used by Unix.c protected String username; protected long uid; protected long gid; diff -r e47423f1318b -r ca19b94eac7a test/hotspot/jtreg/ProblemList-graal.txt --- a/test/hotspot/jtreg/ProblemList-graal.txt Mon Sep 23 09:16:05 2019 -0700 +++ b/test/hotspot/jtreg/ProblemList-graal.txt Wed Sep 25 22:40:41 2019 +0200 @@ -43,8 +43,6 @@ compiler/unsafe/UnsafeGetConstantField.java 8181833 generic-all compiler/unsafe/UnsafeGetStableArrayElement.java 8181833 generic-all -compiler/unsafe/UnsafeOffHeapBooleanTest.java 8181833 generic-all -compiler/unsafe/UnsafeOnHeapBooleanTest.java 8181833 generic-all compiler/whitebox/ClearMethodStateTest.java 8181831 generic-all compiler/whitebox/EnqueueMethodForCompilationTest.java 8181831 generic-all diff -r e47423f1318b -r ca19b94eac7a test/hotspot/jtreg/compiler/escapeAnalysis/TestSelfArrayCopy.java --- a/test/hotspot/jtreg/compiler/escapeAnalysis/TestSelfArrayCopy.java Mon Sep 23 09:16:05 2019 -0700 +++ b/test/hotspot/jtreg/compiler/escapeAnalysis/TestSelfArrayCopy.java Wed Sep 25 22:40:41 2019 +0200 @@ -23,7 +23,7 @@ /* * @test - * @bug 8229016 + * @bug 8229016 8231055 * @summary Test correct elimination of array allocation with arraycopy to itself. * @library /test/lib * @run main/othervm -Xbatch -XX:CompileCommand=compileonly,compiler.escapeAnalysis.TestSelfArrayCopy::test @@ -39,7 +39,7 @@ private static final int rI1 = Utils.getRandomInstance().nextInt(); private static final int rI2 = Utils.getRandomInstance().nextInt(); - private static int test() { + private static int test1() { // Non-escaping allocation Integer[] array = {rI1, rI2}; // Arraycopy with src == dst @@ -51,14 +51,40 @@ return array[0] + array[1]; } + private static int test2() { + // Non-escaping allocation + Integer[] array = {rI1, rI2}; + // Arraycopy with src == dst + System.arraycopy(array, 0, array, 1, 1); + if (b) { + // Uncommon trap + System.out.println(array[0]); + } + return array[0] + array[1]; + } + public static void main(String[] args) { - int expected = rI1 + rI2; + int expected1 = rI1 + rI2; + int expected2 = rI1 + rI1; // Trigger compilation for (int i = 0; i < 20_000; ++i) { - int result = test(); - if (result != expected) { - throw new RuntimeException("Incorrect result: " + result + " != " + expected); + int result = test1(); + if (result != expected1) { + throw new RuntimeException("Incorrect result: " + result + " != " + expected1); + } + result = test2(); + if (result != expected2) { + throw new RuntimeException("Incorrect result: " + result + " != " + expected2); } } + b = true; + int result = test1(); + if (result != expected1) { + throw new RuntimeException("Incorrect result: " + result + " != " + expected1); + } + result = test2(); + if (result != expected2) { + throw new RuntimeException("Incorrect result: " + result + " != " + expected2); + } } } diff -r e47423f1318b -r ca19b94eac7a test/hotspot/jtreg/compiler/linkage/TestLinkageErrorInGenerateOopMap.java --- a/test/hotspot/jtreg/compiler/linkage/TestLinkageErrorInGenerateOopMap.java Mon Sep 23 09:16:05 2019 -0700 +++ b/test/hotspot/jtreg/compiler/linkage/TestLinkageErrorInGenerateOopMap.java Wed Sep 25 22:40:41 2019 +0200 @@ -47,6 +47,8 @@ "-XX:-BytecodeVerificationLocal", "-XX:-TieredCompilation", "-XX:CompileCommand=dontinline,compiler/linkage/OSRWithBadOperandStack.m*", + "-XX:-CreateCoredumpOnCrash", + "-Xmx64m", "compiler.linkage.TestLinkageErrorInGenerateOopMap", "run"}; ProcessBuilder pb = ProcessTools.createJavaProcessBuilder(flags); OutputAnalyzer out = new OutputAnalyzer(pb.start()); diff -r e47423f1318b -r ca19b94eac7a test/hotspot/jtreg/compiler/loopstripmining/AntiDependentLoadInOuterStripMinedLoop.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/hotspot/jtreg/compiler/loopstripmining/AntiDependentLoadInOuterStripMinedLoop.java Wed Sep 25 22:40:41 2019 +0200 @@ -0,0 +1,92 @@ +/* + * Copyright (c) 2019, Red Hat, Inc. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/** + * @test + * @bug 8229483 + * @summary Sinking load out of loop may trigger: assert(found_sfpt) failed: no node in loop that's not input to safepoint + * + * @run main/othervm -XX:-TieredCompilation -XX:-BackgroundCompilation -XX:-UseOnStackReplacement -XX:LoopMaxUnroll=0 AntiDependentLoadInOuterStripMinedLoop + * + */ + +public class AntiDependentLoadInOuterStripMinedLoop { + private static int field; + private static volatile int barrier; + + public static void main(String[] args) { + int[] array = new int[1]; + A a = new A(); + for (int i = 0; i < 20_000; i++) { + test1(array); + test2(a, array); + test2_helper(array, 0, 0); + } + } + + private static int test1(int[] array) { + int res = 1; + + for (int i = 0; i < 10; i++) { + barrier = 1; + // field load doesn't float higher than here + + for (int j = 0; j < 2000; j++) { + array[0] = j; // seen as anti dependence by C2 during loop opts, sunk out of loop + res *= j; + } + } + + return field + res + field * 2; + } + + private static int test2(A a, int[] array) { + int ignore = a.field; + int res = 1; + + int k = 0; + for (k = 0; k < 2; k++) { + } + + for (int i = 0; i < 10; i++) { + barrier = 1; + + for (int j = 0; j < 2000; j++) { + test2_helper(array, k, j); + res *= j; + } + } + + return a.field + res + a.field * 2; + } + + private static void test2_helper(int[] array, int k, int j) { + if (k == 2) { + array[0] = j; + } + } + + private static class A { + public int field; + } +} diff -r e47423f1318b -r ca19b94eac7a test/hotspot/jtreg/compiler/loopstripmining/DeadNodesInOuterLoopAtLoopCloning.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/hotspot/jtreg/compiler/loopstripmining/DeadNodesInOuterLoopAtLoopCloning.java Wed Sep 25 22:40:41 2019 +0200 @@ -0,0 +1,84 @@ +/* + * Copyright (c) 2019, Red Hat, Inc. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/** + * @test + * @bug 8230061 + * @summary loop unrolling breaks when outer strip mined loop contains dead node + * + * @run main/othervm -Xmx1G DeadNodesInOuterLoopAtLoopCloning + * + */ + +public class DeadNodesInOuterLoopAtLoopCloning { + + public static final int N = 400; + + public static long instanceCount=-2288355609708559532L; + + public static double checkSum(double[] a) { + double sum = 0; + for (int j = 0; j < a.length; j++) { + sum += (a[j] / (j + 1) + a[j] % (j + 1)); + } + return sum; + } + + public static int iMeth(double d1) { + + int i4=6022, i5=-211, i6=-15841, iArr[]=new int[N]; + double d2=-8.78129, dArr[]=new double[N]; + + i5 = 1; + do { + i6 = 1; + while (++i6 < 5) { + i4 = -933; + i4 *= i4; + dArr[i5 + 1] = i4; + i4 -= i4; + d2 = 1; + do { + iArr[(int)(d2 + 1)] += (int)instanceCount; + try { + i4 = (i4 % -51430); + i4 = (iArr[i6] % 31311); + iArr[i6 + 1] = (24197 / i5); + } catch (ArithmeticException a_e) {} + i4 -= (int)instanceCount; + i4 <<= i5; + i4 &= 12; + } while (++d2 < 1); + } + } while (++i5 < 320); + long meth_res = Double.doubleToLongBits(checkSum(dArr)); + return (int)meth_res; + } + + public static void main(String[] strArr) { + DeadNodesInOuterLoopAtLoopCloning _instance = new DeadNodesInOuterLoopAtLoopCloning(); + for (int i = 0; i < 10 * 320; i++ ) { + _instance.iMeth(0.8522); + } + } +} diff -r e47423f1318b -r ca19b94eac7a test/hotspot/jtreg/gc/g1/TestGCLogMessages.java --- a/test/hotspot/jtreg/gc/g1/TestGCLogMessages.java Mon Sep 23 09:16:05 2019 -0700 +++ b/test/hotspot/jtreg/gc/g1/TestGCLogMessages.java Wed Sep 25 22:40:41 2019 +0200 @@ -128,8 +128,7 @@ new LogMessageWithLevel("CLDG Roots", Level.TRACE), new LogMessageWithLevel("JVMTI Roots", Level.TRACE), new LogMessageWithLevel("CM RefProcessor Roots", Level.TRACE), - new LogMessageWithLevel("Wait For Strong CLD", Level.TRACE), - new LogMessageWithLevel("Weak CLD Roots", Level.TRACE), + new LogMessageWithLevel("Wait For Strong Roots", Level.TRACE), // Redirty Cards new LogMessageWithLevel("Redirty Cards", Level.DEBUG), new LogMessageWithLevel("Parallel Redirty", Level.TRACE), diff -r e47423f1318b -r ca19b94eac7a test/hotspot/jtreg/gc/shenandoah/compiler/TestClone.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/hotspot/jtreg/gc/shenandoah/compiler/TestClone.java Wed Sep 25 22:40:41 2019 +0200 @@ -0,0 +1,239 @@ +/* + * Copyright (c) 2019, Red Hat, Inc. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test TestClone + * @summary Test clone barriers work correctly + * @key gc + * @requires vm.gc.Shenandoah & !vm.graal.enabled + * + * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -Xms1g -Xmx1g + * -XX:+UseShenandoahGC + * TestClone + * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -Xms1g -Xmx1g + * -XX:+UseShenandoahGC + * -Xint + * TestClone + * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -Xms1g -Xmx1g + * -XX:+UseShenandoahGC + * -XX:-TieredCompilation + * TestClone + * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -Xms1g -Xmx1g + * -XX:+UseShenandoahGC + * -XX:TieredStopAtLevel=1 + * TestClone + * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -Xms1g -Xmx1g + * -XX:+UseShenandoahGC + * -XX:TieredStopAtLevel=4 + * TestClone + */ + +/* + * @test TestClone + * @summary Test clone barriers work correctly + * @key gc + * @requires vm.gc.Shenandoah & !vm.graal.enabled + * + * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -Xms1g -Xmx1g + * -XX:+UseShenandoahGC + * -XX:+ShenandoahVerify + * TestClone + * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -Xms1g -Xmx1g + * -XX:+UseShenandoahGC + * -XX:+ShenandoahVerify + * -Xint + * TestClone + * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -Xms1g -Xmx1g + * -XX:+UseShenandoahGC + * -XX:+ShenandoahVerify + * -XX:-TieredCompilation + * TestClone + * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -Xms1g -Xmx1g + * -XX:+UseShenandoahGC + * -XX:+ShenandoahVerify + * -XX:TieredStopAtLevel=1 + * TestClone + * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -Xms1g -Xmx1g + * -XX:+UseShenandoahGC + * -XX:+ShenandoahVerify + * -XX:TieredStopAtLevel=4 + * TestClone + */ + +/* + * @test TestClone + * @summary Test clone barriers work correctly + * @key gc + * @requires vm.gc.Shenandoah & !vm.graal.enabled + * + * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -Xms1g -Xmx1g + * -XX:+UseShenandoahGC -XX:ShenandoahGCHeuristics=aggressive + * TestClone + * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -Xms1g -Xmx1g + * -XX:+UseShenandoahGC -XX:ShenandoahGCHeuristics=aggressive + * -Xint + * TestClone + * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -Xms1g -Xmx1g + * -XX:+UseShenandoahGC -XX:ShenandoahGCHeuristics=aggressive + * -XX:-TieredCompilation + * TestClone + * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -Xms1g -Xmx1g + * -XX:+UseShenandoahGC -XX:ShenandoahGCHeuristics=aggressive + * -XX:TieredStopAtLevel=1 + * TestClone + * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -Xms1g -Xmx1g + * -XX:+UseShenandoahGC -XX:ShenandoahGCHeuristics=aggressive + * -XX:TieredStopAtLevel=4 + * TestClone + */ + +/* + * @test TestClone + * @summary Test clone barriers work correctly + * @key gc + * @requires vm.gc.Shenandoah & !vm.graal.enabled & (vm.bits == "64") + * + * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -Xms1g -Xmx1g + * -XX:-UseCompressedOops + * -XX:+UseShenandoahGC + * TestClone + * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -Xms1g -Xmx1g + * -XX:-UseCompressedOops + * -XX:+UseShenandoahGC + * -Xint + * TestClone + * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -Xms1g -Xmx1g + * -XX:-UseCompressedOops + * -XX:+UseShenandoahGC + * -XX:-TieredCompilation + * TestClone + * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -Xms1g -Xmx1g + * -XX:-UseCompressedOops + * -XX:+UseShenandoahGC + * -XX:TieredStopAtLevel=1 + * TestClone + * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -Xms1g -Xmx1g + * -XX:-UseCompressedOops + * -XX:+UseShenandoahGC + * -XX:TieredStopAtLevel=4 + * TestClone + */ + +/* + * @test TestClone + * @summary Test clone barriers work correctly + * @key gc + * @requires vm.gc.Shenandoah & !vm.graal.enabled & (vm.bits == "64") + * + * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -Xms1g -Xmx1g + * -XX:-UseCompressedOops + * -XX:+UseShenandoahGC + * -XX:+ShenandoahVerify + * TestClone + * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -Xms1g -Xmx1g + * -XX:-UseCompressedOops + * -XX:+UseShenandoahGC + * -XX:+ShenandoahVerify + * -Xint + * TestClone + * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -Xms1g -Xmx1g + * -XX:-UseCompressedOops + * -XX:+UseShenandoahGC + * -XX:+ShenandoahVerify + * -XX:-TieredCompilation + * TestClone + * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -Xms1g -Xmx1g + * -XX:-UseCompressedOops + * -XX:+UseShenandoahGC + * -XX:+ShenandoahVerify + * -XX:TieredStopAtLevel=1 + * TestClone + * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -Xms1g -Xmx1g + * -XX:-UseCompressedOops + * -XX:+UseShenandoahGC + * -XX:+ShenandoahVerify + * -XX:TieredStopAtLevel=4 + * TestClone + */ + +/* + * @test TestClone + * @summary Test clone barriers work correctly + * @key gc + * @requires vm.gc.Shenandoah & !vm.graal.enabled & (vm.bits == "64") + * + * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -Xms1g -Xmx1g + * -XX:-UseCompressedOops + * -XX:+UseShenandoahGC -XX:ShenandoahGCHeuristics=aggressive + * TestClone + * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -Xms1g -Xmx1g + * -XX:-UseCompressedOops + * -XX:+UseShenandoahGC -XX:ShenandoahGCHeuristics=aggressive + * -Xint + * TestClone + * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -Xms1g -Xmx1g + * -XX:-UseCompressedOops + * -XX:+UseShenandoahGC -XX:ShenandoahGCHeuristics=aggressive + * -XX:-TieredCompilation + * TestClone + * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -Xms1g -Xmx1g + * -XX:-UseCompressedOops + * -XX:+UseShenandoahGC -XX:ShenandoahGCHeuristics=aggressive + * -XX:TieredStopAtLevel=1 + * TestClone + * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -Xms1g -Xmx1g + * -XX:-UseCompressedOops + * -XX:+UseShenandoahGC -XX:ShenandoahGCHeuristics=aggressive + * -XX:TieredStopAtLevel=4 + * TestClone + */ + + +public class TestClone { + + public static void main(String[] args) throws Exception { + for (int i = 0; i < 10000; i++) { + Object[] src = new Object[i]; + for (int c = 0; c < src.length; c++) { + src[c] = new Object(); + } + testWith(src); + } + } + + static void testWith(Object[] src) { + Object[] dst = src.clone(); + int srcLen = src.length; + int dstLen = dst.length; + if (srcLen != dstLen) { + throw new IllegalStateException("Lengths do not match: " + srcLen + " vs " + dstLen); + } + for (int c = 0; c < src.length; c++) { + Object s = src[c]; + Object d = dst[c]; + if (s != d) { + throw new IllegalStateException("Elements do not match at " + c + ": " + s + " vs " + d); + } + } + } +} diff -r e47423f1318b -r ca19b94eac7a test/hotspot/jtreg/runtime/CheckUnhandledOops/TestVerifyOops.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/hotspot/jtreg/runtime/CheckUnhandledOops/TestVerifyOops.java Wed Sep 25 22:40:41 2019 +0200 @@ -0,0 +1,36 @@ +/* + * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * @bug 8231058 + * @requires vm.debug & (os.arch != "sparc") & (os.arch != "sparcv9") + * @run main/othervm -XX:+VerifyOops TestVerifyOops + */ + +public class TestVerifyOops { + + public static void main(String[] args) { + System.out.println("Test passed"); + } +} diff -r e47423f1318b -r ca19b94eac7a test/hotspot/jtreg/runtime/InvocationTests/invocationC1Tests.java --- a/test/hotspot/jtreg/runtime/InvocationTests/invocationC1Tests.java Mon Sep 23 09:16:05 2019 -0700 +++ b/test/hotspot/jtreg/runtime/InvocationTests/invocationC1Tests.java Wed Sep 25 22:40:41 2019 +0200 @@ -49,8 +49,9 @@ System.out.println("\nC1 invocation tests, Tests: " + whichTests + ", class file version: " + classFileVersion); ProcessBuilder pb = ProcessTools.createJavaProcessBuilder(false, "-Xmx128M", - "-Xcomp", "-XX:TieredStopAtLevel=1", whichTests, - "--classfile_version=" + classFileVersion); + "-Xcomp", "-XX:TieredStopAtLevel=1", + "--add-exports", "java.base/jdk.internal.org.objectweb.asm=ALL-UNNAMED", + whichTests, "--classfile_version=" + classFileVersion); OutputAnalyzer output = new OutputAnalyzer(pb.start()); try { output.shouldContain("EXECUTION STATUS: PASSED"); diff -r e47423f1318b -r ca19b94eac7a test/hotspot/jtreg/runtime/InvocationTests/invocationGraalTests.java --- a/test/hotspot/jtreg/runtime/InvocationTests/invocationGraalTests.java Mon Sep 23 09:16:05 2019 -0700 +++ b/test/hotspot/jtreg/runtime/InvocationTests/invocationGraalTests.java Wed Sep 25 22:40:41 2019 +0200 @@ -51,6 +51,7 @@ ", class file version: " + classFileVersion); ProcessBuilder pb = ProcessTools.createJavaProcessBuilder(false, "-Xmx128M", "-XX:+UnlockExperimentalVMOptions", "-XX:+EnableJVMCI", "-XX:+UseJVMCICompiler", + "--add-exports", "java.base/jdk.internal.org.objectweb.asm=ALL-UNNAMED", whichTests, "--classfile_version=" + classFileVersion); OutputAnalyzer output = new OutputAnalyzer(pb.start()); try { diff -r e47423f1318b -r ca19b94eac7a test/hotspot/jtreg/runtime/InvocationTests/invokeinterfaceTests.java --- a/test/hotspot/jtreg/runtime/InvocationTests/invokeinterfaceTests.java Mon Sep 23 09:16:05 2019 -0700 +++ b/test/hotspot/jtreg/runtime/InvocationTests/invokeinterfaceTests.java Wed Sep 25 22:40:41 2019 +0200 @@ -48,6 +48,7 @@ System.out.println("\ninvokeinterface invocation tests, option: " + option + ", class file version: " + classFileVersion); ProcessBuilder pb = ProcessTools.createJavaProcessBuilder(false, "-Xmx128M", option, + "--add-exports", "java.base/jdk.internal.org.objectweb.asm=ALL-UNNAMED", "invokeinterface.Generator", "--classfile_version=" + classFileVersion); OutputAnalyzer output = new OutputAnalyzer(pb.start()); try { diff -r e47423f1318b -r ca19b94eac7a test/hotspot/jtreg/runtime/InvocationTests/invokespecialTests.java --- a/test/hotspot/jtreg/runtime/InvocationTests/invokespecialTests.java Mon Sep 23 09:16:05 2019 -0700 +++ b/test/hotspot/jtreg/runtime/InvocationTests/invokespecialTests.java Wed Sep 25 22:40:41 2019 +0200 @@ -47,6 +47,7 @@ System.out.println("\ninvokespecial invocation tests, option: " + option + ", class file version: " + classFileVersion); ProcessBuilder pb = ProcessTools.createJavaProcessBuilder(false, "-Xmx128M", option, + "--add-exports", "java.base/jdk.internal.org.objectweb.asm=ALL-UNNAMED", "invokespecial.Generator", "--classfile_version=" + classFileVersion); OutputAnalyzer output = new OutputAnalyzer(pb.start()); try { diff -r e47423f1318b -r ca19b94eac7a test/hotspot/jtreg/runtime/InvocationTests/invokevirtualTests.java --- a/test/hotspot/jtreg/runtime/InvocationTests/invokevirtualTests.java Mon Sep 23 09:16:05 2019 -0700 +++ b/test/hotspot/jtreg/runtime/InvocationTests/invokevirtualTests.java Wed Sep 25 22:40:41 2019 +0200 @@ -47,6 +47,7 @@ System.out.println("\ninvokevirtual invocation tests, option: " + option + ", class file version: " + classFileVersion); ProcessBuilder pb = ProcessTools.createJavaProcessBuilder(false, "-Xmx128M", option, + "--add-exports", "java.base/jdk.internal.org.objectweb.asm=ALL-UNNAMED", "invokevirtual.Generator", "--classfile_version=" + classFileVersion); OutputAnalyzer output = new OutputAnalyzer(pb.start()); try { diff -r e47423f1318b -r ca19b94eac7a test/hotspot/jtreg/runtime/Unsafe/InternalErrorTest.java --- a/test/hotspot/jtreg/runtime/Unsafe/InternalErrorTest.java Mon Sep 23 09:16:05 2019 -0700 +++ b/test/hotspot/jtreg/runtime/Unsafe/InternalErrorTest.java Wed Sep 25 22:40:41 2019 +0200 @@ -28,6 +28,7 @@ * @summary Check that SIGBUS errors caused by memory accesses in Unsafe_CopyMemory() * and UnsafeCopySwapMemory() get converted to java.lang.InternalError exceptions. * @modules java.base/jdk.internal.misc + * java.base/java.nio:+open * * @library /test/lib * @build sun.hotspot.WhiteBox diff -r e47423f1318b -r ca19b94eac7a test/hotspot/jtreg/runtime/cds/appcds/ParallelLoadTest.java --- a/test/hotspot/jtreg/runtime/cds/appcds/ParallelLoadTest.java Mon Sep 23 09:16:05 2019 -0700 +++ b/test/hotspot/jtreg/runtime/cds/appcds/ParallelLoadTest.java Wed Sep 25 22:40:41 2019 +0200 @@ -33,29 +33,52 @@ * @run driver ParallelLoadTest */ +import java.io.File; + public class ParallelLoadTest { public static final int MAX_CLASSES = 40; + /* For easy stress testing, do this: + + i=0; while jtreg -DParallelLoadTest.app.loops=100 -DParallelLoadTest.boot.loops=100 \ + ParallelLoadTest.java; do i=$(expr $i + 1); echo =====$i; done + + */ + + private static final int APP_LOOPS = Integer.parseInt(System.getProperty("ParallelLoadTest.app.loops", "1")); + private static final int BOOT_LOOPS = Integer.parseInt(System.getProperty("ParallelLoadTest.boot.loops", "1")); + public static void main(String[] args) throws Exception { - JarBuilder.build("parallel_load", getClassList(true)); - String appJar = TestCommon.getTestJar("parallel_load.jar"); - TestCommon.test(appJar, getClassList(false), "ParallelLoad"); + JarBuilder.build("parallel_load_app", "ParallelLoad", "ParallelLoadThread", "ParallelLoadWatchdog"); + JarBuilder.build("parallel_load_classes", getClassList()); + String appJar = TestCommon.getTestJar("parallel_load_app.jar"); + String classesJar = TestCommon.getTestJar("parallel_load_classes.jar"); + + // (1) Load the classes from app class loader + String CP = appJar + File.pathSeparator + classesJar; + TestCommon.testDump(CP, getClassList()); + for (int i = 0; i < APP_LOOPS; i++) { + TestCommon.run("-cp", CP, "ParallelLoad").assertNormalExit(); + } + + // (2) Load the classes from boot class loader + String bootcp = "-Xbootclasspath/a:" + classesJar; + TestCommon.testDump(appJar, getClassList(), bootcp); + for (int i = 0; i < BOOT_LOOPS; i++) { + TestCommon.run(bootcp, "-cp", appJar, + // "-Xlog:class+load=debug", + "ParallelLoad").assertNormalExit(); + } } - private static String[] getClassList(boolean includeWatchdog) { - int extra = includeWatchdog ? 3 : 2; - String[] classList = new String[MAX_CLASSES + extra]; + private static String[] getClassList() { + String[] classList = new String[MAX_CLASSES]; int i; - for (i=0; i 0) { - throw new RuntimeException("test.dynamic.dump not supported empty classpath with non-empty classlist"); + throw new RuntimeException("test.dynamic.dump is not supported with an empty classpath while the classlist is not empty"); } cmd.add("-version"); } @@ -242,7 +242,12 @@ if (opts.appJarDir != null) { pb.directory(new File(opts.appJarDir)); } - return executeAndLog(pb, "dump"); + + OutputAnalyzer output = executeAndLog(pb, "dump"); + if (DYNAMIC_DUMP && isUnableToMap(output)) { + throw new SkippedException(UnableToMapMsg); + } + return output; } // This allows you to run the AppCDS tests with JFR enabled at runtime (though not at @@ -462,9 +467,6 @@ String... suffix) throws Exception { OutputAnalyzer output = dump(appJar, classList, suffix); if (DYNAMIC_DUMP) { - if (isUnableToMap(output)) { - throw new SkippedException(UnableToMapMsg); - } output.shouldContain("Written dynamic archive"); } else { output.shouldContain("Loading classes to share"); @@ -477,9 +479,6 @@ String... suffix) throws Exception { OutputAnalyzer output = dump(appJarDir, appJar, classList, suffix); if (DYNAMIC_DUMP) { - if (isUnableToMap(output)) { - throw new SkippedException(UnableToMapMsg); - } output.shouldContain("Written dynamic archive"); } else { output.shouldContain("Loading classes to share"); diff -r e47423f1318b -r ca19b94eac7a test/hotspot/jtreg/runtime/cds/appcds/test-classes/ParallelLoad.java --- a/test/hotspot/jtreg/runtime/cds/appcds/test-classes/ParallelLoad.java Mon Sep 23 09:16:05 2019 -0700 +++ b/test/hotspot/jtreg/runtime/cds/appcds/test-classes/ParallelLoad.java Wed Sep 25 22:40:41 2019 +0200 @@ -25,6 +25,7 @@ import java.io.*; import java.net.*; import java.lang.reflect.Field; +import java.util.concurrent.atomic.AtomicInteger; // This test helper is parameterized by: @@ -78,7 +79,7 @@ if ("FINGERPRINT_MODE".equals(args[1])) { mode = FINGERPRINT_MODE; classLoaders = new ClassLoader[NUM_THREADS]; - for (int i=0; i timeout + TOLERANCE) { + throw new RuntimeException(String.format( + "elapsed=%s, timeout=%s, TOLERANCE=%s, PREMATURE_RETURN=%s", + elapsed, timeout, TOLERANCE, PREMATURE_RETURN)); + } + + DNSTestUtils.debug(attrs); + + /* Note that the returned attributes are truncated and the response + is not valid. */ + var txtAttr = attrs.get("TXT"); + if (txtAttr == null) + throw new RuntimeException("TXT attribute missing."); + } + + @Override + public void initTest(String[] args) { + /* We need to bind the TCP server on the same port the UDP server is + listening to. This may not be possible if that port is in use. Retry + MAX_RETRIES times relying on UDP port randomness. */ + final int MAX_RETRIES = 5; + for (int i = 0; i < MAX_RETRIES; i++) { + super.initTest(args); + var udpServer = (Server) env().get(DNSTestUtils.TEST_DNS_SERVER_THREAD); + int port = udpServer.getPort(); + try { + tcpDnsServer = new TcpDnsServer(port); + break; // success + } catch (BindException be) { + DNSTestUtils.debug("Failed to bind server socket on port " + port + + ", retry no. " + (i + 1) + ", " + be.getMessage()); + } catch (Exception ex) { + throw new RuntimeException("Unexpected exception during initTest", ex); + } finally { + if (tcpDnsServer == null) { // cleanup behind exceptions + super.cleanupTest(); + } + } + } + + if (tcpDnsServer == null) { + throw new SkippedException("Cannot start TCP server after " + + MAX_RETRIES + + " tries, skip the test"); + } + } + + @Override + public void cleanupTest() { + super.cleanupTest(); + if (tcpDnsServer != null) + tcpDnsServer.stopServer(); + } + + /** + * A TCP server that accepts a connection and does nothing else: causes read + * timeout on client side. + */ + private static class TcpDnsServer { + final ServerSocket serverSocket; + + TcpDnsServer(int port) throws IOException { + serverSocket = new ServerSocket(port, 0, InetAddress.getLoopbackAddress()); + System.out.println("TcpDnsServer: listening on port " + port); + } + + void stopServer() { + try { + if (serverSocket != null) + serverSocket.close(); + } catch (Exception ignored) { } + } + } +} diff -r e47423f1318b -r ca19b94eac7a test/jdk/java/net/httpclient/websocket/Abort.java --- a/test/jdk/java/net/httpclient/websocket/Abort.java Mon Sep 23 09:16:05 2019 -0700 +++ b/test/jdk/java/net/httpclient/websocket/Abort.java Wed Sep 25 22:40:41 2019 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2019, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -29,7 +29,6 @@ * Abort */ -import org.testng.annotations.AfterTest; import org.testng.annotations.Test; import java.io.IOException; @@ -56,38 +55,35 @@ private static final Class IAE = IllegalArgumentException.class; private static final Class IOE = IOException.class; - private DummyWebSocketServer server; - private WebSocket webSocket; - - @AfterTest - public void cleanup() { - server.close(); - webSocket.abort(); - } @Test public void onOpenThenAbort() throws Exception { int[] bytes = new int[]{ 0x88, 0x00, // opcode=close }; - server = Support.serverWithCannedData(bytes); - server.open(); - // messages are available - MockListener listener = new MockListener() { - @Override - protected void onOpen0(WebSocket webSocket) { - // unbounded request - webSocket.request(Long.MAX_VALUE); + try (var server = Support.serverWithCannedData(bytes)) { + server.open(); + // messages are available + MockListener listener = new MockListener() { + @Override + protected void onOpen0(WebSocket webSocket) { + // unbounded request + webSocket.request(Long.MAX_VALUE); + webSocket.abort(); + } + }; + var webSocket = newHttpClient().newWebSocketBuilder() + .buildAsync(server.getURI(), listener) + .join(); + try { + TimeUnit.SECONDS.sleep(5); + List inv = listener.invocationsSoFar(); + // no more invocations after onOpen as WebSocket was aborted + assertEquals(inv, List.of(MockListener.Invocation.onOpen(webSocket))); + } finally { webSocket.abort(); } - }; - webSocket = newHttpClient().newWebSocketBuilder() - .buildAsync(server.getURI(), listener) - .join(); - TimeUnit.SECONDS.sleep(5); - List inv = listener.invocationsSoFar(); - // no more invocations after onOpen as WebSocket was aborted - assertEquals(inv, List.of(MockListener.Invocation.onOpen(webSocket))); + } } @Test @@ -96,33 +92,38 @@ 0x81, 0x00, // opcode=text, fin=true 0x88, 0x00, // opcode=close }; - server = Support.serverWithCannedData(bytes); - server.open(); - MockListener listener = new MockListener() { - @Override - protected void onOpen0(WebSocket webSocket) { - // unbounded request - webSocket.request(Long.MAX_VALUE); - } + try (var server = Support.serverWithCannedData(bytes)) { + server.open(); + MockListener listener = new MockListener() { + @Override + protected void onOpen0(WebSocket webSocket) { + // unbounded request + webSocket.request(Long.MAX_VALUE); + } - @Override - protected CompletionStage onText0(WebSocket webSocket, - CharSequence message, - boolean last) { + @Override + protected CompletionStage onText0(WebSocket webSocket, + CharSequence message, + boolean last) { + webSocket.abort(); + return super.onText0(webSocket, message, last); + } + }; + var webSocket = newHttpClient().newWebSocketBuilder() + .buildAsync(server.getURI(), listener) + .join(); + try { + TimeUnit.SECONDS.sleep(5); + List inv = listener.invocationsSoFar(); + // no more invocations after onOpen, onBinary as WebSocket was aborted + List expected = List.of( + MockListener.Invocation.onOpen(webSocket), + MockListener.Invocation.onText(webSocket, "", true)); + assertEquals(inv, expected); + } finally { webSocket.abort(); - return super.onText0(webSocket, message, last); } - }; - webSocket = newHttpClient().newWebSocketBuilder() - .buildAsync(server.getURI(), listener) - .join(); - TimeUnit.SECONDS.sleep(5); - List inv = listener.invocationsSoFar(); - // no more invocations after onOpen, onBinary as WebSocket was aborted - List expected = List.of( - MockListener.Invocation.onOpen(webSocket), - MockListener.Invocation.onText(webSocket, "", true)); - assertEquals(inv, expected); + } } @Test @@ -131,33 +132,38 @@ 0x82, 0x00, // opcode=binary, fin=true 0x88, 0x00, // opcode=close }; - server = Support.serverWithCannedData(bytes); - server.open(); - MockListener listener = new MockListener() { - @Override - protected void onOpen0(WebSocket webSocket) { - // unbounded request - webSocket.request(Long.MAX_VALUE); - } + try (var server = Support.serverWithCannedData(bytes)) { + server.open(); + MockListener listener = new MockListener() { + @Override + protected void onOpen0(WebSocket webSocket) { + // unbounded request + webSocket.request(Long.MAX_VALUE); + } - @Override - protected CompletionStage onBinary0(WebSocket webSocket, - ByteBuffer message, - boolean last) { + @Override + protected CompletionStage onBinary0(WebSocket webSocket, + ByteBuffer message, + boolean last) { + webSocket.abort(); + return super.onBinary0(webSocket, message, last); + } + }; + var webSocket = newHttpClient().newWebSocketBuilder() + .buildAsync(server.getURI(), listener) + .join(); + try { + TimeUnit.SECONDS.sleep(5); + List inv = listener.invocationsSoFar(); + // no more invocations after onOpen, onBinary as WebSocket was aborted + List expected = List.of( + MockListener.Invocation.onOpen(webSocket), + MockListener.Invocation.onBinary(webSocket, ByteBuffer.allocate(0), true)); + assertEquals(inv, expected); + } finally { webSocket.abort(); - return super.onBinary0(webSocket, message, last); } - }; - webSocket = newHttpClient().newWebSocketBuilder() - .buildAsync(server.getURI(), listener) - .join(); - TimeUnit.SECONDS.sleep(5); - List inv = listener.invocationsSoFar(); - // no more invocations after onOpen, onBinary as WebSocket was aborted - List expected = List.of( - MockListener.Invocation.onOpen(webSocket), - MockListener.Invocation.onBinary(webSocket, ByteBuffer.allocate(0), true)); - assertEquals(inv, expected); + } } @Test @@ -166,32 +172,37 @@ 0x89, 0x00, // opcode=ping 0x88, 0x00, // opcode=close }; - server = Support.serverWithCannedData(bytes); - server.open(); - MockListener listener = new MockListener() { - @Override - protected void onOpen0(WebSocket webSocket) { - // unbounded request - webSocket.request(Long.MAX_VALUE); - } + try (var server = Support.serverWithCannedData(bytes)) { + server.open(); + MockListener listener = new MockListener() { + @Override + protected void onOpen0(WebSocket webSocket) { + // unbounded request + webSocket.request(Long.MAX_VALUE); + } - @Override - protected CompletionStage onPing0(WebSocket webSocket, - ByteBuffer message) { + @Override + protected CompletionStage onPing0(WebSocket webSocket, + ByteBuffer message) { + webSocket.abort(); + return super.onPing0(webSocket, message); + } + }; + var webSocket = newHttpClient().newWebSocketBuilder() + .buildAsync(server.getURI(), listener) + .join(); + try { + TimeUnit.SECONDS.sleep(5); + List inv = listener.invocationsSoFar(); + // no more invocations after onOpen, onPing as WebSocket was aborted + List expected = List.of( + MockListener.Invocation.onOpen(webSocket), + MockListener.Invocation.onPing(webSocket, ByteBuffer.allocate(0))); + assertEquals(inv, expected); + } finally { webSocket.abort(); - return super.onPing0(webSocket, message); } - }; - webSocket = newHttpClient().newWebSocketBuilder() - .buildAsync(server.getURI(), listener) - .join(); - TimeUnit.SECONDS.sleep(5); - List inv = listener.invocationsSoFar(); - // no more invocations after onOpen, onPing as WebSocket was aborted - List expected = List.of( - MockListener.Invocation.onOpen(webSocket), - MockListener.Invocation.onPing(webSocket, ByteBuffer.allocate(0))); - assertEquals(inv, expected); + } } @Test @@ -200,32 +211,37 @@ 0x8a, 0x00, // opcode=pong 0x88, 0x00, // opcode=close }; - server = Support.serverWithCannedData(bytes); - server.open(); - MockListener listener = new MockListener() { - @Override - protected void onOpen0(WebSocket webSocket) { - // unbounded request - webSocket.request(Long.MAX_VALUE); - } + try (var server = Support.serverWithCannedData(bytes)) { + server.open(); + MockListener listener = new MockListener() { + @Override + protected void onOpen0(WebSocket webSocket) { + // unbounded request + webSocket.request(Long.MAX_VALUE); + } - @Override - protected CompletionStage onPong0(WebSocket webSocket, - ByteBuffer message) { + @Override + protected CompletionStage onPong0(WebSocket webSocket, + ByteBuffer message) { + webSocket.abort(); + return super.onPong0(webSocket, message); + } + }; + var webSocket = newHttpClient().newWebSocketBuilder() + .buildAsync(server.getURI(), listener) + .join(); + try { + TimeUnit.SECONDS.sleep(5); + List inv = listener.invocationsSoFar(); + // no more invocations after onOpen, onPong as WebSocket was aborted + List expected = List.of( + MockListener.Invocation.onOpen(webSocket), + MockListener.Invocation.onPong(webSocket, ByteBuffer.allocate(0))); + assertEquals(inv, expected); + } finally { webSocket.abort(); - return super.onPong0(webSocket, message); } - }; - webSocket = newHttpClient().newWebSocketBuilder() - .buildAsync(server.getURI(), listener) - .join(); - TimeUnit.SECONDS.sleep(5); - List inv = listener.invocationsSoFar(); - // no more invocations after onOpen, onPong as WebSocket was aborted - List expected = List.of( - MockListener.Invocation.onOpen(webSocket), - MockListener.Invocation.onPong(webSocket, ByteBuffer.allocate(0))); - assertEquals(inv, expected); + } } @Test @@ -234,33 +250,38 @@ 0x88, 0x00, // opcode=close 0x8a, 0x00, // opcode=pong }; - server = Support.serverWithCannedData(bytes); - server.open(); - MockListener listener = new MockListener() { - @Override - protected void onOpen0(WebSocket webSocket) { - // unbounded request - webSocket.request(Long.MAX_VALUE); - } + try (var server = Support.serverWithCannedData(bytes)) { + server.open(); + MockListener listener = new MockListener() { + @Override + protected void onOpen0(WebSocket webSocket) { + // unbounded request + webSocket.request(Long.MAX_VALUE); + } - @Override - protected CompletionStage onClose0(WebSocket webSocket, - int statusCode, - String reason) { + @Override + protected CompletionStage onClose0(WebSocket webSocket, + int statusCode, + String reason) { + webSocket.abort(); + return super.onClose0(webSocket, statusCode, reason); + } + }; + var webSocket = newHttpClient().newWebSocketBuilder() + .buildAsync(server.getURI(), listener) + .join(); + try { + TimeUnit.SECONDS.sleep(5); + List inv = listener.invocationsSoFar(); + // no more invocations after onOpen, onClose + List expected = List.of( + MockListener.Invocation.onOpen(webSocket), + MockListener.Invocation.onClose(webSocket, 1005, "")); + assertEquals(inv, expected); + } finally { webSocket.abort(); - return super.onClose0(webSocket, statusCode, reason); } - }; - webSocket = newHttpClient().newWebSocketBuilder() - .buildAsync(server.getURI(), listener) - .join(); - TimeUnit.SECONDS.sleep(5); - List inv = listener.invocationsSoFar(); - // no more invocations after onOpen, onClose - List expected = List.of( - MockListener.Invocation.onOpen(webSocket), - MockListener.Invocation.onClose(webSocket, 1005, "")); - assertEquals(inv, expected); + } } @Test @@ -271,32 +292,37 @@ int[] bytes = new int[badPingHeader.length + 128 + closeMessage.length]; System.arraycopy(badPingHeader, 0, bytes, 0, badPingHeader.length); System.arraycopy(closeMessage, 0, bytes, badPingHeader.length + 128, closeMessage.length); - server = Support.serverWithCannedData(bytes); - server.open(); - MockListener listener = new MockListener() { - @Override - protected void onOpen0(WebSocket webSocket) { - // unbounded request - webSocket.request(Long.MAX_VALUE); - } + try (var server = Support.serverWithCannedData(bytes)) { + server.open(); + MockListener listener = new MockListener() { + @Override + protected void onOpen0(WebSocket webSocket) { + // unbounded request + webSocket.request(Long.MAX_VALUE); + } - @Override - protected void onError0(WebSocket webSocket, Throwable error) { + @Override + protected void onError0(WebSocket webSocket, Throwable error) { + webSocket.abort(); + super.onError0(webSocket, error); + } + }; + var webSocket = newHttpClient().newWebSocketBuilder() + .buildAsync(server.getURI(), listener) + .join(); + try { + TimeUnit.SECONDS.sleep(5); + List inv = listener.invocationsSoFar(); + // no more invocations after onOpen, onError + List expected = List.of( + MockListener.Invocation.onOpen(webSocket), + MockListener.Invocation.onError(webSocket, ProtocolException.class)); + System.out.println("actual invocations:" + Arrays.toString(inv.toArray())); + assertEquals(inv, expected); + } finally { webSocket.abort(); - super.onError0(webSocket, error); } - }; - webSocket = newHttpClient().newWebSocketBuilder() - .buildAsync(server.getURI(), listener) - .join(); - TimeUnit.SECONDS.sleep(5); - List inv = listener.invocationsSoFar(); - // no more invocations after onOpen, onError - List expected = List.of( - MockListener.Invocation.onOpen(webSocket), - MockListener.Invocation.onError(webSocket, ProtocolException.class)); - System.out.println("actual invocations:" + Arrays.toString(inv.toArray())); - assertEquals(inv, expected); + } } @Test @@ -352,65 +378,70 @@ 0x82, 0x00, // opcode=binary, fin=true 0x88, 0x00, // opcode=close }; - server = Support.serverWithCannedData(bytes); - server.open(); + try (var server = Support.serverWithCannedData(bytes)) { + server.open(); - WebSocket ws = newHttpClient() - .newWebSocketBuilder() - .buildAsync(server.getURI(), listener) - .join(); - for (int i = 0; i < 3; i++) { - System.out.printf("iteration #%s%n", i); - // after the first abort() each consecutive one must be a no-op, - // moreover, query methods should continue to return consistent - // values - for (int j = 0; j < 3; j++) { - System.out.printf("abort #%s%n", j); + WebSocket ws = newHttpClient() + .newWebSocketBuilder() + .buildAsync(server.getURI(), listener) + .join(); + try { + for (int i = 0; i < 3; i++) { + System.out.printf("iteration #%s%n", i); + // after the first abort() each consecutive one must be a no-op, + // moreover, query methods should continue to return consistent + // values + for (int j = 0; j < 3; j++) { + System.out.printf("abort #%s%n", j); + ws.abort(); + assertTrue(ws.isInputClosed()); + assertTrue(ws.isOutputClosed()); + assertEquals(ws.getSubprotocol(), ""); + } + // at this point valid requests MUST be a no-op: + for (int j = 0; j < 3; j++) { + System.out.printf("request #%s%n", j); + ws.request(1); + ws.request(2); + ws.request(8); + ws.request(Integer.MAX_VALUE); + ws.request(Long.MAX_VALUE); + // invalid requests MUST throw IAE: + assertThrows(IAE, () -> ws.request(Integer.MIN_VALUE)); + assertThrows(IAE, () -> ws.request(Long.MIN_VALUE)); + assertThrows(IAE, () -> ws.request(-1)); + assertThrows(IAE, () -> ws.request(0)); + } + } + // even though there is a bunch of messages readily available on the + // wire we shouldn't have received any of them as we aborted before + // the first request + try { + messageReceived.get(5, TimeUnit.SECONDS); + fail(); + } catch (TimeoutException expected) { + System.out.println("Finished waiting"); + } + for (int i = 0; i < 3; i++) { + System.out.printf("send #%s%n", i); + Support.assertFails(IOE, ws.sendText("text!", false)); + Support.assertFails(IOE, ws.sendText("text!", true)); + Support.assertFails(IOE, ws.sendBinary(ByteBuffer.allocate(16), false)); + Support.assertFails(IOE, ws.sendBinary(ByteBuffer.allocate(16), true)); + Support.assertFails(IOE, ws.sendPing(ByteBuffer.allocate(16))); + Support.assertFails(IOE, ws.sendPong(ByteBuffer.allocate(16))); + Support.assertFails(IOE, ws.sendClose(NORMAL_CLOSURE, "a reason")); + assertThrows(NPE, () -> ws.sendText(null, false)); + assertThrows(NPE, () -> ws.sendText(null, true)); + assertThrows(NPE, () -> ws.sendBinary(null, false)); + assertThrows(NPE, () -> ws.sendBinary(null, true)); + assertThrows(NPE, () -> ws.sendPing(null)); + assertThrows(NPE, () -> ws.sendPong(null)); + assertThrows(NPE, () -> ws.sendClose(NORMAL_CLOSURE, null)); + } + } finally { ws.abort(); - assertTrue(ws.isInputClosed()); - assertTrue(ws.isOutputClosed()); - assertEquals(ws.getSubprotocol(), ""); } - // at this point valid requests MUST be a no-op: - for (int j = 0; j < 3; j++) { - System.out.printf("request #%s%n", j); - ws.request(1); - ws.request(2); - ws.request(8); - ws.request(Integer.MAX_VALUE); - ws.request(Long.MAX_VALUE); - // invalid requests MUST throw IAE: - assertThrows(IAE, () -> ws.request(Integer.MIN_VALUE)); - assertThrows(IAE, () -> ws.request(Long.MIN_VALUE)); - assertThrows(IAE, () -> ws.request(-1)); - assertThrows(IAE, () -> ws.request(0)); - } - } - // even though there is a bunch of messages readily available on the - // wire we shouldn't have received any of them as we aborted before - // the first request - try { - messageReceived.get(5, TimeUnit.SECONDS); - fail(); - } catch (TimeoutException expected) { - System.out.println("Finished waiting"); - } - for (int i = 0; i < 3; i++) { - System.out.printf("send #%s%n", i); - Support.assertFails(IOE, ws.sendText("text!", false)); - Support.assertFails(IOE, ws.sendText("text!", true)); - Support.assertFails(IOE, ws.sendBinary(ByteBuffer.allocate(16), false)); - Support.assertFails(IOE, ws.sendBinary(ByteBuffer.allocate(16), true)); - Support.assertFails(IOE, ws.sendPing(ByteBuffer.allocate(16))); - Support.assertFails(IOE, ws.sendPong(ByteBuffer.allocate(16))); - Support.assertFails(IOE, ws.sendClose(NORMAL_CLOSURE, "a reason")); - assertThrows(NPE, () -> ws.sendText(null, false)); - assertThrows(NPE, () -> ws.sendText(null, true)); - assertThrows(NPE, () -> ws.sendBinary(null, false)); - assertThrows(NPE, () -> ws.sendBinary(null, true)); - assertThrows(NPE, () -> ws.sendPing(null)); - assertThrows(NPE, () -> ws.sendPong(null)); - assertThrows(NPE, () -> ws.sendClose(NORMAL_CLOSURE, null)); } } } diff -r e47423f1318b -r ca19b94eac7a test/jdk/java/net/httpclient/websocket/AutomaticPong.java --- a/test/jdk/java/net/httpclient/websocket/AutomaticPong.java Mon Sep 23 09:16:05 2019 -0700 +++ b/test/jdk/java/net/httpclient/websocket/AutomaticPong.java Wed Sep 25 22:40:41 2019 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2019, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -28,8 +28,6 @@ * -Djdk.internal.httpclient.websocket.debug=true * AutomaticPong */ - -import org.testng.annotations.AfterTest; import org.testng.annotations.DataProvider; import org.testng.annotations.Test; @@ -46,16 +44,6 @@ import static org.testng.Assert.fail; public class AutomaticPong { - - private DummyWebSocketServer server; - private WebSocket webSocket; - - @AfterTest - public void cleanup() { - server.close(); - webSocket.abort(); - } - /* * The sendClose method has been invoked and a Ping comes from the server. * Naturally, the client cannot reply with a Pong (the output has been @@ -72,32 +60,36 @@ 0x89, 0x06, 0x68, 0x65, 0x6c, 0x6c, 0x6f, 0x3f, // ping hello? 0x88, 0x00, // close }; - server = Support.serverWithCannedData(bytes); - server.open(); - MockListener listener = new MockListener() { - @Override - protected void onOpen0(WebSocket webSocket) { - /* request nothing */ + try (var server = Support.serverWithCannedData(bytes)) { + server.open(); + MockListener listener = new MockListener() { + @Override + protected void onOpen0(WebSocket webSocket) { + /* request nothing */ + } + }; + var webSocket = newHttpClient() + .newWebSocketBuilder() + .buildAsync(server.getURI(), listener) + .join(); + try { + webSocket.sendClose(WebSocket.NORMAL_CLOSURE, "ok").join(); + // now request all messages available + webSocket.request(Long.MAX_VALUE); + List actual = listener.invocations(); + ByteBuffer hello = ByteBuffer.wrap("hello?".getBytes(StandardCharsets.UTF_8)); + ByteBuffer empty = ByteBuffer.allocate(0); + List expected = List.of( + MockListener.Invocation.onOpen(webSocket), + MockListener.Invocation.onPing(webSocket, empty), + MockListener.Invocation.onPing(webSocket, hello), + MockListener.Invocation.onClose(webSocket, 1005, "") + ); + assertEquals(actual, expected); + } finally { + webSocket.abort(); } - }; - webSocket = newHttpClient() - .newWebSocketBuilder() - .buildAsync(server.getURI(), listener) - .join(); - - webSocket.sendClose(WebSocket.NORMAL_CLOSURE, "ok").join(); - // now request all messages available - webSocket.request(Long.MAX_VALUE); - List actual = listener.invocations(); - ByteBuffer hello = ByteBuffer.wrap("hello?".getBytes(StandardCharsets.UTF_8)); - ByteBuffer empty = ByteBuffer.allocate(0); - List expected = List.of( - MockListener.Invocation.onOpen(webSocket), - MockListener.Invocation.onPing(webSocket, empty), - MockListener.Invocation.onPing(webSocket, hello), - MockListener.Invocation.onClose(webSocket, 1005, "") - ); - assertEquals(actual, expected); + } } /* @@ -131,84 +123,100 @@ .write(buffer); buffer.putChar((char) 1000); buffer.flip(); - server = Support.serverWithCannedData(buffer.array()); - server.open(); - MockListener listener = new MockListener(); - webSocket = newHttpClient() - .newWebSocketBuilder() - .buildAsync(server.getURI(), listener) - .join(); - List inv = listener.invocations(); - assertEquals(inv.size(), nPings + 2); // n * onPing + onOpen + onClose + try (var server = Support.serverWithCannedData(buffer.array())) { + server.open(); + MockListener listener = new MockListener(); + var webSocket = newHttpClient() + .newWebSocketBuilder() + .buildAsync(server.getURI(), listener) + .join(); + try { + List inv = listener.invocations(); + assertEquals(inv.size(), nPings + 2); // n * onPing + onOpen + onClose + + ByteBuffer data = server.read(); + Frame.Reader reader = new Frame.Reader(); + + Frame.Consumer consumer = new Frame.Consumer() { - ByteBuffer data = server.read(); - Frame.Reader reader = new Frame.Reader(); + ByteBuffer number = ByteBuffer.allocate(4); + Frame.Masker masker = new Frame.Masker(); + int i = -1; + boolean closed; + + @Override + public void fin(boolean value) { + assertTrue(value); + } - Frame.Consumer consumer = new Frame.Consumer() { + @Override + public void rsv1(boolean value) { + assertFalse(value); + } + + @Override + public void rsv2(boolean value) { + assertFalse(value); + } + + @Override + public void rsv3(boolean value) { + assertFalse(value); + } - ByteBuffer number = ByteBuffer.allocate(4); - Frame.Masker masker = new Frame.Masker(); - int i = -1; - boolean closed; + @Override + public void opcode(Frame.Opcode value) { + if (value == Frame.Opcode.CLOSE) { + closed = true; + return; + } + assertEquals(value, Frame.Opcode.PONG); + } - @Override - public void fin(boolean value) { assertTrue(value); } + @Override + public void mask(boolean value) { + assertTrue(value); + } - @Override - public void rsv1(boolean value) { assertFalse(value); } + @Override + public void payloadLen(long value) { + if (!closed) + assertEquals(value, 4); + } + + @Override + public void maskingKey(int value) { + masker.mask(value); + } - @Override - public void rsv2(boolean value) { assertFalse(value); } - - @Override - public void rsv3(boolean value) { assertFalse(value); } + @Override + public void payloadData(ByteBuffer src) { + masker.transferMasking(src, number); + if (closed) { + return; + } + number.flip(); + int n = number.getInt(); + System.out.printf("pong number=%s%n", n); + number.clear(); + // a Pong with the number less than the maximum of Pongs already + // received MUST never be received + if (i >= n) { + fail(String.format("i=%s, n=%s", i, n)); + } + i = n; + } - @Override - public void opcode(Frame.Opcode value) { - if (value == Frame.Opcode.CLOSE) { - closed = true; - return; + @Override + public void endFrame() { + } + }; + while (data.hasRemaining()) { + reader.readFrame(data, consumer); } - assertEquals(value, Frame.Opcode.PONG); - } - - @Override - public void mask(boolean value) { assertTrue(value); } - - @Override - public void payloadLen(long value) { - if (!closed) - assertEquals(value, 4); - } - - @Override - public void maskingKey(int value) { - masker.mask(value); + } finally { + webSocket.abort(); } - - @Override - public void payloadData(ByteBuffer src) { - masker.transferMasking(src, number); - if (closed) { - return; - } - number.flip(); - int n = number.getInt(); - System.out.printf("pong number=%s%n", n); - number.clear(); - // a Pong with the number less than the maximum of Pongs already - // received MUST never be received - if (i >= n) { - fail(String.format("i=%s, n=%s", i, n)); - } - i = n; - } - - @Override - public void endFrame() { } - }; - while (data.hasRemaining()) { - reader.readFrame(data, consumer); } } diff -r e47423f1318b -r ca19b94eac7a test/jdk/java/net/httpclient/websocket/SendTest.java --- a/test/jdk/java/net/httpclient/websocket/SendTest.java Mon Sep 23 09:16:05 2019 -0700 +++ b/test/jdk/java/net/httpclient/websocket/SendTest.java Wed Sep 25 22:40:41 2019 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2019, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -29,7 +29,6 @@ * SendTest */ -import org.testng.annotations.AfterTest; import org.testng.annotations.Test; import java.io.IOException; @@ -46,40 +45,35 @@ private static final Class NPE = NullPointerException.class; - private DummyWebSocketServer server; - private WebSocket webSocket; - - @AfterTest - public void cleanup() { - server.close(); - webSocket.abort(); - } - @Test public void sendMethodsThrowNPE() throws IOException { - server = new DummyWebSocketServer(); - server.open(); - webSocket = newBuilder().proxy(NO_PROXY).build().newWebSocketBuilder() - .buildAsync(server.getURI(), new WebSocket.Listener() { }) - .join(); + try (var server = new DummyWebSocketServer()) { + server.open(); + var webSocket = newBuilder().proxy(NO_PROXY).build().newWebSocketBuilder() + .buildAsync(server.getURI(), new WebSocket.Listener() { }) + .join(); + try { + assertThrows(NPE, () -> webSocket.sendText(null, false)); + assertThrows(NPE, () -> webSocket.sendText(null, true)); + assertThrows(NPE, () -> webSocket.sendBinary(null, false)); + assertThrows(NPE, () -> webSocket.sendBinary(null, true)); + assertThrows(NPE, () -> webSocket.sendPing(null)); + assertThrows(NPE, () -> webSocket.sendPong(null)); + assertThrows(NPE, () -> webSocket.sendClose(NORMAL_CLOSURE, null)); - assertThrows(NPE, () -> webSocket.sendText(null, false)); - assertThrows(NPE, () -> webSocket.sendText(null, true)); - assertThrows(NPE, () -> webSocket.sendBinary(null, false)); - assertThrows(NPE, () -> webSocket.sendBinary(null, true)); - assertThrows(NPE, () -> webSocket.sendPing(null)); - assertThrows(NPE, () -> webSocket.sendPong(null)); - assertThrows(NPE, () -> webSocket.sendClose(NORMAL_CLOSURE, null)); + webSocket.abort(); - webSocket.abort(); - - assertThrows(NPE, () -> webSocket.sendText(null, false)); - assertThrows(NPE, () -> webSocket.sendText(null, true)); - assertThrows(NPE, () -> webSocket.sendBinary(null, false)); - assertThrows(NPE, () -> webSocket.sendBinary(null, true)); - assertThrows(NPE, () -> webSocket.sendPing(null)); - assertThrows(NPE, () -> webSocket.sendPong(null)); - assertThrows(NPE, () -> webSocket.sendClose(NORMAL_CLOSURE, null)); + assertThrows(NPE, () -> webSocket.sendText(null, false)); + assertThrows(NPE, () -> webSocket.sendText(null, true)); + assertThrows(NPE, () -> webSocket.sendBinary(null, false)); + assertThrows(NPE, () -> webSocket.sendBinary(null, true)); + assertThrows(NPE, () -> webSocket.sendPing(null)); + assertThrows(NPE, () -> webSocket.sendPong(null)); + assertThrows(NPE, () -> webSocket.sendClose(NORMAL_CLOSURE, null)); + } finally { + webSocket.abort(); + } + } } // TODO: request in onClose/onError @@ -88,14 +82,20 @@ @Test public void sendCloseCompleted() throws IOException { - server = new DummyWebSocketServer(); - server.open(); - webSocket = newBuilder().proxy(NO_PROXY).build().newWebSocketBuilder() - .buildAsync(server.getURI(), new WebSocket.Listener() { }) - .join(); - webSocket.sendClose(NORMAL_CLOSURE, "").join(); - assertTrue(webSocket.isOutputClosed()); - assertEquals(webSocket.getSubprotocol(), ""); - webSocket.request(1); // No exceptions must be thrown + try (var server = new DummyWebSocketServer()) { + server.open(); + var webSocket = newBuilder().proxy(NO_PROXY).build().newWebSocketBuilder() + .buildAsync(server.getURI(), new WebSocket.Listener() { }) + .join(); + try { + webSocket.sendClose(NORMAL_CLOSURE, "").join(); + assertTrue(webSocket.isOutputClosed()); + assertEquals(webSocket.getSubprotocol(), ""); + webSocket.request(1); // No exceptions must be thrown + } finally { + webSocket.abort(); + } + } } } + diff -r e47423f1318b -r ca19b94eac7a test/jdk/java/net/httpclient/websocket/WebSocketTest.java --- a/test/jdk/java/net/httpclient/websocket/WebSocketTest.java Mon Sep 23 09:16:05 2019 -0700 +++ b/test/jdk/java/net/httpclient/websocket/WebSocketTest.java Wed Sep 25 22:40:41 2019 +0200 @@ -29,7 +29,6 @@ * WebSocketTest */ -import org.testng.annotations.AfterTest; import org.testng.annotations.DataProvider; import org.testng.annotations.Test; @@ -73,150 +72,150 @@ Support.assertCompletesExceptionally(clazz, stage); } - private DummyWebSocketServer server; - private WebSocket webSocket; - - @AfterTest - public void cleanup() { - System.out.println("AFTER TEST"); - if (server != null) - server.close(); - if (webSocket != null) - webSocket.abort(); - } - @Test public void illegalArgument() throws IOException { - server = new DummyWebSocketServer(); - server.open(); - webSocket = newBuilder().proxy(NO_PROXY).build() - .newWebSocketBuilder() - .buildAsync(server.getURI(), new WebSocket.Listener() { }) - .join(); + try (var server = new DummyWebSocketServer()) { + server.open(); + var webSocket = newBuilder().proxy(NO_PROXY).build() + .newWebSocketBuilder() + .buildAsync(server.getURI(), new WebSocket.Listener() { }) + .join(); + try { + assertFails(IAE, webSocket.sendPing(ByteBuffer.allocate(126))); + assertFails(IAE, webSocket.sendPing(ByteBuffer.allocate(127))); + assertFails(IAE, webSocket.sendPing(ByteBuffer.allocate(128))); + assertFails(IAE, webSocket.sendPing(ByteBuffer.allocate(129))); + assertFails(IAE, webSocket.sendPing(ByteBuffer.allocate(256))); - assertFails(IAE, webSocket.sendPing(ByteBuffer.allocate(126))); - assertFails(IAE, webSocket.sendPing(ByteBuffer.allocate(127))); - assertFails(IAE, webSocket.sendPing(ByteBuffer.allocate(128))); - assertFails(IAE, webSocket.sendPing(ByteBuffer.allocate(129))); - assertFails(IAE, webSocket.sendPing(ByteBuffer.allocate(256))); + assertFails(IAE, webSocket.sendPong(ByteBuffer.allocate(126))); + assertFails(IAE, webSocket.sendPong(ByteBuffer.allocate(127))); + assertFails(IAE, webSocket.sendPong(ByteBuffer.allocate(128))); + assertFails(IAE, webSocket.sendPong(ByteBuffer.allocate(129))); + assertFails(IAE, webSocket.sendPong(ByteBuffer.allocate(256))); - assertFails(IAE, webSocket.sendPong(ByteBuffer.allocate(126))); - assertFails(IAE, webSocket.sendPong(ByteBuffer.allocate(127))); - assertFails(IAE, webSocket.sendPong(ByteBuffer.allocate(128))); - assertFails(IAE, webSocket.sendPong(ByteBuffer.allocate(129))); - assertFails(IAE, webSocket.sendPong(ByteBuffer.allocate(256))); + assertFails(IOE, webSocket.sendText(Support.incompleteString(), true)); + assertFails(IOE, webSocket.sendText(Support.incompleteString(), false)); + assertFails(IOE, webSocket.sendText(Support.malformedString(), true)); + assertFails(IOE, webSocket.sendText(Support.malformedString(), false)); - assertFails(IOE, webSocket.sendText(Support.incompleteString(), true)); - assertFails(IOE, webSocket.sendText(Support.incompleteString(), false)); - assertFails(IOE, webSocket.sendText(Support.malformedString(), true)); - assertFails(IOE, webSocket.sendText(Support.malformedString(), false)); + assertFails(IAE, webSocket.sendClose(NORMAL_CLOSURE, Support.stringWithNBytes(124))); + assertFails(IAE, webSocket.sendClose(NORMAL_CLOSURE, Support.stringWithNBytes(125))); + assertFails(IAE, webSocket.sendClose(NORMAL_CLOSURE, Support.stringWithNBytes(128))); + assertFails(IAE, webSocket.sendClose(NORMAL_CLOSURE, Support.stringWithNBytes(256))); + assertFails(IAE, webSocket.sendClose(NORMAL_CLOSURE, Support.stringWithNBytes(257))); + assertFails(IAE, webSocket.sendClose(NORMAL_CLOSURE, Support.stringWith2NBytes((123 / 2) + 1))); + assertFails(IAE, webSocket.sendClose(NORMAL_CLOSURE, Support.malformedString())); + assertFails(IAE, webSocket.sendClose(NORMAL_CLOSURE, Support.incompleteString())); - assertFails(IAE, webSocket.sendClose(NORMAL_CLOSURE, Support.stringWithNBytes(124))); - assertFails(IAE, webSocket.sendClose(NORMAL_CLOSURE, Support.stringWithNBytes(125))); - assertFails(IAE, webSocket.sendClose(NORMAL_CLOSURE, Support.stringWithNBytes(128))); - assertFails(IAE, webSocket.sendClose(NORMAL_CLOSURE, Support.stringWithNBytes(256))); - assertFails(IAE, webSocket.sendClose(NORMAL_CLOSURE, Support.stringWithNBytes(257))); - assertFails(IAE, webSocket.sendClose(NORMAL_CLOSURE, Support.stringWith2NBytes((123 / 2) + 1))); - assertFails(IAE, webSocket.sendClose(NORMAL_CLOSURE, Support.malformedString())); - assertFails(IAE, webSocket.sendClose(NORMAL_CLOSURE, Support.incompleteString())); + assertFails(IAE, webSocket.sendClose(-2, "a reason")); + assertFails(IAE, webSocket.sendClose(-1, "a reason")); + assertFails(IAE, webSocket.sendClose(0, "a reason")); + assertFails(IAE, webSocket.sendClose(1, "a reason")); + assertFails(IAE, webSocket.sendClose(500, "a reason")); + assertFails(IAE, webSocket.sendClose(998, "a reason")); + assertFails(IAE, webSocket.sendClose(999, "a reason")); + assertFails(IAE, webSocket.sendClose(1002, "a reason")); + assertFails(IAE, webSocket.sendClose(1003, "a reason")); + assertFails(IAE, webSocket.sendClose(1006, "a reason")); + assertFails(IAE, webSocket.sendClose(1007, "a reason")); + assertFails(IAE, webSocket.sendClose(1009, "a reason")); + assertFails(IAE, webSocket.sendClose(1010, "a reason")); + assertFails(IAE, webSocket.sendClose(1012, "a reason")); + assertFails(IAE, webSocket.sendClose(1013, "a reason")); + assertFails(IAE, webSocket.sendClose(1015, "a reason")); + assertFails(IAE, webSocket.sendClose(5000, "a reason")); + assertFails(IAE, webSocket.sendClose(32768, "a reason")); + assertFails(IAE, webSocket.sendClose(65535, "a reason")); + assertFails(IAE, webSocket.sendClose(65536, "a reason")); + assertFails(IAE, webSocket.sendClose(Integer.MAX_VALUE, "a reason")); + assertFails(IAE, webSocket.sendClose(Integer.MIN_VALUE, "a reason")); - assertFails(IAE, webSocket.sendClose(-2, "a reason")); - assertFails(IAE, webSocket.sendClose(-1, "a reason")); - assertFails(IAE, webSocket.sendClose(0, "a reason")); - assertFails(IAE, webSocket.sendClose(1, "a reason")); - assertFails(IAE, webSocket.sendClose(500, "a reason")); - assertFails(IAE, webSocket.sendClose(998, "a reason")); - assertFails(IAE, webSocket.sendClose(999, "a reason")); - assertFails(IAE, webSocket.sendClose(1002, "a reason")); - assertFails(IAE, webSocket.sendClose(1003, "a reason")); - assertFails(IAE, webSocket.sendClose(1006, "a reason")); - assertFails(IAE, webSocket.sendClose(1007, "a reason")); - assertFails(IAE, webSocket.sendClose(1009, "a reason")); - assertFails(IAE, webSocket.sendClose(1010, "a reason")); - assertFails(IAE, webSocket.sendClose(1012, "a reason")); - assertFails(IAE, webSocket.sendClose(1013, "a reason")); - assertFails(IAE, webSocket.sendClose(1015, "a reason")); - assertFails(IAE, webSocket.sendClose(5000, "a reason")); - assertFails(IAE, webSocket.sendClose(32768, "a reason")); - assertFails(IAE, webSocket.sendClose(65535, "a reason")); - assertFails(IAE, webSocket.sendClose(65536, "a reason")); - assertFails(IAE, webSocket.sendClose(Integer.MAX_VALUE, "a reason")); - assertFails(IAE, webSocket.sendClose(Integer.MIN_VALUE, "a reason")); + assertThrows(IAE, () -> webSocket.request(Integer.MIN_VALUE)); + assertThrows(IAE, () -> webSocket.request(Long.MIN_VALUE)); + assertThrows(IAE, () -> webSocket.request(-1)); + assertThrows(IAE, () -> webSocket.request(0)); - assertThrows(IAE, () -> webSocket.request(Integer.MIN_VALUE)); - assertThrows(IAE, () -> webSocket.request(Long.MIN_VALUE)); - assertThrows(IAE, () -> webSocket.request(-1)); - assertThrows(IAE, () -> webSocket.request(0)); - - server.close(); + } finally { + webSocket.abort(); + } + } } @Test public void partialBinaryThenText() throws IOException { - server = new DummyWebSocketServer(); - server.open(); - webSocket = newBuilder().proxy(NO_PROXY).build().newWebSocketBuilder() - .buildAsync(server.getURI(), new WebSocket.Listener() { }) - .join(); - webSocket.sendBinary(ByteBuffer.allocate(16), false).join(); - assertFails(ISE, webSocket.sendText("text", false)); - assertFails(ISE, webSocket.sendText("text", true)); - // Pings & Pongs are fine - webSocket.sendPing(ByteBuffer.allocate(125)).join(); - webSocket.sendPong(ByteBuffer.allocate(125)).join(); - server.close(); + try (var server = new DummyWebSocketServer()) { + server.open(); + var webSocket = newBuilder().proxy(NO_PROXY).build().newWebSocketBuilder() + .buildAsync(server.getURI(), new WebSocket.Listener() { }) + .join(); + try { + webSocket.sendBinary(ByteBuffer.allocate(16), false).join(); + assertFails(ISE, webSocket.sendText("text", false)); + assertFails(ISE, webSocket.sendText("text", true)); + // Pings & Pongs are fine + webSocket.sendPing(ByteBuffer.allocate(125)).join(); + webSocket.sendPong(ByteBuffer.allocate(125)).join(); + } finally { + webSocket.abort(); + } + } } @Test public void partialTextThenBinary() throws IOException { - server = new DummyWebSocketServer(); - server.open(); - webSocket = newBuilder().proxy(NO_PROXY).build().newWebSocketBuilder() - .buildAsync(server.getURI(), new WebSocket.Listener() { }) - .join(); - - webSocket.sendText("text", false).join(); - assertFails(ISE, webSocket.sendBinary(ByteBuffer.allocate(16), false)); - assertFails(ISE, webSocket.sendBinary(ByteBuffer.allocate(16), true)); - // Pings & Pongs are fine - webSocket.sendPing(ByteBuffer.allocate(125)).join(); - webSocket.sendPong(ByteBuffer.allocate(125)).join(); - server.close(); + try (var server = new DummyWebSocketServer()) { + server.open(); + var webSocket = newBuilder().proxy(NO_PROXY).build().newWebSocketBuilder() + .buildAsync(server.getURI(), new WebSocket.Listener() { }) + .join(); + try { + webSocket.sendText("text", false).join(); + assertFails(ISE, webSocket.sendBinary(ByteBuffer.allocate(16), false)); + assertFails(ISE, webSocket.sendBinary(ByteBuffer.allocate(16), true)); + // Pings & Pongs are fine + webSocket.sendPing(ByteBuffer.allocate(125)).join(); + webSocket.sendPong(ByteBuffer.allocate(125)).join(); + } finally { + webSocket.abort(); + } + } } @Test public void sendMethodsThrowIOE1() throws IOException { - server = new DummyWebSocketServer(); - server.open(); - webSocket = newBuilder().proxy(NO_PROXY).build() - .newWebSocketBuilder() - .buildAsync(server.getURI(), new WebSocket.Listener() { }) - .join(); + try (var server = new DummyWebSocketServer()) { + server.open(); + var webSocket = newBuilder().proxy(NO_PROXY).build() + .newWebSocketBuilder() + .buildAsync(server.getURI(), new WebSocket.Listener() { }) + .join(); + try { + webSocket.sendClose(NORMAL_CLOSURE, "ok").join(); - webSocket.sendClose(NORMAL_CLOSURE, "ok").join(); - - assertFails(IOE, webSocket.sendClose(WebSocket.NORMAL_CLOSURE, "ok")); + assertFails(IOE, webSocket.sendClose(WebSocket.NORMAL_CLOSURE, "ok")); - assertFails(IOE, webSocket.sendText("", true)); - assertFails(IOE, webSocket.sendText("", false)); - assertFails(IOE, webSocket.sendText("abc", true)); - assertFails(IOE, webSocket.sendText("abc", false)); - assertFails(IOE, webSocket.sendBinary(ByteBuffer.allocate(0), true)); - assertFails(IOE, webSocket.sendBinary(ByteBuffer.allocate(0), false)); - assertFails(IOE, webSocket.sendBinary(ByteBuffer.allocate(1), true)); - assertFails(IOE, webSocket.sendBinary(ByteBuffer.allocate(1), false)); + assertFails(IOE, webSocket.sendText("", true)); + assertFails(IOE, webSocket.sendText("", false)); + assertFails(IOE, webSocket.sendText("abc", true)); + assertFails(IOE, webSocket.sendText("abc", false)); + assertFails(IOE, webSocket.sendBinary(ByteBuffer.allocate(0), true)); + assertFails(IOE, webSocket.sendBinary(ByteBuffer.allocate(0), false)); + assertFails(IOE, webSocket.sendBinary(ByteBuffer.allocate(1), true)); + assertFails(IOE, webSocket.sendBinary(ByteBuffer.allocate(1), false)); - assertFails(IOE, webSocket.sendPing(ByteBuffer.allocate(125))); - assertFails(IOE, webSocket.sendPing(ByteBuffer.allocate(124))); - assertFails(IOE, webSocket.sendPing(ByteBuffer.allocate(1))); - assertFails(IOE, webSocket.sendPing(ByteBuffer.allocate(0))); + assertFails(IOE, webSocket.sendPing(ByteBuffer.allocate(125))); + assertFails(IOE, webSocket.sendPing(ByteBuffer.allocate(124))); + assertFails(IOE, webSocket.sendPing(ByteBuffer.allocate(1))); + assertFails(IOE, webSocket.sendPing(ByteBuffer.allocate(0))); - assertFails(IOE, webSocket.sendPong(ByteBuffer.allocate(125))); - assertFails(IOE, webSocket.sendPong(ByteBuffer.allocate(124))); - assertFails(IOE, webSocket.sendPong(ByteBuffer.allocate(1))); - assertFails(IOE, webSocket.sendPong(ByteBuffer.allocate(0))); - - server.close(); + assertFails(IOE, webSocket.sendPong(ByteBuffer.allocate(125))); + assertFails(IOE, webSocket.sendPong(ByteBuffer.allocate(124))); + assertFails(IOE, webSocket.sendPong(ByteBuffer.allocate(1))); + assertFails(IOE, webSocket.sendPong(ByteBuffer.allocate(0))); + } finally { + webSocket.abort(); + } + } } @DataProvider(name = "sequence") @@ -251,150 +250,153 @@ public void listenerSequentialOrder(int[] binary, long requestSize) throws IOException { - - server = Support.serverWithCannedData(binary); - server.open(); + try (var server = Support.serverWithCannedData(binary)) { + server.open(); - CompletableFuture violation = new CompletableFuture<>(); + CompletableFuture violation = new CompletableFuture<>(); - MockListener listener = new MockListener(requestSize) { + MockListener listener = new MockListener(requestSize) { - final AtomicBoolean guard = new AtomicBoolean(); + final AtomicBoolean guard = new AtomicBoolean(); - private T checkRunExclusively(Supplier action) { - if (guard.getAndSet(true)) { - violation.completeExceptionally(new RuntimeException()); - } - try { - return action.get(); - } finally { - if (!guard.getAndSet(false)) { + private T checkRunExclusively(Supplier action) { + if (guard.getAndSet(true)) { violation.completeExceptionally(new RuntimeException()); } + try { + return action.get(); + } finally { + if (!guard.getAndSet(false)) { + violation.completeExceptionally(new RuntimeException()); + } + } } - } - @Override - public void onOpen(WebSocket webSocket) { - checkRunExclusively(() -> { - super.onOpen(webSocket); - return null; - }); - } + @Override + public void onOpen(WebSocket webSocket) { + checkRunExclusively(() -> { + super.onOpen(webSocket); + return null; + }); + } - @Override - public CompletionStage onText(WebSocket webSocket, - CharSequence data, - boolean last) { - return checkRunExclusively( - () -> super.onText(webSocket, data, last)); - } + @Override + public CompletionStage onText(WebSocket webSocket, + CharSequence data, + boolean last) { + return checkRunExclusively( + () -> super.onText(webSocket, data, last)); + } - @Override - public CompletionStage onBinary(WebSocket webSocket, - ByteBuffer data, - boolean last) { - return checkRunExclusively( - () -> super.onBinary(webSocket, data, last)); - } + @Override + public CompletionStage onBinary(WebSocket webSocket, + ByteBuffer data, + boolean last) { + return checkRunExclusively( + () -> super.onBinary(webSocket, data, last)); + } - @Override - public CompletionStage onPing(WebSocket webSocket, - ByteBuffer message) { - return checkRunExclusively( - () -> super.onPing(webSocket, message)); - } + @Override + public CompletionStage onPing(WebSocket webSocket, + ByteBuffer message) { + return checkRunExclusively( + () -> super.onPing(webSocket, message)); + } - @Override - public CompletionStage onPong(WebSocket webSocket, - ByteBuffer message) { - return checkRunExclusively( - () -> super.onPong(webSocket, message)); - } + @Override + public CompletionStage onPong(WebSocket webSocket, + ByteBuffer message) { + return checkRunExclusively( + () -> super.onPong(webSocket, message)); + } - @Override - public CompletionStage onClose(WebSocket webSocket, - int statusCode, - String reason) { - return checkRunExclusively( - () -> super.onClose(webSocket, statusCode, reason)); - } + @Override + public CompletionStage onClose(WebSocket webSocket, + int statusCode, + String reason) { + return checkRunExclusively( + () -> super.onClose(webSocket, statusCode, reason)); + } - @Override - public void onError(WebSocket webSocket, Throwable error) { - checkRunExclusively(() -> { - super.onError(webSocket, error); - return null; - }); - } - }; + @Override + public void onError(WebSocket webSocket, Throwable error) { + checkRunExclusively(() -> { + super.onError(webSocket, error); + return null; + }); + } + }; - webSocket = newBuilder().proxy(NO_PROXY).build().newWebSocketBuilder() - .buildAsync(server.getURI(), listener) - .join(); - - - listener.invocations(); - violation.complete(null); // won't affect if completed exceptionally - violation.join(); - - server.close(); + var webSocket = newBuilder().proxy(NO_PROXY).build().newWebSocketBuilder() + .buildAsync(server.getURI(), listener) + .join(); + try { + listener.invocations(); + violation.complete(null); // won't affect if completed exceptionally + violation.join(); + } finally { + webSocket.abort(); + } + } } @Test public void sendMethodsThrowIOE2() throws Exception { - server = Support.serverWithCannedData(0x88, 0x00); - server.open(); - CompletableFuture onCloseCalled = new CompletableFuture<>(); - CompletableFuture canClose = new CompletableFuture<>(); + try (var server = Support.serverWithCannedData(0x88, 0x00)) { + server.open(); + + CompletableFuture onCloseCalled = new CompletableFuture<>(); + CompletableFuture canClose = new CompletableFuture<>(); - WebSocket.Listener listener = new WebSocket.Listener() { - @Override - public CompletionStage onClose(WebSocket webSocket, - int statusCode, - String reason) { - System.out.printf("onClose(%s, '%s')%n", statusCode, reason); - onCloseCalled.complete(null); - return canClose; - } + WebSocket.Listener listener = new WebSocket.Listener() { + @Override + public CompletionStage onClose(WebSocket webSocket, + int statusCode, + String reason) { + System.out.printf("onClose(%s, '%s')%n", statusCode, reason); + onCloseCalled.complete(null); + return canClose; + } - @Override - public void onError(WebSocket webSocket, Throwable error) { - System.out.println("onError(" + error + ")"); - onCloseCalled.completeExceptionally(error); - } - }; - - webSocket = newBuilder().proxy(NO_PROXY).build().newWebSocketBuilder() - .buildAsync(server.getURI(), listener) - .join(); + @Override + public void onError(WebSocket webSocket, Throwable error) { + System.out.println("onError(" + error + ")"); + onCloseCalled.completeExceptionally(error); + } + }; - onCloseCalled.join(); // Wait for onClose to be called - canClose.complete(null); // Signal to the WebSocket it can close the output - TimeUnit.SECONDS.sleep(5); // Give canClose some time to reach the WebSocket + var webSocket = newBuilder().proxy(NO_PROXY).build().newWebSocketBuilder() + .buildAsync(server.getURI(), listener) + .join(); + try { + onCloseCalled.join(); // Wait for onClose to be called + canClose.complete(null); // Signal to the WebSocket it can close the output + TimeUnit.SECONDS.sleep(5); // Give canClose some time to reach the WebSocket - assertFails(IOE, webSocket.sendClose(WebSocket.NORMAL_CLOSURE, "ok")); + assertFails(IOE, webSocket.sendClose(WebSocket.NORMAL_CLOSURE, "ok")); - assertFails(IOE, webSocket.sendText("", true)); - assertFails(IOE, webSocket.sendText("", false)); - assertFails(IOE, webSocket.sendText("abc", true)); - assertFails(IOE, webSocket.sendText("abc", false)); - assertFails(IOE, webSocket.sendBinary(ByteBuffer.allocate(0), true)); - assertFails(IOE, webSocket.sendBinary(ByteBuffer.allocate(0), false)); - assertFails(IOE, webSocket.sendBinary(ByteBuffer.allocate(1), true)); - assertFails(IOE, webSocket.sendBinary(ByteBuffer.allocate(1), false)); + assertFails(IOE, webSocket.sendText("", true)); + assertFails(IOE, webSocket.sendText("", false)); + assertFails(IOE, webSocket.sendText("abc", true)); + assertFails(IOE, webSocket.sendText("abc", false)); + assertFails(IOE, webSocket.sendBinary(ByteBuffer.allocate(0), true)); + assertFails(IOE, webSocket.sendBinary(ByteBuffer.allocate(0), false)); + assertFails(IOE, webSocket.sendBinary(ByteBuffer.allocate(1), true)); + assertFails(IOE, webSocket.sendBinary(ByteBuffer.allocate(1), false)); - assertFails(IOE, webSocket.sendPing(ByteBuffer.allocate(125))); - assertFails(IOE, webSocket.sendPing(ByteBuffer.allocate(124))); - assertFails(IOE, webSocket.sendPing(ByteBuffer.allocate(1))); - assertFails(IOE, webSocket.sendPing(ByteBuffer.allocate(0))); + assertFails(IOE, webSocket.sendPing(ByteBuffer.allocate(125))); + assertFails(IOE, webSocket.sendPing(ByteBuffer.allocate(124))); + assertFails(IOE, webSocket.sendPing(ByteBuffer.allocate(1))); + assertFails(IOE, webSocket.sendPing(ByteBuffer.allocate(0))); - assertFails(IOE, webSocket.sendPong(ByteBuffer.allocate(125))); - assertFails(IOE, webSocket.sendPong(ByteBuffer.allocate(124))); - assertFails(IOE, webSocket.sendPong(ByteBuffer.allocate(1))); - assertFails(IOE, webSocket.sendPong(ByteBuffer.allocate(0))); - - server.close(); + assertFails(IOE, webSocket.sendPong(ByteBuffer.allocate(125))); + assertFails(IOE, webSocket.sendPong(ByteBuffer.allocate(124))); + assertFails(IOE, webSocket.sendPong(ByteBuffer.allocate(1))); + assertFails(IOE, webSocket.sendPong(ByteBuffer.allocate(0))); + } finally { + webSocket.abort(); + } + } } // Used to verify a server requiring Authentication @@ -458,74 +460,76 @@ }; CompletableFuture> actual = new CompletableFuture<>(); - server = serverSupplier.apply(binary); - server.open(); - - WebSocket.Listener listener = new WebSocket.Listener() { + try (var server = serverSupplier.apply(binary)) { + server.open(); - List collectedBytes = new ArrayList<>(); - ByteBuffer buffer = ByteBuffer.allocate(1024); + WebSocket.Listener listener = new WebSocket.Listener() { - @Override - public CompletionStage onBinary(WebSocket webSocket, - ByteBuffer message, - boolean last) { - System.out.printf("onBinary(%s, %s)%n", message, last); - webSocket.request(1); + List collectedBytes = new ArrayList<>(); + ByteBuffer buffer = ByteBuffer.allocate(1024); - append(message); - if (last) { - buffer.flip(); - byte[] bytes = new byte[buffer.remaining()]; - buffer.get(bytes); - buffer.clear(); - processWholeBinary(bytes); - } - return null; - } + @Override + public CompletionStage onBinary(WebSocket webSocket, + ByteBuffer message, + boolean last) { + System.out.printf("onBinary(%s, %s)%n", message, last); + webSocket.request(1); - private void append(ByteBuffer message) { - if (buffer.remaining() < message.remaining()) { - assert message.remaining() > 0; - int cap = (buffer.capacity() + message.remaining()) * 2; - ByteBuffer b = ByteBuffer.allocate(cap); - b.put(buffer.flip()); - buffer = b; + append(message); + if (last) { + buffer.flip(); + byte[] bytes = new byte[buffer.remaining()]; + buffer.get(bytes); + buffer.clear(); + processWholeBinary(bytes); + } + return null; } - buffer.put(message); - } - private void processWholeBinary(byte[] bytes) { - String stringBytes = new String(bytes, UTF_8); - System.out.println("processWholeBinary: " + stringBytes); - collectedBytes.add(bytes); - } + private void append(ByteBuffer message) { + if (buffer.remaining() < message.remaining()) { + assert message.remaining() > 0; + int cap = (buffer.capacity() + message.remaining()) * 2; + ByteBuffer b = ByteBuffer.allocate(cap); + b.put(buffer.flip()); + buffer = b; + } + buffer.put(message); + } - @Override - public CompletionStage onClose(WebSocket webSocket, - int statusCode, - String reason) { - actual.complete(collectedBytes); - return null; - } + private void processWholeBinary(byte[] bytes) { + String stringBytes = new String(bytes, UTF_8); + System.out.println("processWholeBinary: " + stringBytes); + collectedBytes.add(bytes); + } - @Override - public void onError(WebSocket webSocket, Throwable error) { - actual.completeExceptionally(error); - } - }; + @Override + public CompletionStage onClose(WebSocket webSocket, + int statusCode, + String reason) { + actual.complete(collectedBytes); + return null; + } + + @Override + public void onError(WebSocket webSocket, Throwable error) { + actual.completeExceptionally(error); + } + }; - webSocket = newBuilder() - .proxy(NO_PROXY) - .authenticator(new WSAuthenticator()) - .build().newWebSocketBuilder() - .buildAsync(server.getURI(), listener) - .join(); - - List a = actual.join(); - assertEquals(a, expected); - - server.close(); + var webSocket = newBuilder() + .proxy(NO_PROXY) + .authenticator(new WSAuthenticator()) + .build().newWebSocketBuilder() + .buildAsync(server.getURI(), listener) + .join(); + try { + List a = actual.join(); + assertEquals(a, expected); + } finally { + webSocket.abort(); + } + } } @Test(dataProvider = "servers") @@ -554,59 +558,61 @@ }; CompletableFuture> actual = new CompletableFuture<>(); - server = serverSupplier.apply(binary); - server.open(); + try (var server = serverSupplier.apply(binary)) { + server.open(); + + WebSocket.Listener listener = new WebSocket.Listener() { + + List collectedStrings = new ArrayList<>(); + StringBuilder text = new StringBuilder(); - WebSocket.Listener listener = new WebSocket.Listener() { - - List collectedStrings = new ArrayList<>(); - StringBuilder text = new StringBuilder(); + @Override + public CompletionStage onText(WebSocket webSocket, + CharSequence message, + boolean last) { + System.out.printf("onText(%s, %s)%n", message, last); + webSocket.request(1); + text.append(message); + if (last) { + String str = text.toString(); + text.setLength(0); + processWholeText(str); + } + return null; + } - @Override - public CompletionStage onText(WebSocket webSocket, - CharSequence message, - boolean last) { - System.out.printf("onText(%s, %s)%n", message, last); - webSocket.request(1); - text.append(message); - if (last) { - String str = text.toString(); - text.setLength(0); - processWholeText(str); + private void processWholeText(String string) { + System.out.println(string); + collectedStrings.add(string); + } + + @Override + public CompletionStage onClose(WebSocket webSocket, + int statusCode, + String reason) { + actual.complete(collectedStrings); + return null; } - return null; - } + + @Override + public void onError(WebSocket webSocket, Throwable error) { + actual.completeExceptionally(error); + } + }; - private void processWholeText(String string) { - System.out.println(string); - collectedStrings.add(string); + var webSocket = newBuilder() + .proxy(NO_PROXY) + .authenticator(new WSAuthenticator()) + .build().newWebSocketBuilder() + .buildAsync(server.getURI(), listener) + .join(); + try { + List a = actual.join(); + assertEquals(a, expected); + } finally { + webSocket.abort(); } - - @Override - public CompletionStage onClose(WebSocket webSocket, - int statusCode, - String reason) { - actual.complete(collectedStrings); - return null; - } - - @Override - public void onError(WebSocket webSocket, Throwable error) { - actual.completeExceptionally(error); - } - }; - - webSocket = newBuilder() - .proxy(NO_PROXY) - .authenticator(new WSAuthenticator()) - .build().newWebSocketBuilder() - .buildAsync(server.getURI(), listener) - .join(); - - List a = actual.join(); - assertEquals(a, expected); - - server.close(); + } } /* @@ -639,73 +645,75 @@ }; CompletableFuture> actual = new CompletableFuture<>(); - server = serverSupplier.apply(binary); - server.open(); + try (var server = serverSupplier.apply(binary)) { + server.open(); - WebSocket.Listener listener = new WebSocket.Listener() { + WebSocket.Listener listener = new WebSocket.Listener() { - List parts = new ArrayList<>(); - /* - * A CompletableFuture which will complete once the current - * message has been fully assembled. Until then the listener - * returns this instance for every call. - */ - CompletableFuture currentCf = new CompletableFuture<>(); - List collected = new ArrayList<>(); + List parts = new ArrayList<>(); + /* + * A CompletableFuture which will complete once the current + * message has been fully assembled. Until then the listener + * returns this instance for every call. + */ + CompletableFuture currentCf = new CompletableFuture<>(); + List collected = new ArrayList<>(); - @Override - public CompletionStage onText(WebSocket webSocket, - CharSequence message, - boolean last) { - parts.add(message); - if (!last) { - webSocket.request(1); - } else { - this.currentCf.thenRun(() -> webSocket.request(1)); - CompletableFuture refCf = this.currentCf; - processWholeMessage(new ArrayList<>(parts), refCf); - currentCf = new CompletableFuture<>(); - parts.clear(); - return refCf; + @Override + public CompletionStage onText(WebSocket webSocket, + CharSequence message, + boolean last) { + parts.add(message); + if (!last) { + webSocket.request(1); + } else { + this.currentCf.thenRun(() -> webSocket.request(1)); + CompletableFuture refCf = this.currentCf; + processWholeMessage(new ArrayList<>(parts), refCf); + currentCf = new CompletableFuture<>(); + parts.clear(); + return refCf; + } + return currentCf; } - return currentCf; - } - @Override - public CompletionStage onClose(WebSocket webSocket, - int statusCode, - String reason) { - actual.complete(collected); - return null; - } + @Override + public CompletionStage onClose(WebSocket webSocket, + int statusCode, + String reason) { + actual.complete(collected); + return null; + } - @Override - public void onError(WebSocket webSocket, Throwable error) { - actual.completeExceptionally(error); - } + @Override + public void onError(WebSocket webSocket, Throwable error) { + actual.completeExceptionally(error); + } - public void processWholeMessage(List data, - CompletableFuture cf) { - StringBuilder b = new StringBuilder(); - data.forEach(b::append); - String s = b.toString(); - System.out.println(s); - cf.complete(null); - collected.add(s); - } - }; + public void processWholeMessage(List data, + CompletableFuture cf) { + StringBuilder b = new StringBuilder(); + data.forEach(b::append); + String s = b.toString(); + System.out.println(s); + cf.complete(null); + collected.add(s); + } + }; - webSocket = newBuilder() - .proxy(NO_PROXY) - .authenticator(new WSAuthenticator()) - .build().newWebSocketBuilder() - .buildAsync(server.getURI(), listener) - .join(); - - List a = actual.join(); - assertEquals(a, expected); - - server.close(); + var webSocket = newBuilder() + .proxy(NO_PROXY) + .authenticator(new WSAuthenticator()) + .build().newWebSocketBuilder() + .buildAsync(server.getURI(), listener) + .join(); + try { + List a = actual.join(); + assertEquals(a, expected); + } finally { + webSocket.abort(); + } + } } // -- authentication specific tests @@ -725,6 +733,7 @@ .newWebSocketBuilder() .buildAsync(server.getURI(), new WebSocket.Listener() { }) .join(); + webSocket.abort(); } } @@ -745,6 +754,7 @@ .header("Authorization", hv) .buildAsync(server.getURI(), new WebSocket.Listener() { }) .join(); + webSocket.abort(); } } @@ -763,6 +773,7 @@ try { var webSocket = cf.join(); + silentAbort(webSocket); fail("Expected exception not thrown"); } catch (CompletionException expected) { WebSocketHandshakeException e = (WebSocketHandshakeException)expected.getCause(); @@ -783,7 +794,7 @@ Authenticator authenticator = new Authenticator() { @Override protected PasswordAuthentication getPasswordAuthentication() { - return new PasswordAuthentication("BAD"+USERNAME, "".toCharArray()); + return new PasswordAuthentication("BAD" + USERNAME, "".toCharArray()); } }; @@ -796,10 +807,16 @@ try { var webSocket = cf.join(); + silentAbort(webSocket); fail("Expected exception not thrown"); } catch (CompletionException expected) { System.out.println("caught expected exception:" + expected); } } } + private static void silentAbort(WebSocket ws) { + try { + ws.abort(); + } catch (Throwable t) { } + } } diff -r e47423f1318b -r ca19b94eac7a test/jdk/java/nio/channels/spi/SelectorProvider/inheritedChannel/InheritedChannelTest.java --- a/test/jdk/java/nio/channels/spi/SelectorProvider/inheritedChannel/InheritedChannelTest.java Mon Sep 23 09:16:05 2019 -0700 +++ b/test/jdk/java/nio/channels/spi/SelectorProvider/inheritedChannel/InheritedChannelTest.java Wed Sep 25 22:40:41 2019 +0200 @@ -25,7 +25,7 @@ * @test * @bug 4673940 4930794 8211842 * @summary Unit tests for inetd feature - * @requires (os.family == "linux" | os.family == "solaris") + * @requires (os.family == "linux" | os.family == "solaris" | os.family == "mac") * @library /test/lib * @build jdk.test.lib.Utils * jdk.test.lib.Asserts @@ -33,7 +33,8 @@ * jdk.test.lib.JDKToolLauncher * jdk.test.lib.Platform * jdk.test.lib.process.* - * UnixSocketTest StateTest StateTestService EchoTest EchoService CloseTest Launcher Util + * UnixSocketTest StateTest StateTestService EchoTest EchoService + * UnixDomainChannelTest CloseTest Launcher Util * @run testng/othervm/native InheritedChannelTest * @key intermittent */ @@ -73,7 +74,8 @@ @DataProvider public Object[][] testCases() { - return new Object[][]{ + return new Object[][] { + { "UnixDomainChannelTest", List.of(UnixDomainChannelTest.class.getName())}, { "UnixSocketTest", List.of(UnixSocketTest.class.getName())}, { "StateTest", List.of(StateTest.class.getName()) }, { "EchoTest", List.of(EchoTest.class.getName()) }, @@ -83,6 +85,7 @@ // Note that the system properties are arguments to StateTest and not options. // These system properties are passed to the launched service as options: // java [-options] class [args...] + { "StateTest run with " + POLICY_PASS, List.of(StateTest.class.getName(), "-Djava.security.manager", "-Djava.security.policy=" @@ -97,7 +100,7 @@ }; } - @Test(dataProvider = "testCases") + @Test(dataProvider = "testCases", timeOut=30000) public void test(String desc, List opts) throws Throwable { String pathVar = Platform.sharedLibraryPathVariableName(); System.out.println(pathVar + "=" + libraryPath); diff -r e47423f1318b -r ca19b94eac7a test/jdk/java/nio/channels/spi/SelectorProvider/inheritedChannel/Launcher.java --- a/test/jdk/java/nio/channels/spi/SelectorProvider/inheritedChannel/Launcher.java Mon Sep 23 09:16:05 2019 -0700 +++ b/test/jdk/java/nio/channels/spi/SelectorProvider/inheritedChannel/Launcher.java Wed Sep 25 22:40:41 2019 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2019, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -75,6 +75,15 @@ return socks[1]; } + /** + * Launch specified class with an AF_UNIX socket created externally, and one String arg to child VM + */ + public static void launchWithUnixDomainSocket(String className, UnixDomainSocket socket, String arg) throws IOException { + String[] args = new String[1]; + args[0] = arg; + launch(className, null, args, socket.fd()); + } + /* * Launch 'java' with specified class with the specified arguments (may be null). * The launched process will inherit a connected TCP socket. The remote endpoint diff -r e47423f1318b -r ca19b94eac7a test/jdk/java/nio/channels/spi/SelectorProvider/inheritedChannel/UnixDomainChannelTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/jdk/java/nio/channels/spi/SelectorProvider/inheritedChannel/UnixDomainChannelTest.java Wed Sep 25 22:40:41 2019 +0200 @@ -0,0 +1,117 @@ +/* + * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import java.nio.channels.*; +import java.nio.ByteBuffer; +import java.io.IOException; +import static java.nio.charset.StandardCharsets.ISO_8859_1; + +/* + * Make sure that System.inheritedChannel returns null when given a UNIX domain socket + */ + +public class UnixDomainChannelTest { + + public static class Child { + public static void main(String[] args) throws Exception { + // we just want to make sure that System.inheritedChannel either + // returns a connected channel, or null if it is given a listener + Channel channel = System.inheritedChannel(); + String result = channel == null ? "N" : "Y"; + if (args[0].equals("test1") || args[0].equals("test2")) { + // socket is writeable + ByteChannel bc = (ByteChannel)channel; + ByteBuffer buf = ByteBuffer.wrap(result.getBytes(ISO_8859_1)); + bc.write(buf); + } else { // test3 + // in this case the socket is a listener + // we can't write to it. So, use UnixDatagramSocket + // to accept a writeable socket + UnixDomainSocket listener = new UnixDomainSocket(0); // fd 0 + UnixDomainSocket sock = listener.accept(); + sock.write((int)result.charAt(0)); + } + } + } + + static boolean passed = true; + + public static void main(String args[]) throws Exception { + test1(); + test2(); + test3(); + if (!passed) + throw new RuntimeException(); + } + + private static void closeAll(UnixDomainSocket... sockets) { + for (UnixDomainSocket sock : sockets) { + sock.close(); + } + } + + // Test with a named connected socket + private static void test1() throws Exception { + UnixDomainSocket listener = new UnixDomainSocket(); + listener.bind("foo.socket"); + UnixDomainSocket sock1 = new UnixDomainSocket(); + sock1.connect("foo.socket"); + UnixDomainSocket sock2 = listener.accept(); + + Launcher.launchWithUnixDomainSocket("UnixDomainChannelTest$Child", sock2, "test1"); + int c = sock1.read(); + if (c != 'Y') { + System.err.printf("test1: failed %d d\n", c ); + passed = false; + } + closeAll(listener, sock1, sock2); + } + + // Test with unnamed socketpair + private static void test2() throws Exception { + UnixDomainSocket[] pair = UnixDomainSocket.socketpair(); + System.out.println("test2: launching child"); + Launcher.launchWithUnixDomainSocket("UnixDomainChannelTest$Child", pair[0], "test2"); + if (pair[1].read() != 'Y') { + System.err.println("test2: failed"); + passed = false; + } + closeAll(pair[0], pair[1]); + } + + // Test with a named listener + private static void test3() throws Exception { + UnixDomainSocket listener = new UnixDomainSocket(); + listener.bind("foo.socket"); + UnixDomainSocket sock1 = new UnixDomainSocket(); + System.out.println("test3: launching child"); + Launcher.launchWithUnixDomainSocket("UnixDomainChannelTest$Child", listener, "test3"); + sock1.connect("foo.socket"); + if (sock1.read() != 'N') { + System.err.println("test3: failed"); + passed = false; + } + closeAll(listener, sock1); + } + +} diff -r e47423f1318b -r ca19b94eac7a test/jdk/java/nio/channels/spi/SelectorProvider/inheritedChannel/UnixDomainSocket.java --- a/test/jdk/java/nio/channels/spi/SelectorProvider/inheritedChannel/UnixDomainSocket.java Mon Sep 23 09:16:05 2019 -0700 +++ b/test/jdk/java/nio/channels/spi/SelectorProvider/inheritedChannel/UnixDomainSocket.java Wed Sep 25 22:40:41 2019 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2019 Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -37,21 +37,44 @@ } private final int fd; + private volatile String name; + + public UnixDomainSocket() throws IOException { + this.fd = create(); + } + + public void bind(String name) throws IOException { + bind0(fd, name); + this.name = name; + } + + public UnixDomainSocket accept() throws IOException { + int newsock = accept0(fd); + return new UnixDomainSocket(newsock); + } public UnixDomainSocket(int fd) { this.fd = fd; } + public void connect(String dest) throws IOException { + connect0(fd, dest); + } + public int read() throws IOException { return read0(fd); } + public String name() { + return name; + } + public void write(int w) throws IOException { write0(fd, w); } public void close() { - close0(fd); + close0(fd, name); // close0 will unlink name if non-null } public int fd() { @@ -62,11 +85,16 @@ return "UnixDomainSocket: fd=" + Integer.toString(fd); } + private static native int create() throws IOException; + private static native void bind0(int fd, String name) throws IOException; + private static native int accept0(int fd) throws IOException; + private static native int connect0(int fd, String name) throws IOException; + /* read and write bytes with UNIX domain sockets */ private static native int read0(int fd) throws IOException; private static native void write0(int fd, int w) throws IOException; - private static native void close0(int fd); + private static native void close0(int fd, String name); private static native void init(); public static native UnixDomainSocket[] socketpair(); } diff -r e47423f1318b -r ca19b94eac7a test/jdk/java/nio/channels/spi/SelectorProvider/inheritedChannel/libInheritedChannel.c --- a/test/jdk/java/nio/channels/spi/SelectorProvider/inheritedChannel/libInheritedChannel.c Mon Sep 23 09:16:05 2019 -0700 +++ b/test/jdk/java/nio/channels/spi/SelectorProvider/inheritedChannel/libInheritedChannel.c Wed Sep 25 22:40:41 2019 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2019, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -26,8 +26,10 @@ */ #include #include +#include #include #include +#include #include #include #include @@ -147,19 +149,18 @@ /* * We need to close all file descriptors except for serviceFd. To - * get the list of open file descriptos we read through /proc/self/fd + * get the list of open file descriptos we read through /proc/self/fd (/dev/fd) * but to open this requires a file descriptor. We could use a specific * file descriptor and fdopendir but Linux doesn't seem to support * fdopendir. Instead we use opendir and make an assumption on the * file descriptor that is used (by opening & closing a file). */ - thisFd = open("/dev/null", O_RDONLY); + thisFd = open("/dev/fd", O_RDONLY); if (thisFd < 0) { _exit(-1); } - close(thisFd); - if ((dp = opendir("/proc/self/fd")) == NULL) { + if ((dp = fdopendir(thisFd)) == NULL) { _exit(-1); } @@ -216,6 +217,65 @@ return result; } +JNIEXPORT jint JNICALL Java_UnixDomainSocket_create + (JNIEnv *env, jclass cls) +{ + int sock = socket(AF_UNIX, SOCK_STREAM, 0); + if (sock == -1) { + ThrowException(env, "java/io/IOException", "socket create error"); + } + return sock; +} + +JNIEXPORT void JNICALL Java_UnixDomainSocket_bind0 + (JNIEnv *env, jclass cls, jint sock, jstring name) +{ + struct sockaddr_un addr; + const char *nameUtf = (*env)->GetStringUTFChars(env, name, NULL); + int ret = -1; + unlink(nameUtf); + memset(&addr, 0, sizeof(addr)); + addr.sun_family = AF_UNIX; + strncpy(addr.sun_path, nameUtf, strlen(nameUtf)); + ret = bind(sock, (const struct sockaddr*)&addr, sizeof(addr)); + if (ret == -1) { + ThrowException(env, "java/io/IOException", "socket bind error"); + } + ret = listen(sock, 5); + if (ret == -1) { + ThrowException(env, "java/io/IOException", "socket bind error"); + } + (*env)->ReleaseStringUTFChars(env, name, nameUtf); +} + +JNIEXPORT jint JNICALL Java_UnixDomainSocket_accept0 + (JNIEnv *env, jclass cls, jint sock) +{ + struct sockaddr_storage addr; + socklen_t len = sizeof(addr); + int ret = accept(sock, (struct sockaddr *)&addr, &len); + if (ret == -1) + ThrowException(env, "java/io/IOException", "socket accept error"); + return ret; +} + +JNIEXPORT void JNICALL Java_UnixDomainSocket_connect0 + (JNIEnv *env, jclass cls, jint fd, jstring name) +{ + struct sockaddr_un addr; + const char *nameUtf = (*env)->GetStringUTFChars(env, name, NULL); + int ret = -1; + memset(&addr, 0, sizeof(addr)); + addr.sun_family = AF_UNIX; + strncpy(addr.sun_path, nameUtf, strlen(nameUtf)); + ret = connect(fd, (const struct sockaddr*)&addr, sizeof(addr)); + if (ret == -1) { + ThrowException(env, "java/io/IOException", "socket connect error"); + } + (*env)->ReleaseStringUTFChars(env, name, nameUtf); +} + + JNIEXPORT jint JNICALL Java_UnixDomainSocket_read0 (JNIEnv *env, jclass cls, jint fd) { @@ -243,7 +303,12 @@ } JNIEXPORT void JNICALL Java_UnixDomainSocket_close0 - (JNIEnv *env, jclass cls, jint fd) + (JNIEnv *env, jclass cls, jint fd, jstring name) { close(fd); + if (name != NULL) { + const char *nameUtf = (*env)->GetStringUTFChars(env, name, NULL); + unlink(nameUtf); + (*env)->ReleaseStringUTFChars(env, name, nameUtf); + } } diff -r e47423f1318b -r ca19b94eac7a test/jdk/java/nio/file/attribute/BasicFileAttributeView/SetTimesNanos.java --- a/test/jdk/java/nio/file/attribute/BasicFileAttributeView/SetTimesNanos.java Mon Sep 23 09:16:05 2019 -0700 +++ b/test/jdk/java/nio/file/attribute/BasicFileAttributeView/SetTimesNanos.java Wed Sep 25 22:40:41 2019 +0200 @@ -22,9 +22,9 @@ */ /* @test - * @bug 8181493 + * @bug 8181493 8231174 * @summary Verify that nanosecond precision is maintained for file timestamps - * @requires (os.family == "linux") | (os.family == "mac") | (os.family == "solaris") + * @requires (os.family == "linux") | (os.family == "mac") | (os.family == "solaris") | (os.family == "windows") * @modules java.base/sun.nio.fs:+open */ @@ -40,14 +40,21 @@ import java.util.concurrent.TimeUnit; public class SetTimesNanos { + private static final boolean IS_WINDOWS = + System.getProperty("os.name").startsWith("Windows"); + public static void main(String[] args) throws Exception { - // Check whether futimens() system call is supported - Class unixNativeDispatcherClass = Class.forName("sun.nio.fs.UnixNativeDispatcher"); - Method futimensSupported = unixNativeDispatcherClass.getDeclaredMethod("futimensSupported"); - futimensSupported.setAccessible(true); - if (!(boolean)futimensSupported.invoke(null)) { - System.err.println("futimens() system call not supported; skipping test"); - return; + if (!IS_WINDOWS) { + // Check whether futimens() system call is supported + Class unixNativeDispatcherClass = + Class.forName("sun.nio.fs.UnixNativeDispatcher"); + Method futimensSupported = + unixNativeDispatcherClass.getDeclaredMethod("futimensSupported"); + futimensSupported.setAccessible(true); + if (!(boolean)futimensSupported.invoke(null)) { + System.err.println("futimens() not supported; skipping test"); + return; + } } Path dirPath = Path.of("test"); @@ -56,7 +63,8 @@ System.out.format("FileStore: \"%s\" on %s (%s)%n", dir, store.name(), store.type()); - Set testedTypes = Set.of("apfs", "ext4", "xfs", "zfs"); + Set testedTypes = IS_WINDOWS ? + Set.of("NTFS") : Set.of("apfs", "ext4", "xfs", "zfs"); if (!testedTypes.contains(store.type())) { System.err.format("%s not in %s; skipping test", store.type(), testedTypes); return; @@ -77,6 +85,11 @@ Files.getFileAttributeView(path, BasicFileAttributeView.class); view.setTimes(pathTime, pathTime, null); + // Windows file time resolution is 100ns so truncate + if (IS_WINDOWS) { + timeNanos = 100L*(timeNanos/100L); + } + // Read attributes BasicFileAttributes attrs = Files.readAttributes(path, BasicFileAttributes.class); diff -r e47423f1318b -r ca19b94eac7a test/jdk/java/nio/file/etc/MacVolumesTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/jdk/java/nio/file/etc/MacVolumesTest.java Wed Sep 25 22:40:41 2019 +0200 @@ -0,0 +1,203 @@ +/* + * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* @test + * @bug 8231254 + * @requires os.family == "mac" + * @summary Check access and basic NIO APIs on APFS for macOS version >= 10.15 + */ +import java.io.BufferedReader; +import java.io.FileInputStream; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.io.IOException; +import java.io.Reader; +import java.nio.ByteBuffer; +import java.nio.channels.SeekableByteChannel; +import java.nio.file.DirectoryStream; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.StandardOpenOption; +import java.nio.file.attribute.FileTime; +import java.util.Arrays; +import java.util.Iterator; +import java.util.Random; + +public class MacVolumesTest { + private static final String SYSTEM_VOLUME = "/"; + private static final String DATA_VOLUME = "/System/Volumes/Data"; + private static final String FIRMLINKS = "/usr/share/firmlinks"; + + private static final void checkSystemVolume() throws IOException { + System.out.format("--- Checking system volume %s ---%n", SYSTEM_VOLUME); + Path root = Path.of(SYSTEM_VOLUME); + if (!Files.getFileStore(root).isReadOnly()) { + throw new RuntimeException("Root volume is not read-only"); + } + + Path tempDir; + try { + tempDir = Files.createTempDirectory(root, "tempDir"); + throw new RuntimeException("Created temporary directory in root"); + } catch (IOException ignore) { + } + + Path tempFile; + try { + tempFile = Files.createTempFile(root, "tempFile", null); + throw new RuntimeException("Created temporary file in root"); + } catch (IOException ignore) { + } + + Path path = null; + Path etc = Path.of(SYSTEM_VOLUME, "etc"); + if (Files.isWritable(etc)) { + throw new RuntimeException("System path " + etc + " is writable"); + } + try (DirectoryStream ds = Files.newDirectoryStream(etc)) { + Iterator paths = ds.iterator(); + while (paths.hasNext()) { + Path p = paths.next(); + if (Files.isReadable(p) && Files.isRegularFile(p)) { + path = p; + break; + } + } + } + if (path == null) { + System.err.println("No root test file found: skipping file test"); + return; + } + System.out.format("Using root test file %s%n", path); + + if (Files.isWritable(path)) { + throw new RuntimeException("Test file " + path + " is writable"); + } + + FileTime creationTime = + (FileTime)Files.getAttribute(path, "basic:creationTime"); + System.out.format("%s creation time: %s%n", path, creationTime); + + long size = Files.size(path); + int capacity = (int)Math.min(1024, size); + ByteBuffer buf = ByteBuffer.allocate(capacity); + try (SeekableByteChannel sbc = Files.newByteChannel(path)) { + int n = sbc.read(buf); + System.out.format("Read %d bytes from %s%n", n, path); + } + } + + private static final void checkDataVolume() throws IOException { + System.out.format("--- Checking data volume %s ---%n", DATA_VOLUME); + Path data = Path.of(DATA_VOLUME, "tmp"); + if (Files.getFileStore(data).isReadOnly()) { + throw new RuntimeException("Data volume is read-only"); + } + + Path tempDir = Files.createTempDirectory(data, "tempDir"); + tempDir.toFile().deleteOnExit(); + System.out.format("Temporary directory: %s%n", tempDir); + if (!Files.isWritable(tempDir)) { + throw new RuntimeException("Temporary directory is not writable"); + } + + Path tempFile = Files.createTempFile(tempDir, "tempFile", null); + tempFile.toFile().deleteOnExit(); + System.out.format("Temporary file: %s%n", tempFile); + if (!Files.isWritable(tempFile)) { + throw new RuntimeException("Temporary file is not writable"); + } + + byte[] bytes = new byte[42]; + new Random().nextBytes(bytes); + try (SeekableByteChannel sbc = Files.newByteChannel(tempFile, + StandardOpenOption.WRITE)) { + ByteBuffer src = ByteBuffer.wrap(bytes); + if (sbc.write(src) != bytes.length) { + throw new RuntimeException("Incorrect number of bytes written"); + } + } + + try (SeekableByteChannel sbc = Files.newByteChannel(tempFile)) { + ByteBuffer dst = ByteBuffer.allocate(bytes.length); + if (sbc.read(dst) != bytes.length) { + throw new RuntimeException("Incorrect number of bytes read"); + } + if (!Arrays.equals(dst.array(), bytes)) { + throw new RuntimeException("Bytes read != bytes written"); + } + } + } + + static void checkFirmlinks() throws IOException { + System.out.format("--- Checking firmlinks %s ---%n", FIRMLINKS); + Path firmlinks = Path.of(FIRMLINKS); + if (!Files.exists(firmlinks)) { + System.err.format("%s does not exist: skipping firmlinks test%n", + firmlinks); + return; + } else if (!Files.isReadable(firmlinks)) { + throw new RuntimeException(String.format("%s is not readable", + firmlinks)); + } + + try (BufferedReader br = Files.newBufferedReader(firmlinks)) { + String line; + while ((line = br.readLine()) != null) { + String file = line.split("\\s")[0]; + Path path = Path.of(file); + if (!Files.exists(path)) { + System.err.format("Firmlink %s does not exist: skipping%n", + file); + continue; + } + if (Files.getFileStore(path).isReadOnly()) { + String msg = String.format("%s is read-only%n", file); + throw new RuntimeException(msg); + } else { + System.out.format("Firmlink %s OK%n", file); + } + } + } + } + + public static void main(String[] args) throws Exception { + String[] osv = System.getProperty("os.version").split("\\."); + int major = Integer.valueOf(osv[0]); + int minor = Integer.valueOf(osv[1]); + if (major < 10 || (major == 10 && minor < 15)) { + System.out.format("macOS version %d.%d too old: skipping test%n", + major, minor); + return; + } + + // Check system volume for read-only. + checkSystemVolume(); + + // Check data volume for read-write. + checkDataVolume(); + + // Check firmlinks for read-write. + checkFirmlinks(); + } +} diff -r e47423f1318b -r ca19b94eac7a test/jdk/java/security/Provider/GetServiceRace.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/jdk/java/security/Provider/GetServiceRace.java Wed Sep 25 22:40:41 2019 +0200 @@ -0,0 +1,98 @@ +/* + * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * @bug 8231387 + * @library ../testlibrary + * @summary make sure getService() avoids a race + * @author Tianmin Shi + */ + +import java.security.Provider; + +public class GetServiceRace { + + private static final Provider testProvider; + static { + testProvider = new Provider("MyProvider", 1.0, "test") { + }; + testProvider.put("CertificateFactory.Fixed", "MyCertificateFactory"); + } + + private static final int NUMBER_OF_RETRIEVERS = 3; + private static final int TEST_TIME_MS = 1000; + + public static boolean testFailed = false; + + public static void main(String[] args) throws Exception { + Updater updater = new Updater(); + updater.start(); + Retriever [] retrievers = new Retriever[NUMBER_OF_RETRIEVERS]; + for (int i=0; i isFrameShowing = frame.isShowing()); + if (!isFrameShowing) { + Thread.sleep(1000); + } + } catch (InterruptedException ex) { + } catch (Exception ex) { + throw new RuntimeException(ex); + } + } + } + private static void executeTest() throws Exception { - Point point = Util.getCenterPoint(menu); performMouseOperations(point); point = Util.getCenterPoint(menuItem); diff -r e47423f1318b -r ca19b94eac7a test/jdk/javax/swing/plaf/metal/MetalIcons/MetalHiDPIIconsTest.java --- a/test/jdk/javax/swing/plaf/metal/MetalIcons/MetalHiDPIIconsTest.java Mon Sep 23 09:16:05 2019 -0700 +++ b/test/jdk/javax/swing/plaf/metal/MetalIcons/MetalHiDPIIconsTest.java Wed Sep 25 22:40:41 2019 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2019, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -23,7 +23,7 @@ /* * @test - * @bug 8160986 8174845 8176883 + * @bug 8160986 8174845 8176883 8165828 * @summary Bad rendering of Swing UI controls with Metal L&F on HiDPI display * @run main/manual MetalHiDPIIconsTest */ @@ -50,7 +50,7 @@ + "Verify that icons are painted smoothly for standard Swing UI controls.\n\n" + "If the display does not support HiDPI mode press PASS.\n\n" + "1. Run the SwingSet2 demo on HiDPI Display.\n" - + "2. Select Metal Look and Feel\n" + + "2. Select Java Look and Feel. It is equivalent to Metal Look And Feel\n" + "3. Check that the icons are painted smoothly on Swing UI controls like:\n" + " - JRadioButton\n" + " - JCheckBox\n" diff -r e47423f1318b -r ca19b94eac7a test/jdk/jdk/jfr/event/gc/collection/TestG1ParallelPhases.java --- a/test/jdk/jdk/jfr/event/gc/collection/TestG1ParallelPhases.java Mon Sep 23 09:16:05 2019 -0700 +++ b/test/jdk/jdk/jfr/event/gc/collection/TestG1ParallelPhases.java Wed Sep 25 22:40:41 2019 +0200 @@ -98,8 +98,7 @@ "CLDGRoots", "JVMTIRoots", "CMRefRoots", - "WaitForStrongCLD", - "WeakCLDRoots", + "WaitForStrongRoots", "MergeER", "MergeHCC", "MergeRS", diff -r e47423f1318b -r ca19b94eac7a test/jdk/jdk/jfr/jcmd/TestJcmdConfigure.java --- a/test/jdk/jdk/jfr/jcmd/TestJcmdConfigure.java Mon Sep 23 09:16:05 2019 -0700 +++ b/test/jdk/jdk/jfr/jcmd/TestJcmdConfigure.java Wed Sep 25 22:40:41 2019 +0200 @@ -25,6 +25,7 @@ package jdk.jfr.jcmd; +import java.io.File; import java.nio.file.Files; import java.nio.file.Paths; import java.util.ArrayList; @@ -56,8 +57,8 @@ private static final String SAMPLE_THREADS = "samplethreads"; private static final String UNSUPPORTED_OPTION = "unsupportedoption"; - private static final String REPOSITORYPATH_1 = "./repo1"; - private static final String REPOSITORYPATH_2 = "./repo2"; + private static final String REPOSITORYPATH_1 = "." + File.pathSeparator + "repo1"; + private static final String REPOSITORYPATH_2 = "." + File.pathSeparator + "repo2"; private static final String REPOSITORYPATH_SETTING_1 = "repositorypath="+REPOSITORYPATH_1; private static final String REPOSITORYPATH_SETTING_2 = "repositorypath="+REPOSITORYPATH_2; diff -r e47423f1318b -r ca19b94eac7a test/jdk/sun/java2d/marlin/FlipBitTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/jdk/sun/java2d/marlin/FlipBitTest.java Wed Sep 25 22:40:41 2019 +0200 @@ -0,0 +1,104 @@ +/* + * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + + +import java.awt.BasicStroke; +import java.awt.Color; +import java.awt.Graphics2D; +import java.awt.Rectangle; +import java.awt.RenderingHints; +import java.awt.geom.AffineTransform; +import java.awt.geom.Ellipse2D; +import java.awt.image.BufferedImage; +import java.io.File; +import java.io.IOException; +import javax.imageio.ImageIO; + + +/** + * Tests calculating user space line with a negative determinant (flip). + * + * @test + * @summary verify that flipped transformed lines are properly rasterized + * @bug 8230728 + */ +public class FlipBitTest { + + static final boolean SAVE_IMAGE = false; + + public static void main(final String[] args) { + + final int size = 100; + + // First display which renderer is tested: + // JDK9 only: + System.setProperty("sun.java2d.renderer.verbose", "true"); + + System.out.println("FlipBitTest: size = " + size); + + final BufferedImage image = new BufferedImage(size, size, BufferedImage.TYPE_INT_ARGB); + + final Graphics2D g2d = (Graphics2D) image.getGraphics(); + try { + g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); + g2d.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY); + g2d.setRenderingHint(RenderingHints.KEY_STROKE_CONTROL, RenderingHints.VALUE_STROKE_NORMALIZE); + + final AffineTransform at = new AffineTransform(); + at.setToScale(1, -1.01); + g2d.setTransform(at); + + g2d.translate(0, -image.getHeight()); + g2d.setPaint(Color.WHITE); + g2d.fill(new Rectangle(image.getWidth(), image.getHeight())); + + g2d.setPaint(Color.BLACK); + g2d.setStroke(new BasicStroke(0.1f)); + g2d.draw(new Ellipse2D.Double(25, 25, 50, 50)); + + if (SAVE_IMAGE) { + try { + final File file = new File("FlipBitTest.png"); + + System.out.println("Writing file: " + file.getAbsolutePath()); + ImageIO.write(image, "PNG", file); + } catch (IOException ex) { + ex.printStackTrace(); + } + } + + boolean nonWhitePixelFound = false; + for (int x = 0; x < image.getWidth(); ++x) { + if (image.getRGB(x, 50) != Color.WHITE.getRGB()) { + nonWhitePixelFound = true; + break; + } + } + if (!nonWhitePixelFound) { + throw new IllegalStateException("The ellipse was not drawn"); + } + } finally { + g2d.dispose(); + } + } +} diff -r e47423f1318b -r ca19b94eac7a test/jdk/sun/java2d/pipe/hw/RSLAPITest/RSLAPITest.java --- a/test/jdk/sun/java2d/pipe/hw/RSLAPITest/RSLAPITest.java Mon Sep 23 09:16:05 2019 -0700 +++ b/test/jdk/sun/java2d/pipe/hw/RSLAPITest/RSLAPITest.java Wed Sep 25 22:40:41 2019 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2007, 2019, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -44,7 +44,6 @@ import java.util.HashSet; import sun.java2d.DestSurfaceProvider; import sun.java2d.Surface; -import sun.java2d.pipe.BufferedContext; import sun.java2d.pipe.RenderQueue; import sun.java2d.pipe.hw.AccelGraphicsConfig; import sun.java2d.pipe.hw.AccelSurface; @@ -161,8 +160,6 @@ AccelGraphicsConfig agc = (AccelGraphicsConfig) gc; printAGC(agc); - testContext(agc); - VolatileImage vi = gc.createCompatibleVolatileImage(10, 10); vi.validate(gc); if (vi instanceof DestSurfaceProvider) { @@ -250,22 +247,6 @@ } } - private static void testContext(final AccelGraphicsConfig agc) { - BufferedContext c = agc.getContext(); - - RenderQueue rq = c.getRenderQueue(); - rq.lock(); - try { - c.saveState(); - rq.flushNow(); - c.restoreState(); - rq.flushNow(); - System.out.println("Passed: Save/Restore"); - } finally { - rq.unlock(); - } - } - private static void testForNPEDuringCreation(AccelGraphicsConfig agc) { int iterations = 100; HashSet vis = new HashSet(); diff -r e47423f1318b -r ca19b94eac7a test/jdk/sun/java2d/pipe/hw/RSLContextInvalidationTest/RSLContextInvalidationTest.java --- a/test/jdk/sun/java2d/pipe/hw/RSLContextInvalidationTest/RSLContextInvalidationTest.java Mon Sep 23 09:16:05 2019 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,110 +0,0 @@ -/* - * Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -/* - * @test - * @key headful - * @bug 6764257 8198613 - * @summary Tests that the color is reset properly after save/restore context - * @author Dmitri.Trembovetski@sun.com: area=Graphics - * @modules java.desktop/sun.java2d - * java.desktop/sun.java2d.pipe - * java.desktop/sun.java2d.pipe.hw - * @compile -XDignore.symbol.file=true RSLContextInvalidationTest.java - * @run main/othervm RSLContextInvalidationTest - * @run main/othervm -Dsun.java2d.noddraw=true RSLContextInvalidationTest - */ - -import java.awt.Color; -import java.awt.Graphics; -import java.awt.GraphicsConfiguration; -import java.awt.GraphicsDevice; -import java.awt.GraphicsEnvironment; -import java.awt.image.BufferedImage; -import java.awt.image.VolatileImage; -import sun.java2d.DestSurfaceProvider; -import sun.java2d.Surface; -import sun.java2d.pipe.RenderQueue; -import sun.java2d.pipe.hw.*; - -public class RSLContextInvalidationTest { - - public static void main(String[] args) { - GraphicsEnvironment ge = - GraphicsEnvironment.getLocalGraphicsEnvironment(); - GraphicsDevice gd = ge.getDefaultScreenDevice(); - GraphicsConfiguration gc = gd.getDefaultConfiguration(); - VolatileImage vi = gc.createCompatibleVolatileImage(100, 100); - vi.validate(gc); - VolatileImage vi1 = gc.createCompatibleVolatileImage(100, 100); - vi1.validate(gc); - - if (!(vi instanceof DestSurfaceProvider)) { - System.out.println("Test considered PASSED: no HW acceleration"); - return; - } - - DestSurfaceProvider p = (DestSurfaceProvider)vi; - Surface s = p.getDestSurface(); - if (!(s instanceof AccelSurface)) { - System.out.println("Test considered PASSED: no HW acceleration"); - return; - } - AccelSurface dst = (AccelSurface)s; - - Graphics g = vi.createGraphics(); - g.drawImage(vi1, 95, 95, null); - g.setColor(Color.red); - g.fillRect(0, 0, 100, 100); - g.setColor(Color.black); - g.fillRect(0, 0, 100, 100); - // after this the validated context color is black - - RenderQueue rq = dst.getContext().getRenderQueue(); - rq.lock(); - try { - dst.getContext().saveState(); - dst.getContext().restoreState(); - } finally { - rq.unlock(); - } - - // this will cause ResetPaint (it will set color to extended EA=ff, - // which is ffffffff==Color.white) - g.drawImage(vi1, 95, 95, null); - - // now try filling with black again, but it will come up as white - // because this fill rect won't validate the color properly - g.setColor(Color.black); - g.fillRect(0, 0, 100, 100); - - BufferedImage bi = vi.getSnapshot(); - if (bi.getRGB(50, 50) != Color.black.getRGB()) { - throw new RuntimeException("Test FAILED: found color="+ - Integer.toHexString(bi.getRGB(50, 50))+" instead of "+ - Integer.toHexString(Color.black.getRGB())); - } - - System.out.println("Test PASSED."); - } -} diff -r e47423f1318b -r ca19b94eac7a test/jdk/sun/tools/jcmd/TestProcessHelper.java --- a/test/jdk/sun/tools/jcmd/TestProcessHelper.java Mon Sep 23 09:16:05 2019 -0700 +++ b/test/jdk/sun/tools/jcmd/TestProcessHelper.java Wed Sep 25 22:40:41 2019 +0200 @@ -21,16 +21,13 @@ * questions. */ -import jdk.internal.module.ModuleInfoWriter; -import jdk.test.lib.JDKToolFinder; -import jdk.test.lib.process.ProcessTools; -import jdk.test.lib.util.JarUtils; -import sun.tools.common.ProcessHelper; - import java.io.File; import java.io.IOException; import java.io.OutputStream; +import java.lang.invoke.MethodHandle; +import java.lang.invoke.MethodHandles; import java.lang.module.ModuleDescriptor; +import java.lang.reflect.Method; import java.nio.file.FileSystems; import java.nio.file.Files; import java.nio.file.Path; @@ -44,6 +41,11 @@ import java.util.stream.Collectors; import java.util.stream.Stream; +import jdk.internal.module.ModuleInfoWriter; +import jdk.test.lib.JDKToolFinder; +import jdk.test.lib.process.ProcessTools; +import jdk.test.lib.util.JarUtils; + /* * @test * @bug 8205654 @@ -52,15 +54,13 @@ * * @requires os.family == "linux" * @library /test/lib - * @modules jdk.jcmd/sun.tools.common + * @modules jdk.jcmd/sun.tools.common:+open * java.base/jdk.internal.module * @build test.TestProcess * @run main/othervm TestProcessHelper */ public class TestProcessHelper { - private ProcessHelper PROCESS_HELPER = ProcessHelper.platformProcessHelper(); - private static final String TEST_PROCESS_MAIN_CLASS_NAME = "TestProcess"; private static final String TEST_PROCESS_MAIN_CLASS_PACKAGE = "test"; private static final String TEST_PROCESS_MAIN_CLASS = TEST_PROCESS_MAIN_CLASS_PACKAGE + "." @@ -89,6 +89,29 @@ private static final String[] PATCH_MODULE_OPTIONS = {"--patch-module", null}; + private static final MethodHandle MH_GET_MAIN_CLASS = resolveMainClassMH(); + + private static MethodHandle resolveMainClassMH() { + try { + Method getMainClassMethod = Class + .forName("sun.tools.common.ProcessHelper") + .getDeclaredMethod("getMainClass", String.class); + getMainClassMethod.setAccessible(true); + return MethodHandles.lookup().unreflect(getMainClassMethod); + } catch (ClassNotFoundException | NoSuchMethodException | SecurityException | IllegalAccessException e) { + throw new RuntimeException(e); + } + } + + private static String callGetMainClass(Process p) { + try { + return (String)MH_GET_MAIN_CLASS.invoke(Long.toString(p.pid())); + } catch (Throwable e) { + throw new RuntimeException(e); + } + + } + public static void main(String[] args) throws Exception { new TestProcessHelper().runTests(); } @@ -188,7 +211,7 @@ } private void checkMainClass(Process p, String expectedMainClass) { - String mainClass = PROCESS_HELPER.getMainClass(Long.toString(p.pid())); + String mainClass = callGetMainClass(p); // getMainClass() may return null, e.g. due to timing issues. // Attempt some limited retries. if (mainClass == null) { @@ -204,7 +227,7 @@ } catch (InterruptedException e) { // ignore } - mainClass = PROCESS_HELPER.getMainClass(Long.toString(p.pid())); + mainClass = callGetMainClass(p); retrycount++; sleepms *= 2; } diff -r e47423f1318b -r ca19b94eac7a test/jdk/tools/launcher/TestSpecialArgs.java --- a/test/jdk/tools/launcher/TestSpecialArgs.java Mon Sep 23 09:16:05 2019 -0700 +++ b/test/jdk/tools/launcher/TestSpecialArgs.java Wed Sep 25 22:40:41 2019 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2019, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -132,11 +132,9 @@ * Code to create env variable not executed. * 4) give and invalid value and check to make sure JVM commented */ - String launcherPidString = "launcher.pid="; String envVarPidString = "TRACER_MARKER: NativeMemoryTracking: env var is NMT_LEVEL_"; String NMT_Option_Value = "off"; String myClassName = "helloworld"; - boolean haveLauncherPid = false; // === Run the tests === // ---Test 1a @@ -163,46 +161,6 @@ throw new RuntimeException("Error: env Var Pid in tracking info is empty string"); } - /* - * On Linux, Launcher Tracking will print the PID. Use this info - * to validate what we got as the PID in the Launcher itself. - * Linux is the only one that prints this, and trying to get it - * here for win is awful. So let the linux test make sure we get - * the valid pid, and for non-linux, just make sure pid string is - * non-zero. - */ - if (isLinux) { - // get what the test says is the launcher pid - String launcherPid = null; - for (String line : tr.testOutput) { - int index = line.indexOf(launcherPidString); - if (index >= 0) { - int sindex = index + launcherPidString.length(); - int tindex = sindex + line.substring(sindex).indexOf("'"); - System.out.println("DEBUG INFO: sindex = " + sindex); - System.out.println("DEBUG INFO: searching substring: " + line.substring(sindex)); - System.out.println("DEBUG INFO: tindex = " + tindex); - // DEBUG INFO - System.out.println(tr); - launcherPid = line.substring(sindex, tindex); - break; - } - } - if (launcherPid == null) { - System.out.println(tr); - throw new RuntimeException("Error: failed to find launcher Pid in launcher tracking info"); - } - - // did we create the env var with the correct pid? - if (!launcherPid.equals(envVarPid)) { - System.out.println(tr); - System.out.println("Error: wrong pid in creating env var"); - System.out.println("Error Info: launcherPid = " + launcherPid); - System.out.println("Error Info: envVarPid = " + envVarPid); - throw new RuntimeException("Error: wrong pid in creating env var"); - } - } - // --- Test 1b if (!tr.contains("NativeMemoryTracking: got value " + NMT_Option_Value)) { System.out.println(tr); diff -r e47423f1318b -r ca19b94eac7a test/langtools/jdk/javadoc/doclet/testSearchScript/TestSearchScript.java --- a/test/langtools/jdk/javadoc/doclet/testSearchScript/TestSearchScript.java Mon Sep 23 09:16:05 2019 -0700 +++ b/test/langtools/jdk/javadoc/doclet/testSearchScript/TestSearchScript.java Wed Sep 25 22:40:41 2019 +0200 @@ -149,11 +149,12 @@ checkSearch(inv, "operty", List.of()); // search tag - checkSearch(inv, "search tag", List.of("search tag")); - checkSearch(inv, "search tag", List.of("search tag")); - checkSearch(inv, "search ", List.of("search tag")); - checkSearch(inv, "tag", List.of("search tag")); - checkSearch(inv, "sea", List.of("search tag")); + checkSearch(inv, "search tag", List.of("multiline search tag", "search tag")); + checkSearch(inv, "search tag", List.of("multiline search tag", "search tag")); + checkSearch(inv, "search ", List.of("multiline search tag", "search tag")); + checkSearch(inv, "tag", List.of("multiline search tag", "search tag")); + checkSearch(inv, "sea", List.of("multiline search tag", "search tag")); + checkSearch(inv, "multi", List.of("multiline search tag")); checkSearch(inv, "ear", List.of()); } @@ -244,7 +245,7 @@ List.of("listpkg.List.of(E, E, E, E)", "listpkg.List.of(E, E, E, E, E)")); checkSearch(inv, "l . o (e,e,e,", List.of("listpkg.List.of(E, E, E, E)", "listpkg.List.of(E, E, E, E, E)")); - checkSearch(inv, "search \tt", List.of("search tag")); + checkSearch(inv, "search \tt", List.of("other search tag")); checkSearch(inv, "sear ch", List.of()); checkSearch(inv, "( e ..", List.of("listpkg.List.of(E...)")); checkSearch(inv, "( i [ ]", List.of("listpkg.Nolist.withArrayArg(int[])")); diff -r e47423f1318b -r ca19b94eac7a test/langtools/jdk/javadoc/doclet/testSearchScript/listpkg/Nolist.java --- a/test/langtools/jdk/javadoc/doclet/testSearchScript/listpkg/Nolist.java Mon Sep 23 09:16:05 2019 -0700 +++ b/test/langtools/jdk/javadoc/doclet/testSearchScript/listpkg/Nolist.java Wed Sep 25 22:40:41 2019 +0200 @@ -27,9 +27,8 @@ import java.util.Map; /** - * Example class containing "list" but not matching at any word boundary. - * - * {@index "search tag"}. + * Example class containing "list" but not matching at any word boundary. {@index "other + * search tag"}. */ public class Nolist { diff -r e47423f1318b -r ca19b94eac7a test/langtools/jdk/javadoc/doclet/testSearchScript/mapmodule/mappkg/Map.java --- a/test/langtools/jdk/javadoc/doclet/testSearchScript/mapmodule/mappkg/Map.java Mon Sep 23 09:16:05 2019 -0700 +++ b/test/langtools/jdk/javadoc/doclet/testSearchScript/mapmodule/mappkg/Map.java Wed Sep 25 22:40:41 2019 +0200 @@ -25,6 +25,13 @@ import java.util.Iterator; +/** + * Map interface. + * + * {@index "multiline + * search + * tag"} + */ public interface Map { public void put(Object key, Object value); public boolean contains(Object key);