--- a/hotspot/src/jdk.internal.vm.compiler/.mx.graal/suite.py Tue Jun 13 07:30:11 2017 -0400
+++ b/hotspot/src/jdk.internal.vm.compiler/.mx.graal/suite.py Tue Jun 13 09:19:35 2017 -0700
@@ -61,6 +61,27 @@
},
"projects" : {
+ # -------------- SDK --------------
+ "org.graalvm.options" : {
+ "subDir" : "share/classes",
+ "sourceDirs" : ["src"],
+ "dependencies" : [],
+ "uses" : [],
+ "exports" : [
+ "<package-info>", # exports all packages containing package-info.java
+ ],
+ "checkstyle" : "org.graalvm.api.word",
+ "javaCompliance" : "1.8",
+ "workingSets" : "API,SDK",
+ },
+ "org.graalvm.api.word" : {
+ "subDir" : "share/classes",
+ "sourceDirs" : ["src"],
+ "dependencies" : [],
+ "checkstyle" : "org.graalvm.api.word",
+ "javaCompliance" : "1.8",
+ "workingSets" : "API,SDK",
+ },
# ------------- Graal -------------
@@ -84,7 +105,7 @@
"org.graalvm.compiler.options" : {
"subDir" : "share/classes",
- "dependencies" : ["JVMCI_SERVICES", "JVMCI_API"],
+ "dependencies" : ["JVMCI_SERVICES", "JVMCI_API", "org.graalvm.util"],
"sourceDirs" : ["src"],
"dependencies" : ["org.graalvm.util"],
"checkstyle" : "org.graalvm.compiler.graph",
@@ -594,15 +615,6 @@
"workingSets" : "Graal,LIR,SPARC",
},
- "org.graalvm.api.word" : {
- "subDir" : "share/classes",
- "sourceDirs" : ["src"],
- "dependencies" : [],
- "checkstyle" : "org.graalvm.compiler.graph",
- "javaCompliance" : "1.8",
- "workingSets" : "API",
- },
-
"org.graalvm.compiler.word" : {
"subDir" : "share/classes",
"sourceDirs" : ["src"],
--- a/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.api.word/src/org/graalvm/api/word/AtomicUnsigned.java Tue Jun 13 07:30:11 2017 -0400
+++ b/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.api.word/src/org/graalvm/api/word/AtomicUnsigned.java Tue Jun 13 09:19:35 2017 -0700
@@ -4,7 +4,9 @@
*
* 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.
+ * 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
--- a/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.api.word/src/org/graalvm/api/word/AtomicWord.java Tue Jun 13 07:30:11 2017 -0400
+++ b/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.api.word/src/org/graalvm/api/word/AtomicWord.java Tue Jun 13 09:19:35 2017 -0700
@@ -4,7 +4,9 @@
*
* 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.
+ * 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
--- a/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.api.word/src/org/graalvm/api/word/ComparableWord.java Tue Jun 13 07:30:11 2017 -0400
+++ b/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.api.word/src/org/graalvm/api/word/ComparableWord.java Tue Jun 13 09:19:35 2017 -0700
@@ -4,7 +4,9 @@
*
* 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.
+ * 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
--- a/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.api.word/src/org/graalvm/api/word/LocationIdentity.java Tue Jun 13 07:30:11 2017 -0400
+++ b/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.api.word/src/org/graalvm/api/word/LocationIdentity.java Tue Jun 13 09:19:35 2017 -0700
@@ -4,7 +4,9 @@
*
* 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.
+ * 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
--- a/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.api.word/src/org/graalvm/api/word/Pointer.java Tue Jun 13 07:30:11 2017 -0400
+++ b/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.api.word/src/org/graalvm/api/word/Pointer.java Tue Jun 13 09:19:35 2017 -0700
@@ -4,7 +4,9 @@
*
* 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.
+ * 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
--- a/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.api.word/src/org/graalvm/api/word/PointerBase.java Tue Jun 13 07:30:11 2017 -0400
+++ b/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.api.word/src/org/graalvm/api/word/PointerBase.java Tue Jun 13 09:19:35 2017 -0700
@@ -4,7 +4,9 @@
*
* 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.
+ * 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
--- a/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.api.word/src/org/graalvm/api/word/PointerUtils.java Tue Jun 13 07:30:11 2017 -0400
+++ b/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.api.word/src/org/graalvm/api/word/PointerUtils.java Tue Jun 13 09:19:35 2017 -0700
@@ -4,7 +4,9 @@
*
* 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.
+ * 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
--- a/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.api.word/src/org/graalvm/api/word/Signed.java Tue Jun 13 07:30:11 2017 -0400
+++ b/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.api.word/src/org/graalvm/api/word/Signed.java Tue Jun 13 09:19:35 2017 -0700
@@ -4,7 +4,9 @@
*
* 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.
+ * 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
--- a/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.api.word/src/org/graalvm/api/word/Unsigned.java Tue Jun 13 07:30:11 2017 -0400
+++ b/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.api.word/src/org/graalvm/api/word/Unsigned.java Tue Jun 13 09:19:35 2017 -0700
@@ -4,7 +4,9 @@
*
* 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.
+ * 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
--- a/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.api.word/src/org/graalvm/api/word/UnsignedUtils.java Tue Jun 13 07:30:11 2017 -0400
+++ b/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.api.word/src/org/graalvm/api/word/UnsignedUtils.java Tue Jun 13 09:19:35 2017 -0700
@@ -4,7 +4,9 @@
*
* 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.
+ * 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
--- a/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.api.word/src/org/graalvm/api/word/WordBase.java Tue Jun 13 07:30:11 2017 -0400
+++ b/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.api.word/src/org/graalvm/api/word/WordBase.java Tue Jun 13 09:19:35 2017 -0700
@@ -4,7 +4,9 @@
*
* 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.
+ * 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
--- a/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.api.word/src/org/graalvm/api/word/WordFactory.java Tue Jun 13 07:30:11 2017 -0400
+++ b/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.api.word/src/org/graalvm/api/word/WordFactory.java Tue Jun 13 09:19:35 2017 -0700
@@ -4,7 +4,9 @@
*
* 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.
+ * 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
--- a/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.aarch64/src/org/graalvm/compiler/core/aarch64/AArch64AddressLowering.java Tue Jun 13 07:30:11 2017 -0400
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,44 +0,0 @@
-/*
- * Copyright (c) 2015, 2016, 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.core.aarch64;
-
-import org.graalvm.compiler.nodes.ValueNode;
-import org.graalvm.compiler.nodes.memory.address.AddressNode;
-import org.graalvm.compiler.phases.common.AddressLoweringPhase.AddressLowering;
-
-public class AArch64AddressLowering extends AddressLowering {
-
- @Override
- public AddressNode lower(ValueNode address) {
- return lower(address, null);
- }
-
- @Override
- public AddressNode lower(ValueNode base, ValueNode offset) {
- AArch64AddressNode ret = new AArch64AddressNode(base, offset);
- // TODO improve
- return base.graph().unique(ret);
- }
-
-}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.aarch64/src/org/graalvm/compiler/core/aarch64/AArch64AddressLoweringByUse.java Tue Jun 13 09:19:35 2017 -0700
@@ -0,0 +1,227 @@
+/*
+ * Copyright (c) 2015, 2016, 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.
+ *
+ * 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.core.aarch64;
+
+import jdk.vm.ci.aarch64.AArch64Kind;
+import jdk.vm.ci.meta.JavaConstant;
+import org.graalvm.compiler.asm.aarch64.AArch64Address;
+import org.graalvm.compiler.core.common.LIRKind;
+import org.graalvm.compiler.core.common.NumUtil;
+import org.graalvm.compiler.core.common.type.Stamp;
+import org.graalvm.compiler.nodes.ValueNode;
+import org.graalvm.compiler.nodes.calc.AddNode;
+import org.graalvm.compiler.nodes.memory.address.AddressNode;
+import org.graalvm.compiler.nodes.memory.address.OffsetAddressNode;
+import org.graalvm.compiler.nodes.memory.address.RawAddressNode;
+import org.graalvm.compiler.phases.common.AddressLoweringByUsePhase;
+
+public class AArch64AddressLoweringByUse extends AddressLoweringByUsePhase.AddressLoweringByUse {
+ private AArch64LIRKindTool kindtool;
+
+ public AArch64AddressLoweringByUse(AArch64LIRKindTool kindtool) {
+ this.kindtool = kindtool;
+ }
+
+ @Override
+ public AddressNode lower(ValueNode use, Stamp stamp, AddressNode address) {
+ if (address instanceof RawAddressNode) {
+ return doLower(stamp, address.getBase(), null);
+ } else if (address instanceof OffsetAddressNode) {
+ OffsetAddressNode offsetAddress = (OffsetAddressNode) address;
+ return doLower(stamp, offsetAddress.getBase(), offsetAddress.getOffset());
+ } else {
+ // must be an already transformed AArch64AddressNode
+ return address;
+ }
+ }
+
+ @Override
+ public AddressNode lower(AddressNode address) {
+ return lower(null, null, address);
+ }
+
+ private AddressNode doLower(Stamp stamp, ValueNode base, ValueNode index) {
+ AArch64AddressNode ret = new AArch64AddressNode(base, index);
+ AArch64Kind aarch64Kind = (stamp == null ? null : getAArch64Kind(stamp));
+
+ // improve the address as much as possible
+ boolean changed;
+ do {
+ changed = improve(aarch64Kind, ret);
+ } while (changed);
+
+ // avoid duplicates
+ return base.graph().unique(ret);
+ }
+
+ protected boolean improve(AArch64Kind kind, AArch64AddressNode ret) {
+ AArch64Address.AddressingMode mode = ret.getAddressingMode();
+ // if we have already set a displacement or set to base only mode then we are done
+ if (isDisplacementMode(mode) || isBaseOnlyMode(mode)) {
+ return false;
+ }
+ ValueNode base = ret.getBase();
+ ValueNode index = ret.getIndex();
+
+ // avoid a constant or null base if possible
+ if (base == null) {
+ ret.setBase(index);
+ ret.setIndex(base);
+ return true;
+ }
+ // make sure any integral JavaConstant
+ // is the index rather than the base
+ // strictly we don't need the conditions on index
+ // as we ought not to see two JavaConstant values
+ if (base.isJavaConstant() && base.asJavaConstant().getJavaKind().isNumericInteger() &&
+ index != null && !index.isJavaConstant()) {
+ ret.setBase(index);
+ ret.setIndex(base);
+ return true;
+ }
+
+ // if the base is an add then move it up
+ if (index == null && base instanceof AddNode) {
+ AddNode add = (AddNode) base;
+ ret.setBase(add.getX());
+ ret.setIndex(add.getY());
+ return true;
+ }
+
+ // we can try to fold a JavaConstant index into a displacement
+ if (index != null && index.isJavaConstant()) {
+ JavaConstant javaConstant = index.asJavaConstant();
+ if (javaConstant.getJavaKind().isNumericInteger()) {
+ long disp = javaConstant.asLong();
+ mode = immediateMode(kind, disp);
+ if (isDisplacementMode(mode)) {
+ index = null;
+ // we can fold this in as a displacement
+ // but first see if we can pull up any additional
+ // constants added into the base
+ boolean tryNextBase = (base instanceof AddNode);
+ while (tryNextBase) {
+ AddNode add = (AddNode) base;
+ tryNextBase = false;
+ ValueNode child = add.getX();
+ if (child.isJavaConstant() && child.asJavaConstant().getJavaKind().isNumericInteger()) {
+ long newDisp = disp + child.asJavaConstant().asLong();
+ AArch64Address.AddressingMode newMode = immediateMode(kind, newDisp);
+ if (newMode != AArch64Address.AddressingMode.REGISTER_OFFSET) {
+ disp = newDisp;
+ mode = newMode;
+ base = add.getY();
+ ret.setBase(base);
+ tryNextBase = (base instanceof AddNode);
+ }
+ } else {
+ child = add.getY();
+ if (child.isJavaConstant() && child.asJavaConstant().getJavaKind().isNumericInteger()) {
+ long newDisp = disp + child.asJavaConstant().asLong();
+ AArch64Address.AddressingMode newMode = immediateMode(kind, newDisp);
+ if (newMode != AArch64Address.AddressingMode.REGISTER_OFFSET) {
+ disp = newDisp;
+ mode = newMode;
+ base = add.getX();
+ ret.setBase(base);
+ tryNextBase = (base instanceof AddNode);
+ }
+ }
+ }
+ }
+ if (disp != 0) {
+ // ok now set the displacement in place of an index
+ ret.setIndex(null);
+ int scaleFactor = computeScaleFactor(kind, mode);
+ ret.setDisplacement(disp, scaleFactor, mode);
+ } else {
+ // reset to base register only
+ ret.setIndex(null);
+ ret.setDisplacement(0, 1, AArch64Address.AddressingMode.BASE_REGISTER_ONLY);
+ }
+ return true;
+ }
+ }
+ }
+ // nope cannot improve this any more
+ return false;
+ }
+
+ private AArch64Kind getAArch64Kind(Stamp stamp) {
+ LIRKind lirKind = stamp.getLIRKind(kindtool);
+ if (!lirKind.isValue()) {
+ if (!lirKind.isReference(0) || lirKind.getReferenceCount() != 1) {
+ return null;
+ }
+ }
+
+ return (AArch64Kind) lirKind.getPlatformKind();
+ }
+
+ private static AArch64Address.AddressingMode immediateMode(AArch64Kind kind, long value) {
+ if (kind != null) {
+ int size = kind.getSizeInBytes();
+ // this next test should never really fail
+ if ((value & (size - 1)) == 0) {
+ long encodedValue = value / size;
+ // assert value % size == 0
+ // we can try for a 12 bit scaled offset
+ if (NumUtil.isUnsignedNbit(12, encodedValue)) {
+ return AArch64Address.AddressingMode.IMMEDIATE_SCALED;
+ }
+ }
+ }
+
+ // we can try for a 9 bit unscaled offset
+ if (NumUtil.isSignedNbit(9, value)) {
+ return AArch64Address.AddressingMode.IMMEDIATE_UNSCALED;
+ }
+
+ // nope this index needs to be passed via offset register
+ return AArch64Address.AddressingMode.REGISTER_OFFSET;
+ }
+
+ private static int computeScaleFactor(AArch64Kind kind, AArch64Address.AddressingMode mode) {
+ if (mode == AArch64Address.AddressingMode.IMMEDIATE_SCALED) {
+ return kind.getSizeInBytes();
+ }
+ return 1;
+ }
+
+ boolean isBaseOnlyMode(AArch64Address.AddressingMode addressingMode) {
+ return addressingMode == AArch64Address.AddressingMode.BASE_REGISTER_ONLY;
+ }
+
+ private static boolean isDisplacementMode(AArch64Address.AddressingMode addressingMode) {
+ switch (addressingMode) {
+ case IMMEDIATE_POST_INDEXED:
+ case IMMEDIATE_PRE_INDEXED:
+ case IMMEDIATE_SCALED:
+ case IMMEDIATE_UNSCALED:
+ return true;
+ }
+ return false;
+ }
+}
--- a/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.aarch64/src/org/graalvm/compiler/core/aarch64/AArch64AddressNode.java Tue Jun 13 07:30:11 2017 -0400
+++ b/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.aarch64/src/org/graalvm/compiler/core/aarch64/AArch64AddressNode.java Tue Jun 13 09:19:35 2017 -0700
@@ -26,7 +26,6 @@
import org.graalvm.compiler.asm.aarch64.AArch64Address;
import org.graalvm.compiler.asm.aarch64.AArch64Address.AddressingMode;
import org.graalvm.compiler.core.common.LIRKind;
-import org.graalvm.compiler.debug.GraalError;
import org.graalvm.compiler.graph.NodeClass;
import org.graalvm.compiler.lir.aarch64.AArch64AddressValue;
import org.graalvm.compiler.lir.gen.LIRGeneratorTool;
@@ -40,7 +39,7 @@
import jdk.vm.ci.meta.Value;
/**
- * Represents an address of the form... TODO.
+ * Represents an AArch64 address in the graph.
*/
@NodeInfo
public class AArch64AddressNode extends AddressNode implements LIRLowerable {
@@ -52,7 +51,8 @@
@OptionalInput private ValueNode index;
private AArch64Address.AddressingMode addressingMode;
- private int displacement;
+ private long displacement;
+ private int scaleFactor;
public AArch64AddressNode(ValueNode base) {
this(base, null);
@@ -63,6 +63,8 @@
this.base = base;
this.index = index;
this.addressingMode = AddressingMode.REGISTER_OFFSET;
+ this.displacement = 0;
+ this.scaleFactor = 1;
}
@Override
@@ -76,7 +78,6 @@
AllocatableValue indexReference;
if (addressingMode.equals(AddressingMode.IMMEDIATE_UNSCALED)) {
indexReference = LIRKind.derivedBaseFromValue(indexValue);
- throw GraalError.unimplemented();
} else {
if (LIRKind.isValue(indexValue.getValueKind())) {
indexReference = null;
@@ -86,8 +87,7 @@
}
LIRKind kind = LIRKind.combineDerived(tool.getLIRKind(stamp()), baseReference, indexReference);
- final boolean scaled = false;
- gen.setResult(this, new AArch64AddressValue(kind, baseValue, indexValue, displacement, scaled, addressingMode));
+ gen.setResult(this, new AArch64AddressValue(kind, baseValue, indexValue, (int) displacement, scaleFactor, addressingMode));
}
@Override
@@ -116,16 +116,22 @@
this.index = index;
}
- public int getDisplacement() {
+ public long getDisplacement() {
return displacement;
}
- public void setDisplacement(int displacement) {
+ public void setDisplacement(long displacement, int scaleFactor, AArch64Address.AddressingMode addressingMode) {
this.displacement = displacement;
+ this.scaleFactor = scaleFactor;
+ this.addressingMode = addressingMode;
}
@Override
public long getMaxConstantDisplacement() {
- return Long.MAX_VALUE;
+ return displacement;
+ }
+
+ public AddressingMode getAddressingMode() {
+ return addressingMode;
}
}
--- a/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.aarch64/src/org/graalvm/compiler/core/aarch64/AArch64LIRGenerator.java Tue Jun 13 07:30:11 2017 -0400
+++ b/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.aarch64/src/org/graalvm/compiler/core/aarch64/AArch64LIRGenerator.java Tue Jun 13 09:19:35 2017 -0700
@@ -120,7 +120,7 @@
if (address instanceof AArch64AddressValue) {
return (AArch64AddressValue) address;
} else {
- return new AArch64AddressValue(address.getValueKind(), asAllocatable(address), Value.ILLEGAL, 0, false, AddressingMode.BASE_REGISTER_ONLY);
+ return new AArch64AddressValue(address.getValueKind(), asAllocatable(address), Value.ILLEGAL, 0, 1, AddressingMode.BASE_REGISTER_ONLY);
}
}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.aarch64/src/org/graalvm/compiler/core/aarch64/AArch64SuitesCreator.java Tue Jun 13 09:19:35 2017 -0700
@@ -0,0 +1,35 @@
+/*
+ * Copyright (c) 2015, 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.core.aarch64;
+
+import org.graalvm.compiler.java.DefaultSuitesCreator;
+import org.graalvm.compiler.nodes.graphbuilderconf.GraphBuilderConfiguration.Plugins;
+import org.graalvm.compiler.phases.tiers.CompilerConfiguration;
+
+public class AArch64SuitesCreator extends DefaultSuitesCreator {
+
+ public AArch64SuitesCreator(CompilerConfiguration compilerConfiguration, Plugins plugins) {
+ super(compilerConfiguration, plugins);
+ }
+
+}
--- a/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.aarch64/src/org/graalvm/compiler/core/aarch64/AArch64SuitesProvider.java Tue Jun 13 07:30:11 2017 -0400
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,35 +0,0 @@
-/*
- * Copyright (c) 2015, 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.core.aarch64;
-
-import org.graalvm.compiler.java.DefaultSuitesProvider;
-import org.graalvm.compiler.nodes.graphbuilderconf.GraphBuilderConfiguration.Plugins;
-import org.graalvm.compiler.phases.tiers.CompilerConfiguration;
-
-public class AArch64SuitesProvider extends DefaultSuitesProvider {
-
- public AArch64SuitesProvider(CompilerConfiguration compilerConfiguration, Plugins plugins) {
- super(compilerConfiguration, plugins);
- }
-
-}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.amd64/src/org/graalvm/compiler/core/amd64/AMD64SuitesCreator.java Tue Jun 13 09:19:35 2017 -0700
@@ -0,0 +1,47 @@
+/*
+ * Copyright (c) 2015, 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.core.amd64;
+
+import org.graalvm.compiler.java.DefaultSuitesCreator;
+import org.graalvm.compiler.lir.amd64.phases.StackMoveOptimizationPhase;
+import org.graalvm.compiler.lir.phases.LIRSuites;
+import org.graalvm.compiler.nodes.graphbuilderconf.GraphBuilderConfiguration.Plugins;
+import org.graalvm.compiler.options.OptionValues;
+import org.graalvm.compiler.phases.tiers.CompilerConfiguration;
+
+public class AMD64SuitesCreator extends DefaultSuitesCreator {
+
+ public AMD64SuitesCreator(CompilerConfiguration compilerConfiguration, Plugins plugins) {
+ super(compilerConfiguration, plugins);
+ }
+
+ @Override
+ public LIRSuites createLIRSuites(OptionValues options) {
+ LIRSuites lirSuites = super.createLIRSuites(options);
+ if (StackMoveOptimizationPhase.Options.LIROptStackMoveOptimizer.getValue(options)) {
+ /* Note: this phase must be inserted <b>after</b> RedundantMoveElimination */
+ lirSuites.getPostAllocationOptimizationStage().appendPhase(new StackMoveOptimizationPhase());
+ }
+ return lirSuites;
+ }
+}
--- a/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.amd64/src/org/graalvm/compiler/core/amd64/AMD64SuitesProvider.java Tue Jun 13 07:30:11 2017 -0400
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,47 +0,0 @@
-/*
- * Copyright (c) 2015, 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.core.amd64;
-
-import org.graalvm.compiler.java.DefaultSuitesProvider;
-import org.graalvm.compiler.lir.amd64.phases.StackMoveOptimizationPhase;
-import org.graalvm.compiler.lir.phases.LIRSuites;
-import org.graalvm.compiler.nodes.graphbuilderconf.GraphBuilderConfiguration.Plugins;
-import org.graalvm.compiler.options.OptionValues;
-import org.graalvm.compiler.phases.tiers.CompilerConfiguration;
-
-public class AMD64SuitesProvider extends DefaultSuitesProvider {
-
- public AMD64SuitesProvider(CompilerConfiguration compilerConfiguration, Plugins plugins) {
- super(compilerConfiguration, plugins);
- }
-
- @Override
- public LIRSuites createLIRSuites(OptionValues options) {
- LIRSuites lirSuites = super.createLIRSuites(options);
- if (StackMoveOptimizationPhase.Options.LIROptStackMoveOptimizer.getValue(options)) {
- /* Note: this phase must be inserted <b>after</b> RedundantMoveElimination */
- lirSuites.getPostAllocationOptimizationStage().appendPhase(new StackMoveOptimizationPhase());
- }
- return lirSuites;
- }
-}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.sparc/src/org/graalvm/compiler/core/sparc/SPARCSuitesCreator.java Tue Jun 13 09:19:35 2017 -0700
@@ -0,0 +1,54 @@
+/*
+ * Copyright (c) 2015, 2016, 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.core.sparc;
+
+import java.util.ListIterator;
+
+import org.graalvm.compiler.java.DefaultSuitesCreator;
+import org.graalvm.compiler.nodes.graphbuilderconf.GraphBuilderConfiguration.Plugins;
+import org.graalvm.compiler.options.OptionValues;
+import org.graalvm.compiler.phases.BasePhase;
+import org.graalvm.compiler.phases.PhaseSuite;
+import org.graalvm.compiler.phases.common.ExpandLogicPhase;
+import org.graalvm.compiler.phases.tiers.CompilerConfiguration;
+import org.graalvm.compiler.phases.tiers.LowTierContext;
+import org.graalvm.compiler.phases.tiers.Suites;
+
+public class SPARCSuitesCreator extends DefaultSuitesCreator {
+
+ public SPARCSuitesCreator(CompilerConfiguration compilerConfiguration, Plugins plugins) {
+ super(compilerConfiguration, plugins);
+ }
+
+ @Override
+ public Suites createSuites(OptionValues options) {
+ Suites s = super.createSuites(options);
+ ListIterator<BasePhase<? super LowTierContext>> l = s.getLowTier().findPhase(ExpandLogicPhase.class);
+ while (PhaseSuite.findNextPhase(l, ExpandLogicPhase.class)) {
+ // Search for last occurrence of ExpandLogicPhase
+ }
+ l.previous();
+ l.add(new SPARCIntegerCompareCanonicalizationPhase());
+ return s;
+ }
+}
--- a/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.sparc/src/org/graalvm/compiler/core/sparc/SPARCSuitesProvider.java Tue Jun 13 07:30:11 2017 -0400
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,53 +0,0 @@
-/*
- * Copyright (c) 2015, 2016, 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.core.sparc;
-
-import java.util.ListIterator;
-
-import org.graalvm.compiler.java.DefaultSuitesProvider;
-import org.graalvm.compiler.nodes.graphbuilderconf.GraphBuilderConfiguration.Plugins;
-import org.graalvm.compiler.options.OptionValues;
-import org.graalvm.compiler.phases.BasePhase;
-import org.graalvm.compiler.phases.PhaseSuite;
-import org.graalvm.compiler.phases.common.ExpandLogicPhase;
-import org.graalvm.compiler.phases.tiers.CompilerConfiguration;
-import org.graalvm.compiler.phases.tiers.LowTierContext;
-import org.graalvm.compiler.phases.tiers.Suites;
-
-public class SPARCSuitesProvider extends DefaultSuitesProvider {
- public SPARCSuitesProvider(CompilerConfiguration compilerConfiguration, Plugins plugins) {
- super(compilerConfiguration, plugins);
- }
-
- @Override
- public Suites createSuites(OptionValues options) {
- Suites s = super.createSuites(options);
- ListIterator<BasePhase<? super LowTierContext>> l = s.getLowTier().findPhase(ExpandLogicPhase.class);
- while (PhaseSuite.findNextPhase(l, ExpandLogicPhase.class)) {
- // Search for last occurrence of ExpandLogicPhase
- }
- l.previous();
- l.add(new SPARCIntegerCompareCanonicalizationPhase());
- return s;
- }
-}
--- a/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core/src/org/graalvm/compiler/core/GraalCompiler.java Tue Jun 13 07:30:11 2017 -0400
+++ b/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core/src/org/graalvm/compiler/core/GraalCompiler.java Tue Jun 13 09:19:35 2017 -0700
@@ -310,7 +310,7 @@
LIRGenerationContext context = new LIRGenerationContext(lirGen, nodeLirGen, graph, schedule);
new LIRGenerationPhase().apply(backend.getTarget(), lirGenRes, context);
- try (Scope s = Debug.scope("LIRStages", nodeLirGen, lir)) {
+ try (Scope s = Debug.scope("LIRStages", nodeLirGen, lirGenRes, lir)) {
// Dump LIR along with HIR (the LIR is looked up from context)
Debug.dump(Debug.BASIC_LEVEL, graph.getLastSchedule(), "After LIR generation");
LIRGenerationResult result = emitLowLevel(backend.getTarget(), lirGenRes, lirGen, lirSuites, backend.newRegisterAllocationConfig(registerConfig, allocationRestrictedTo));
--- a/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.aarch64/src/org/graalvm/compiler/hotspot/aarch64/AArch64HotSpotBackendFactory.java Tue Jun 13 07:30:11 2017 -0400
+++ b/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.aarch64/src/org/graalvm/compiler/hotspot/aarch64/AArch64HotSpotBackendFactory.java Tue Jun 13 09:19:35 2017 -0700
@@ -27,8 +27,9 @@
import org.graalvm.compiler.api.replacements.SnippetReflectionProvider;
import org.graalvm.compiler.bytecode.BytecodeProvider;
-import org.graalvm.compiler.core.aarch64.AArch64AddressLowering;
-import org.graalvm.compiler.core.aarch64.AArch64SuitesProvider;
+import org.graalvm.compiler.core.aarch64.AArch64AddressLoweringByUse;
+import org.graalvm.compiler.core.aarch64.AArch64LIRKindTool;
+import org.graalvm.compiler.core.aarch64.AArch64SuitesCreator;
import org.graalvm.compiler.hotspot.GraalHotSpotVMConfig;
import org.graalvm.compiler.hotspot.HotSpotBackend;
import org.graalvm.compiler.hotspot.HotSpotBackendFactory;
@@ -176,7 +177,7 @@
}
protected HotSpotSuitesProvider createSuites(GraalHotSpotVMConfig config, HotSpotGraalRuntimeProvider runtime, CompilerConfiguration compilerConfiguration, Plugins plugins) {
- return new HotSpotSuitesProvider(new AArch64SuitesProvider(compilerConfiguration, plugins), config, runtime, new AArch64AddressLowering());
+ return new AArch64HotSpotSuitesProvider(new AArch64SuitesCreator(compilerConfiguration, plugins), config, runtime, new AArch64AddressLoweringByUse(new AArch64LIRKindTool()));
}
protected HotSpotSnippetReflectionProvider createSnippetReflection(HotSpotGraalRuntimeProvider runtime, HotSpotConstantReflectionProvider constantReflection, WordTypes wordTypes) {
--- a/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.aarch64/src/org/graalvm/compiler/hotspot/aarch64/AArch64HotSpotLIRGenerator.java Tue Jun 13 07:30:11 2017 -0400
+++ b/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.aarch64/src/org/graalvm/compiler/hotspot/aarch64/AArch64HotSpotLIRGenerator.java Tue Jun 13 09:19:35 2017 -0700
@@ -36,7 +36,6 @@
import org.graalvm.compiler.core.aarch64.AArch64LIRKindTool;
import org.graalvm.compiler.core.common.CompressEncoding;
import org.graalvm.compiler.core.common.LIRKind;
-import org.graalvm.compiler.core.common.NumUtil;
import org.graalvm.compiler.core.common.calc.Condition;
import org.graalvm.compiler.core.common.spi.ForeignCallLinkage;
import org.graalvm.compiler.core.common.spi.LIRKindTool;
@@ -321,8 +320,7 @@
LIRKind wordKind = LIRKind.value(target().arch.getWordKind());
RegisterValue thread = getProviders().getRegisters().getThreadRegister().asValue(wordKind);
final int transferSize = value.getValueKind().getPlatformKind().getSizeInBytes();
- final int scaledDisplacement = offset >> NumUtil.log2Ceil(transferSize);
- AArch64AddressValue address = new AArch64AddressValue(value.getValueKind(), thread, Value.ILLEGAL, scaledDisplacement, true, AddressingMode.IMMEDIATE_SCALED);
+ AArch64AddressValue address = new AArch64AddressValue(value.getValueKind(), thread, Value.ILLEGAL, offset, transferSize, AddressingMode.IMMEDIATE_SCALED);
append(new StoreOp((AArch64Kind) value.getPlatformKind(), address, loadReg(value), null));
}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.aarch64/src/org/graalvm/compiler/hotspot/aarch64/AArch64HotSpotSuitesProvider.java Tue Jun 13 09:19:35 2017 -0700
@@ -0,0 +1,65 @@
+/*
+ * Copyright (c) 2017, 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.
+ *
+ * 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.hotspot.aarch64;
+
+import org.graalvm.compiler.hotspot.GraalHotSpotVMConfig;
+import org.graalvm.compiler.hotspot.HotSpotGraalRuntimeProvider;
+import org.graalvm.compiler.hotspot.meta.HotSpotSuitesProvider;
+import org.graalvm.compiler.options.OptionValues;
+import org.graalvm.compiler.phases.BasePhase;
+import org.graalvm.compiler.phases.common.AddressLoweringByUsePhase;
+import org.graalvm.compiler.phases.common.ExpandLogicPhase;
+import org.graalvm.compiler.phases.common.FixReadsPhase;
+import org.graalvm.compiler.phases.tiers.LowTierContext;
+import org.graalvm.compiler.phases.tiers.Suites;
+import org.graalvm.compiler.phases.tiers.SuitesCreator;
+
+import java.util.ListIterator;
+
+/**
+ * Subclass to factor out management of address lowering.
+ */
+public class AArch64HotSpotSuitesProvider extends HotSpotSuitesProvider {
+
+ private final AddressLoweringByUsePhase.AddressLoweringByUse addressLoweringByUse;
+
+ public AArch64HotSpotSuitesProvider(SuitesCreator defaultSuitesCreator, GraalHotSpotVMConfig config, HotSpotGraalRuntimeProvider runtime,
+ AddressLoweringByUsePhase.AddressLoweringByUse addressLoweringByUse) {
+ super(defaultSuitesCreator, config, runtime);
+ this.addressLoweringByUse = addressLoweringByUse;
+ }
+
+ @Override
+ public Suites createSuites(OptionValues options) {
+ Suites suites = super.createSuites(options);
+
+ ListIterator<BasePhase<? super LowTierContext>> findPhase = suites.getLowTier().findPhase(FixReadsPhase.class);
+ if (findPhase == null) {
+ findPhase = suites.getLowTier().findPhase(ExpandLogicPhase.class);
+ }
+ findPhase.add(new AddressLoweringByUsePhase(addressLoweringByUse));
+
+ return suites;
+ }
+}
--- a/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.amd64/src/org/graalvm/compiler/hotspot/amd64/AMD64HotSpotBackendFactory.java Tue Jun 13 07:30:11 2017 -0400
+++ b/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.amd64/src/org/graalvm/compiler/hotspot/amd64/AMD64HotSpotBackendFactory.java Tue Jun 13 09:19:35 2017 -0700
@@ -35,6 +35,7 @@
import org.graalvm.compiler.hotspot.HotSpotBackendFactory;
import org.graalvm.compiler.hotspot.HotSpotGraalRuntimeProvider;
import org.graalvm.compiler.hotspot.HotSpotReplacementsImpl;
+import org.graalvm.compiler.hotspot.meta.AddressLoweringHotSpotSuitesProvider;
import org.graalvm.compiler.hotspot.meta.HotSpotForeignCallsProvider;
import org.graalvm.compiler.hotspot.meta.HotSpotGraalConstantFieldProvider;
import org.graalvm.compiler.hotspot.meta.HotSpotGraphBuilderPlugins;
@@ -182,7 +183,7 @@
*/
protected HotSpotSuitesProvider createSuites(GraalHotSpotVMConfig config, HotSpotGraalRuntimeProvider runtime, CompilerConfiguration compilerConfiguration, Plugins plugins,
HotSpotRegistersProvider registers, Replacements replacements, OptionValues options) {
- return new HotSpotSuitesProvider(new AMD64HotSpotSuitesProvider(compilerConfiguration, plugins), config, runtime,
+ return new AddressLoweringHotSpotSuitesProvider(new AMD64HotSpotSuitesCreator(compilerConfiguration, plugins), config, runtime,
new AMD64HotSpotAddressLowering(config, registers.getHeapBaseRegister(), options));
}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.amd64/src/org/graalvm/compiler/hotspot/amd64/AMD64HotSpotSuitesCreator.java Tue Jun 13 09:19:35 2017 -0700
@@ -0,0 +1,47 @@
+/*
+ * Copyright (c) 2016, 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.hotspot.amd64;
+
+import org.graalvm.compiler.core.amd64.AMD64SuitesCreator;
+import org.graalvm.compiler.core.common.GraalOptions;
+import org.graalvm.compiler.hotspot.lir.HotSpotZapRegistersPhase;
+import org.graalvm.compiler.lir.phases.LIRSuites;
+import org.graalvm.compiler.nodes.graphbuilderconf.GraphBuilderConfiguration.Plugins;
+import org.graalvm.compiler.options.OptionValues;
+import org.graalvm.compiler.phases.tiers.CompilerConfiguration;
+
+public class AMD64HotSpotSuitesCreator extends AMD64SuitesCreator {
+
+ public AMD64HotSpotSuitesCreator(CompilerConfiguration compilerConfiguration, Plugins plugins) {
+ super(compilerConfiguration, plugins);
+ }
+
+ @Override
+ public LIRSuites createLIRSuites(OptionValues options) {
+ LIRSuites lirSuites = super.createLIRSuites(options);
+ if (GraalOptions.DetailedAsserts.getValue(options)) {
+ lirSuites.getPostAllocationOptimizationStage().appendPhase(new HotSpotZapRegistersPhase());
+ }
+ return lirSuites;
+ }
+}
--- a/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.amd64/src/org/graalvm/compiler/hotspot/amd64/AMD64HotSpotSuitesProvider.java Tue Jun 13 07:30:11 2017 -0400
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,47 +0,0 @@
-/*
- * Copyright (c) 2016, 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.hotspot.amd64;
-
-import org.graalvm.compiler.core.amd64.AMD64SuitesProvider;
-import org.graalvm.compiler.core.common.GraalOptions;
-import org.graalvm.compiler.hotspot.lir.HotSpotZapRegistersPhase;
-import org.graalvm.compiler.lir.phases.LIRSuites;
-import org.graalvm.compiler.nodes.graphbuilderconf.GraphBuilderConfiguration.Plugins;
-import org.graalvm.compiler.options.OptionValues;
-import org.graalvm.compiler.phases.tiers.CompilerConfiguration;
-
-public class AMD64HotSpotSuitesProvider extends AMD64SuitesProvider {
-
- public AMD64HotSpotSuitesProvider(CompilerConfiguration compilerConfiguration, Plugins plugins) {
- super(compilerConfiguration, plugins);
- }
-
- @Override
- public LIRSuites createLIRSuites(OptionValues options) {
- LIRSuites lirSuites = super.createLIRSuites(options);
- if (GraalOptions.DetailedAsserts.getValue(options)) {
- lirSuites.getPostAllocationOptimizationStage().appendPhase(new HotSpotZapRegistersPhase());
- }
- return lirSuites;
- }
-}
--- a/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.sparc/src/org/graalvm/compiler/hotspot/sparc/SPARCHotSpotBackendFactory.java Tue Jun 13 07:30:11 2017 -0400
+++ b/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.sparc/src/org/graalvm/compiler/hotspot/sparc/SPARCHotSpotBackendFactory.java Tue Jun 13 09:19:35 2017 -0700
@@ -27,12 +27,13 @@
import org.graalvm.compiler.bytecode.BytecodeProvider;
import org.graalvm.compiler.core.sparc.SPARCAddressLowering;
-import org.graalvm.compiler.core.sparc.SPARCSuitesProvider;
+import org.graalvm.compiler.core.sparc.SPARCSuitesCreator;
import org.graalvm.compiler.hotspot.GraalHotSpotVMConfig;
import org.graalvm.compiler.hotspot.HotSpotBackend;
import org.graalvm.compiler.hotspot.HotSpotBackendFactory;
import org.graalvm.compiler.hotspot.HotSpotGraalRuntimeProvider;
import org.graalvm.compiler.hotspot.HotSpotReplacementsImpl;
+import org.graalvm.compiler.hotspot.meta.AddressLoweringHotSpotSuitesProvider;
import org.graalvm.compiler.hotspot.meta.HotSpotConstantFieldProvider;
import org.graalvm.compiler.hotspot.meta.HotSpotForeignCallsProvider;
import org.graalvm.compiler.hotspot.meta.HotSpotGraalConstantFieldProvider;
@@ -123,7 +124,7 @@
*/
protected HotSpotSuitesProvider createSuites(GraalHotSpotVMConfig config, HotSpotGraalRuntimeProvider runtime, CompilerConfiguration compilerConfiguration, Plugins plugins,
Replacements replacements) {
- return new HotSpotSuitesProvider(new SPARCSuitesProvider(compilerConfiguration, plugins), config, runtime, new SPARCAddressLowering());
+ return new AddressLoweringHotSpotSuitesProvider(new SPARCSuitesCreator(compilerConfiguration, plugins), config, runtime, new SPARCAddressLowering());
}
protected SPARCHotSpotBackend createBackend(GraalHotSpotVMConfig config, HotSpotGraalRuntimeProvider runtime, HotSpotProviders providers) {
--- a/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.test/src/org/graalvm/compiler/hotspot/test/HotSpotGraalMBeanTest.java Tue Jun 13 07:30:11 2017 -0400
+++ b/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.test/src/org/graalvm/compiler/hotspot/test/HotSpotGraalMBeanTest.java Tue Jun 13 09:19:35 2017 -0700
@@ -22,14 +22,34 @@
*/
package org.graalvm.compiler.hotspot.test;
+import java.lang.annotation.Annotation;
import java.lang.management.ManagementFactory;
import java.lang.reflect.Field;
+import java.lang.reflect.Type;
import javax.management.Attribute;
import javax.management.MBeanAttributeInfo;
import javax.management.MBeanInfo;
+import javax.management.MBeanOperationInfo;
import javax.management.MBeanServer;
import javax.management.ObjectInstance;
import javax.management.ObjectName;
+import jdk.vm.ci.hotspot.HotSpotResolvedJavaMethod;
+import jdk.vm.ci.hotspot.HotSpotResolvedObjectType;
+import jdk.vm.ci.meta.Assumptions;
+import jdk.vm.ci.meta.Constant;
+import jdk.vm.ci.meta.ConstantPool;
+import jdk.vm.ci.meta.ExceptionHandler;
+import jdk.vm.ci.meta.JavaConstant;
+import jdk.vm.ci.meta.JavaKind;
+import jdk.vm.ci.meta.LineNumberTable;
+import jdk.vm.ci.meta.LocalVariableTable;
+import jdk.vm.ci.meta.ProfilingInfo;
+import jdk.vm.ci.meta.ResolvedJavaField;
+import jdk.vm.ci.meta.ResolvedJavaMethod;
+import jdk.vm.ci.meta.ResolvedJavaType;
+import jdk.vm.ci.meta.Signature;
+import jdk.vm.ci.meta.SpeculationLog;
+import org.graalvm.compiler.debug.GraalDebugConfig;
import org.graalvm.compiler.hotspot.HotSpotGraalMBean;
import org.graalvm.compiler.options.OptionValues;
import org.graalvm.util.EconomicMap;
@@ -57,7 +77,7 @@
}
assertNull("The platformMBeanServer isn't initialized now", field.get(null));
- HotSpotGraalMBean bean = HotSpotGraalMBean.create();
+ HotSpotGraalMBean bean = HotSpotGraalMBean.create(null);
assertNotNull("Bean created", bean);
assertNull("It is not registered yet", bean.ensureRegistered(true));
@@ -82,7 +102,7 @@
assertNotNull("Server is started", ManagementFactory.getPlatformMBeanServer());
- HotSpotGraalMBean realBean = HotSpotGraalMBean.create();
+ HotSpotGraalMBean realBean = HotSpotGraalMBean.create(null);
assertNotNull("Bean is registered", name = realBean.ensureRegistered(false));
final MBeanServer server = ManagementFactory.getPlatformMBeanServer();
@@ -124,7 +144,7 @@
assertNotNull("Server is started", ManagementFactory.getPlatformMBeanServer());
- HotSpotGraalMBean realBean = HotSpotGraalMBean.create();
+ HotSpotGraalMBean realBean = HotSpotGraalMBean.create(null);
OptionValues original = new OptionValues(EconomicMap.create());
@@ -153,4 +173,533 @@
}
+ @Test
+ public void dumpOperation() throws Exception {
+ Field field = null;
+ try {
+ field = stopMBeanServer();
+ } catch (Exception ex) {
+ if (ex.getClass().getName().equals("java.lang.reflect.InaccessibleObjectException")) {
+ // skip on JDK9
+ return;
+ }
+ }
+ assertNull("The platformMBeanServer isn't initialized now", field.get(null));
+
+ ObjectName name;
+
+ assertNotNull("Server is started", ManagementFactory.getPlatformMBeanServer());
+
+ HotSpotGraalMBean realBean = HotSpotGraalMBean.create(null);
+
+ assertNotNull("Bean is registered", name = realBean.ensureRegistered(false));
+ final MBeanServer server = ManagementFactory.getPlatformMBeanServer();
+
+ ObjectInstance bean = server.getObjectInstance(name);
+ assertNotNull("Bean is registered", bean);
+
+ MBeanInfo info = server.getMBeanInfo(name);
+ assertNotNull("Info is found", info);
+
+ final MBeanOperationInfo[] arr = info.getOperations();
+ assertEquals("Currently three overloads", 3, arr.length);
+ MBeanOperationInfo dumpOp = null;
+ for (int i = 0; i < arr.length; i++) {
+ assertEquals("dumpMethod", arr[i].getName());
+ if (arr[i].getSignature().length == 3) {
+ dumpOp = arr[i];
+ }
+ }
+ assertNotNull("three args variant found", dumpOp);
+
+ server.invoke(name, "dumpMethod", new Object[]{
+ "java.util.Arrays", "asList", ":3"
+ }, null);
+
+ MBeanAttributeInfo dump = findAttributeInfo("Dump", info);
+ Attribute dumpTo1 = new Attribute(dump.getName(), "");
+ server.setAttribute(name, dumpTo1);
+ Object after = server.getAttribute(name, dump.getName());
+ assertEquals("", after);
+
+ OptionValues empty = new OptionValues(EconomicMap.create());
+ OptionValues unsetDump = realBean.optionsFor(empty, null);
+
+ final OptionValues forMethod = realBean.optionsFor(unsetDump, new MockResolvedJavaMethod());
+ assertNotSame(unsetDump, forMethod);
+ Object nothing = unsetDump.getMap().get(GraalDebugConfig.Options.Dump);
+ assertEquals("Empty string", "", nothing);
+
+ Object specialValue = forMethod.getMap().get(GraalDebugConfig.Options.Dump);
+ assertEquals(":3", specialValue);
+
+ OptionValues normalMethod = realBean.optionsFor(unsetDump, null);
+ Object noSpecialValue = normalMethod.getMap().get(GraalDebugConfig.Options.Dump);
+ assertEquals("Empty string", "", noSpecialValue);
+ }
+
+ private static class MockResolvedJavaMethod implements HotSpotResolvedJavaMethod {
+ MockResolvedJavaMethod() {
+ }
+
+ @Override
+ public boolean isCallerSensitive() {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public HotSpotResolvedObjectType getDeclaringClass() {
+ return new MockResolvedObjectType();
+ }
+
+ @Override
+ public boolean isForceInline() {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public boolean hasReservedStackAccess() {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public void setNotInlineable() {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public boolean ignoredBySecurityStackWalk() {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public ResolvedJavaMethod uniqueConcreteMethod(HotSpotResolvedObjectType receiver) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public boolean hasCompiledCode() {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public boolean hasCompiledCodeAtLevel(int level) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public int vtableEntryOffset(ResolvedJavaType resolved) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public int intrinsicId() {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public int allocateCompileId(int entryBCI) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public boolean hasCodeAtLevel(int entryBCI, int level) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public byte[] getCode() {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public int getCodeSize() {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public int getMaxLocals() {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public int getMaxStackSize() {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public boolean isSynthetic() {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public boolean isVarArgs() {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public boolean isBridge() {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public boolean isClassInitializer() {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public boolean isConstructor() {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public boolean canBeStaticallyBound() {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public ExceptionHandler[] getExceptionHandlers() {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public StackTraceElement asStackTraceElement(int bci) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public ProfilingInfo getProfilingInfo(boolean includeNormal, boolean includeOSR) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public void reprofile() {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public ConstantPool getConstantPool() {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public Annotation[][] getParameterAnnotations() {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public Type[] getGenericParameterTypes() {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public boolean canBeInlined() {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public boolean hasNeverInlineDirective() {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public boolean shouldBeInlined() {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public LineNumberTable getLineNumberTable() {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public LocalVariableTable getLocalVariableTable() {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public Constant getEncoding() {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public boolean isInVirtualMethodTable(ResolvedJavaType resolved) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public SpeculationLog getSpeculationLog() {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public String getName() {
+ return "asList";
+ }
+
+ @Override
+ public Signature getSignature() {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public int getModifiers() {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public <T extends Annotation> T getAnnotation(Class<T> annotationClass) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public Annotation[] getAnnotations() {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public Annotation[] getDeclaredAnnotations() {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public boolean isIntrinsicCandidate() {
+ return true;
+ }
+
+ private static class MockResolvedObjectType implements HotSpotResolvedObjectType {
+ MockResolvedObjectType() {
+ }
+
+ @Override
+ public long getFingerprint() {
+ return 0L;
+ }
+
+ @Override
+ public HotSpotResolvedObjectType getArrayClass() {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public ResolvedJavaType getComponentType() {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public Assumptions.AssumptionResult<ResolvedJavaType> findLeafConcreteSubtype() {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public HotSpotResolvedObjectType getSuperclass() {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public HotSpotResolvedObjectType[] getInterfaces() {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public HotSpotResolvedObjectType getSupertype() {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public HotSpotResolvedObjectType findLeastCommonAncestor(ResolvedJavaType otherType) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public ConstantPool getConstantPool() {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public int instanceSize() {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public int getVtableLength() {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public Assumptions.AssumptionResult<ResolvedJavaMethod> findUniqueConcreteMethod(ResolvedJavaMethod method) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public boolean isDefinitelyResolvedWithRespectTo(ResolvedJavaType accessingClass) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public Constant klass() {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public boolean isPrimaryType() {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public int superCheckOffset() {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public long prototypeMarkWord() {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public int layoutHelper() {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public HotSpotResolvedObjectType getEnclosingType() {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public ResolvedJavaMethod getClassInitializer() {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public boolean hasFinalizer() {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public Assumptions.AssumptionResult<Boolean> hasFinalizableSubclass() {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public boolean isInterface() {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public boolean isInstanceClass() {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public boolean isInitialized() {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public void initialize() {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public boolean isLinked() {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public boolean isAssignableFrom(ResolvedJavaType other) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public boolean isInstance(JavaConstant obj) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public ResolvedJavaType getSingleImplementor() {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public ResolvedJavaMethod resolveMethod(ResolvedJavaMethod method, ResolvedJavaType callerType) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public ResolvedJavaField[] getInstanceFields(boolean includeSuperclasses) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public ResolvedJavaField[] getStaticFields() {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public ResolvedJavaField findInstanceFieldWithOffset(long offset, JavaKind expectedKind) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public String getSourceFileName() {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public boolean isLocal() {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public boolean isMember() {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public ResolvedJavaMethod[] getDeclaredConstructors() {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public ResolvedJavaMethod[] getDeclaredMethods() {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public boolean isCloneableWithAllocation() {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public String getName() {
+ return "Ljava/util/Arrays;";
+ }
+
+ @Override
+ public ResolvedJavaType resolve(ResolvedJavaType accessingClass) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public int getModifiers() {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public <T extends Annotation> T getAnnotation(Class<T> annotationClass) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public Annotation[] getAnnotations() {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public Annotation[] getDeclaredAnnotations() {
+ throw new UnsupportedOperationException();
+ }
+ }
+ }
}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.test/src/org/graalvm/compiler/hotspot/test/ReplaceConstantNodesPhaseTest.java Tue Jun 13 09:19:35 2017 -0700
@@ -0,0 +1,162 @@
+/*
+ * Copyright (c) 2017, 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.hotspot.test;
+
+import org.graalvm.compiler.core.common.GraalOptions;
+import org.graalvm.compiler.hotspot.GraalHotSpotVMConfig;
+import org.graalvm.compiler.hotspot.meta.HotSpotClassInitializationPlugin;
+import org.graalvm.compiler.hotspot.nodes.aot.InitializeKlassNode;
+import org.graalvm.compiler.hotspot.nodes.aot.LoadConstantIndirectlyNode;
+import org.graalvm.compiler.hotspot.nodes.aot.ResolveConstantNode;
+import org.graalvm.compiler.hotspot.phases.LoadJavaMirrorWithKlassPhase;
+import org.graalvm.compiler.hotspot.phases.aot.EliminateRedundantInitializationPhase;
+import org.graalvm.compiler.hotspot.phases.aot.ReplaceConstantNodesPhase;
+import org.graalvm.compiler.nodes.StructuredGraph;
+import org.graalvm.compiler.nodes.StructuredGraph.AllowAssumptions;
+import org.graalvm.compiler.nodes.graphbuilderconf.GraphBuilderConfiguration.Plugins;
+import org.graalvm.compiler.nodes.spi.LoweringTool;
+import org.graalvm.compiler.options.OptionValues;
+import org.graalvm.compiler.phases.common.CanonicalizerPhase;
+import org.graalvm.compiler.phases.common.LoweringPhase;
+import org.graalvm.compiler.phases.tiers.HighTierContext;
+import org.junit.Assert;
+import org.junit.Test;
+
+public class ReplaceConstantNodesPhaseTest extends HotSpotGraalCompilerTest {
+ private final GraalHotSpotVMConfig config = runtime().getVMConfig();
+
+ @Override
+ protected Plugins getDefaultGraphBuilderPlugins() {
+ Plugins plugins = super.getDefaultGraphBuilderPlugins();
+ plugins.setClassInitializationPlugin(new HotSpotClassInitializationPlugin());
+ return plugins;
+ }
+
+ public static class X {
+ public static int x;
+ public static int y;
+ public static int z;
+ public static Object o;
+ }
+
+ public static class Y extends X {
+ public static int a;
+ public static int b;
+ }
+
+ public static int a;
+
+ public static void assignFields() {
+ X.x = 1;
+ X.y = 2;
+ X.z = 3;
+ }
+
+ public static void assignFieldsInBranches(boolean x) {
+ if (x) {
+ X.y = 1;
+ } else {
+ X.z = 2;
+ }
+ }
+
+ public static void assignFieldsWithDominatingInit(boolean x) {
+ X.x = 1;
+ if (x) {
+ X.y = 2;
+ } else {
+ X.z = 3;
+ }
+ }
+
+ public static void assignString() {
+ X.o = "foo";
+ }
+
+ public static void assignToParentAndChild() {
+ Y.a = 1;
+ X.x = 2;
+ }
+
+ public static void assignToThis() {
+ a = 1;
+ }
+
+ public static void assignFieldsWithDominatingInitOfParent(boolean x) {
+ Y.a = 1;
+ if (x) {
+ X.y = 2;
+ } else {
+ X.z = 3;
+ }
+ Y.b = 4;
+ }
+
+ private void test(String name, int expectedInits, int expectedResolves, int expectedLoads) {
+ StructuredGraph graph = parseEager(name, AllowAssumptions.NO, new OptionValues(getInitialOptions(), GraalOptions.GeneratePIC, true));
+ HighTierContext highTierContext = getDefaultHighTierContext();
+ CanonicalizerPhase canonicalizer = new CanonicalizerPhase();
+ new EliminateRedundantInitializationPhase().apply(graph, highTierContext);
+ new LoweringPhase(canonicalizer, LoweringTool.StandardLoweringStage.HIGH_TIER).apply(graph, highTierContext);
+ new LoadJavaMirrorWithKlassPhase(config).apply(graph, highTierContext);
+ new ReplaceConstantNodesPhase(false).apply(graph, highTierContext);
+ Assert.assertEquals(expectedInits, graph.getNodes().filter(InitializeKlassNode.class).count());
+ Assert.assertEquals(expectedResolves, graph.getNodes().filter(ResolveConstantNode.class).count());
+ Assert.assertEquals(expectedLoads, graph.getNodes().filter(LoadConstantIndirectlyNode.class).count());
+ }
+
+ @Test
+ public void test1() {
+ test("assignFields", 1, 0, 0);
+ }
+
+ @Test
+ public void test2() {
+ test("assignFieldsWithDominatingInit", 1, 0, 0);
+ }
+
+ @Test
+ public void test3() {
+ test("assignString", 1, 1, 0);
+ }
+
+ @Test
+ public void test4() {
+ test("assignToParentAndChild", 1, 1, 0);
+ }
+
+ @Test
+ public void test5() {
+ test("assignToThis", 0, 0, 1);
+ }
+
+ @Test
+ public void test6() {
+ test("assignFieldsWithDominatingInitOfParent", 1, 1, 0);
+ }
+
+ @Test
+ public void test7() {
+ test("assignFieldsInBranches", 2, 1, 0);
+ }
+}
--- a/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/CompilationTask.java Tue Jun 13 07:30:11 2017 -0400
+++ b/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/CompilationTask.java Tue Jun 13 09:19:35 2017 -0700
@@ -295,11 +295,13 @@
// Log a compilation event.
EventProvider.CompilationEvent compilationEvent = eventProvider.newCompilationEvent();
- // If there is already compiled code for this method on our level we simply return.
- // JVMCI compiles are always at the highest compile level, even in non-tiered mode so we
- // only need to check for that value.
- if (method.hasCodeAtLevel(entryBCI, config.compilationLevelFullOptimization)) {
- return null;
+ if (installAsDefault) {
+ // If there is already compiled code for this method on our level we simply return.
+ // JVMCI compiles are always at the highest compile level, even in non-tiered mode so we
+ // only need to check for that value.
+ if (method.hasCodeAtLevel(entryBCI, config.compilationLevelFullOptimization)) {
+ return HotSpotCompilationRequestResult.failure("Already compiled", false);
+ }
}
RetryableCompilation compilation = new RetryableCompilation(compilationEvent);
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/HotSpotCodeCacheListener.java Tue Jun 13 09:19:35 2017 -0700
@@ -0,0 +1,40 @@
+/*
+ * Copyright (c) 2015, 2016, 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.hotspot;
+
+import jdk.vm.ci.code.CompiledCode;
+import jdk.vm.ci.code.InstalledCode;
+import jdk.vm.ci.hotspot.HotSpotCodeCacheProvider;
+
+public interface HotSpotCodeCacheListener {
+ /**
+ * Notifies this object on successful install into the CodeCache.
+ *
+ * @param codeCache the code cache into which the code was installed
+ * @param installedCode the code that was installed
+ * @param compiledCode the compiled code from which {@code installedCode} was produced
+ */
+ default void notifyInstall(HotSpotCodeCacheProvider codeCache, InstalledCode installedCode, CompiledCode compiledCode) {
+
+ }
+}
--- a/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/HotSpotGraalCompiler.java Tue Jun 13 07:30:11 2017 -0400
+++ b/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/HotSpotGraalCompiler.java Tue Jun 13 09:19:35 2017 -0700
@@ -81,11 +81,10 @@
private final CompilationCounters compilationCounters;
private final BootstrapWatchDog bootstrapWatchDog;
- HotSpotGraalCompiler(HotSpotJVMCIRuntimeProvider jvmciRuntime, HotSpotGraalRuntimeProvider graalRuntime) {
+ HotSpotGraalCompiler(HotSpotJVMCIRuntimeProvider jvmciRuntime, HotSpotGraalRuntimeProvider graalRuntime, OptionValues options) {
this.jvmciRuntime = jvmciRuntime;
this.graalRuntime = graalRuntime;
// It is sufficient to have one compilation counter object per Graal compiler object.
- OptionValues options = graalRuntime.getOptions();
this.compilationCounters = Options.CompilationCountLimit.getValue(options) > 0 ? new CompilationCounters(options) : null;
this.bootstrapWatchDog = graalRuntime.isBootstrapping() && !GraalDebugConfig.Options.BootstrapInitializeOnly.getValue(options) ? BootstrapWatchDog.maybeCreate(graalRuntime) : null;
}
@@ -96,8 +95,12 @@
}
@Override
+ public CompilationRequestResult compileMethod(CompilationRequest request) {
+ return compileMethod(request, true);
+ }
+
@SuppressWarnings("try")
- public CompilationRequestResult compileMethod(CompilationRequest request) {
+ CompilationRequestResult compileMethod(CompilationRequest request, boolean installAsDefault) {
if (graalRuntime.isShutdown()) {
return HotSpotCompilationRequestResult.failure(String.format("Shutdown entered"), false);
}
@@ -124,8 +127,8 @@
}
// Ensure a debug configuration for this thread is initialized
DebugEnvironment.ensureInitialized(options, graalRuntime.getHostProviders().getSnippetReflection());
- CompilationTask task = new CompilationTask(jvmciRuntime, this, hsRequest, true, true, options);
- CompilationRequestResult r = null;
+ CompilationTask task = new CompilationTask(jvmciRuntime, this, hsRequest, true, installAsDefault, options);
+ CompilationRequestResult r;
try (DebugConfigScope dcs = Debug.setConfig(new TopLevelDebugConfig());
Debug.Scope s = Debug.methodMetricsScope("HotSpotGraalCompiler", MethodMetricsRootScopeInfo.create(method), true, method)) {
r = task.runCompilation();
--- a/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/HotSpotGraalCompilerFactory.java Tue Jun 13 07:30:11 2017 -0400
+++ b/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/HotSpotGraalCompilerFactory.java Tue Jun 13 09:19:35 2017 -0700
@@ -128,7 +128,7 @@
HotSpotJVMCIRuntime jvmciRuntime = (HotSpotJVMCIRuntime) runtime;
try (InitTimer t = timer("HotSpotGraalRuntime.<init>")) {
HotSpotGraalRuntime graalRuntime = new HotSpotGraalRuntime(jvmciRuntime, compilerConfigurationFactory, options);
- return new HotSpotGraalCompiler(jvmciRuntime, graalRuntime);
+ return new HotSpotGraalCompiler(jvmciRuntime, graalRuntime, graalRuntime.getOptions());
}
}
--- a/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/HotSpotGraalMBean.java Tue Jun 13 07:30:11 2017 -0400
+++ b/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/HotSpotGraalMBean.java Tue Jun 13 09:19:35 2017 -0700
@@ -23,9 +23,13 @@
package org.graalvm.compiler.hotspot;
import java.lang.management.ManagementFactory;
+import java.lang.ref.Reference;
+import java.lang.ref.WeakReference;
import java.lang.reflect.Field;
import java.util.ArrayList;
+import java.util.Iterator;
import java.util.List;
+import java.util.Objects;
import javax.management.Attribute;
import javax.management.AttributeList;
import javax.management.AttributeNotFoundException;
@@ -34,31 +38,51 @@
import javax.management.MBeanAttributeInfo;
import javax.management.MBeanException;
import javax.management.MBeanInfo;
+import javax.management.MBeanOperationInfo;
+import javax.management.MBeanParameterInfo;
import javax.management.MBeanRegistrationException;
import javax.management.MBeanServer;
import javax.management.MalformedObjectNameException;
import javax.management.NotCompliantMBeanException;
import javax.management.ObjectName;
import javax.management.ReflectionException;
+import jdk.vm.ci.hotspot.HotSpotCompilationRequest;
+import jdk.vm.ci.hotspot.HotSpotResolvedJavaMethod;
+import jdk.vm.ci.hotspot.HotSpotResolvedJavaType;
+import jdk.vm.ci.hotspot.HotSpotResolvedObjectType;
+import jdk.vm.ci.meta.MetaUtil;
import jdk.vm.ci.meta.ResolvedJavaMethod;
+import jdk.vm.ci.meta.ResolvedJavaType;
+import jdk.vm.ci.runtime.JVMCI;
+import org.graalvm.compiler.debug.GraalDebugConfig;
import org.graalvm.compiler.options.OptionDescriptor;
import org.graalvm.compiler.options.OptionDescriptors;
import org.graalvm.compiler.options.OptionKey;
import org.graalvm.compiler.options.OptionValues;
import org.graalvm.compiler.options.OptionsParser;
import org.graalvm.util.EconomicMap;
+import org.graalvm.util.EconomicSet;
+import org.graalvm.util.Equivalence;
import org.graalvm.util.UnmodifiableEconomicMap;
public final class HotSpotGraalMBean implements DynamicMBean {
private static Object mBeanServerField;
+ private final HotSpotGraalCompiler compiler;
private final OptionValues options;
private final EconomicMap<OptionKey<?>, Object> changes;
+ private final EconomicSet<Dump> methodDumps;
+ private volatile EconomicSet<Reference<ClassLoader>> loaders;
private ObjectName registered;
private OptionValues cachedOptions;
- private HotSpotGraalMBean(OptionValues options) {
+ private HotSpotGraalMBean(HotSpotGraalCompiler compiler, OptionValues options) {
+ this.compiler = compiler;
this.options = options;
this.changes = EconomicMap.create();
+ this.methodDumps = EconomicSet.create();
+ EconomicSet<Reference<ClassLoader>> systemLoaderSet = EconomicSet.create(RefEquivalence.INSTANCE);
+ systemLoaderSet.add(new WeakReference<>(ClassLoader.getSystemClassLoader()));
+ this.loaders = systemLoaderSet;
}
private static boolean isMXServerOn() {
@@ -82,9 +106,9 @@
}
}
- public static HotSpotGraalMBean create() {
+ public static HotSpotGraalMBean create(HotSpotGraalCompiler compiler) {
OptionValues options = HotSpotGraalOptionValues.HOTSPOT_OPTIONS;
- HotSpotGraalMBean mbean = new HotSpotGraalMBean(options);
+ HotSpotGraalMBean mbean = new HotSpotGraalMBean(compiler, options);
return mbean;
}
@@ -111,14 +135,25 @@
return registered;
}
- @SuppressWarnings("unused")
public OptionValues optionsFor(OptionValues initialValues, ResolvedJavaMethod forMethod) {
ensureRegistered(true);
- return currentMap(initialValues);
+ if (forMethod instanceof HotSpotResolvedJavaMethod) {
+ HotSpotResolvedObjectType type = ((HotSpotResolvedJavaMethod) forMethod).getDeclaringClass();
+ if (type instanceof HotSpotResolvedJavaType) {
+ Class<?> clazz = ((HotSpotResolvedJavaType) type).mirror();
+ Reference<ClassLoader> addNewRef = new WeakReference<>(clazz.getClassLoader());
+ if (!loaders.contains(addNewRef)) {
+ EconomicSet<Reference<ClassLoader>> newLoaders = EconomicSet.create(RefEquivalence.INSTANCE, loaders);
+ newLoaders.add(addNewRef);
+ this.loaders = newLoaders;
+ }
+ }
+ }
+ return currentMap(initialValues, forMethod);
}
- private OptionValues currentMap(OptionValues initialValues) {
- if (changes.isEmpty()) {
+ private OptionValues currentMap(OptionValues initialValues, ResolvedJavaMethod method) {
+ if (changes.isEmpty() && methodDumps.isEmpty()) {
return initialValues;
}
OptionValues current = cachedOptions;
@@ -126,12 +161,23 @@
current = new OptionValues(initialValues, changes);
cachedOptions = current;
}
+ if (method != null) {
+ for (Dump request : methodDumps) {
+ final String clazzName = method.getDeclaringClass().getName();
+ if (method.getName().equals(request.method) && clazzName.equals(request.clazz)) {
+ current = new OptionValues(current, GraalDebugConfig.Options.Dump, request.filter,
+ GraalDebugConfig.Options.PrintGraphHost, request.host,
+ GraalDebugConfig.Options.PrintBinaryGraphPort, request.port);
+ break;
+ }
+ }
+ }
return current;
}
@Override
public Object getAttribute(String attribute) {
- UnmodifiableEconomicMap<OptionKey<?>, Object> map = currentMap(options).getMap();
+ UnmodifiableEconomicMap<OptionKey<?>, Object> map = currentMap(options, null).getMap();
for (OptionKey<?> k : map.getKeys()) {
if (k.getName().equals(attribute)) {
return map.get(k);
@@ -185,9 +231,71 @@
@Override
public Object invoke(String actionName, Object[] params, String[] signature) throws MBeanException, ReflectionException {
+ if ("dumpMethod".equals(actionName)) {
+ try {
+ String className = param(params, 0, "className", String.class, null);
+ String methodName = param(params, 1, "methodName", String.class, null);
+ String filter = param(params, 2, "filter", String.class, ":3");
+ String host = param(params, 3, "host", String.class, "localhost");
+ Number port = param(params, 4, "port", Number.class, 4445);
+ dumpMethod(className, methodName, filter, host, port.intValue());
+ } catch (Exception ex) {
+ throw new ReflectionException(ex);
+ }
+ }
return null;
}
+ private static <T> T param(Object[] arr, int index, String name, Class<T> type, T defaultValue) {
+ Object value = arr.length > index ? arr[index] : null;
+ if (value == null || (value instanceof String && ((String) value).isEmpty())) {
+ if (defaultValue == null) {
+ throw new IllegalArgumentException(name + " must be specified");
+ }
+ value = defaultValue;
+ }
+ if (type.isInstance(value)) {
+ return type.cast(value);
+ }
+ throw new IllegalArgumentException("Expecting " + type.getName() + " for " + name + " but was " + value);
+ }
+
+ public void dumpMethod(String className, String methodName, String filter, String host, int port) throws MBeanException {
+ String jvmName = MetaUtil.toInternalName(className);
+ methodDumps.add(new Dump(host, port, jvmName, methodName, filter));
+
+ ClassNotFoundException last = null;
+ EconomicSet<Class<?>> found = EconomicSet.create();
+ Iterator<Reference<ClassLoader>> it = loaders.iterator();
+ while (it.hasNext()) {
+ Reference<ClassLoader> ref = it.next();
+ ClassLoader loader = ref.get();
+ if (loader == null) {
+ it.remove();
+ continue;
+ }
+ try {
+ Class<?> clazz = Class.forName(className, false, loader);
+ if (found.add(clazz)) {
+ ResolvedJavaType type = JVMCI.getRuntime().getHostJVMCIBackend().getMetaAccess().lookupJavaType(clazz);
+ if (compiler != null) {
+ for (ResolvedJavaMethod method : type.getDeclaredMethods()) {
+ if (methodName.equals(method.getName()) && method instanceof HotSpotResolvedJavaMethod) {
+ HotSpotResolvedJavaMethod hotSpotMethod = (HotSpotResolvedJavaMethod) method;
+ compiler.compileMethod(new HotSpotCompilationRequest(hotSpotMethod, -1, 0L), false);
+ }
+ }
+ }
+ }
+ } catch (ClassNotFoundException ex) {
+ last = ex;
+ }
+ }
+ if (found.isEmpty()) {
+ throw new MBeanException(last, "Cannot find class " + className + " to schedule recompilation");
+ }
+ }
+
@Override
public MBeanInfo getMBeanInfo() {
List<MBeanAttributeInfo> attrs = new ArrayList<>();
@@ -196,11 +304,30 @@
attrs.add(new MBeanAttributeInfo(descr.getName(), descr.getType().getName(), descr.getHelp(), true, true, false));
}
}
+ MBeanOperationInfo[] ops = {
+ new MBeanOperationInfo("dumpMethod", "Enable IGV dumps for provided method", new MBeanParameterInfo[]{
+ new MBeanParameterInfo("className", "java.lang.String", "Class to observe"),
+ new MBeanParameterInfo("methodName", "java.lang.String", "Method to observe"),
+ }, "void", MBeanOperationInfo.ACTION),
+ new MBeanOperationInfo("dumpMethod", "Enable IGV dumps for provided method", new MBeanParameterInfo[]{
+ new MBeanParameterInfo("className", "java.lang.String", "Class to observe"),
+ new MBeanParameterInfo("methodName", "java.lang.String", "Method to observe"),
+ new MBeanParameterInfo("filter", "java.lang.String", "The parameter for Dump option"),
+ }, "void", MBeanOperationInfo.ACTION),
+ new MBeanOperationInfo("dumpMethod", "Enable IGV dumps for provided method", new MBeanParameterInfo[]{
+ new MBeanParameterInfo("className", "java.lang.String", "Class to observe"),
+ new MBeanParameterInfo("methodName", "java.lang.String", "Method to observe"),
+ new MBeanParameterInfo("filter", "java.lang.String", "The parameter for Dump option"),
+ new MBeanParameterInfo("host", "java.lang.String", "The host where the IGV tool is running at"),
+ new MBeanParameterInfo("port", "int", "The port where the IGV tool is listening at"),
+ }, "void", MBeanOperationInfo.ACTION)
+ };
+
return new MBeanInfo(
HotSpotGraalMBean.class.getName(),
"Graal",
attrs.toArray(new MBeanAttributeInfo[attrs.size()]),
- null, null, null);
+ null, ops, null);
}
private static Iterable<OptionDescriptor> allOptionDescriptors() {
@@ -213,4 +340,41 @@
return arr;
}
+ private static final class Dump {
+ final String host;
+ final int port;
+ final String clazz;
+ final String method;
+ final String filter;
+
+ Dump(String host, int port, String clazz, String method, String filter) {
+ this.host = host;
+ this.port = port;
+ this.clazz = clazz;
+ this.method = method;
+ this.filter = filter;
+ }
+ }
+
+ private static final class RefEquivalence extends Equivalence {
+ static final Equivalence INSTANCE = new RefEquivalence();
+
+ private RefEquivalence() {
+ }
+
+ @Override
+ public boolean equals(Object a, Object b) {
+ Reference<?> refA = (Reference<?>) a;
+ Reference<?> refB = (Reference<?>) b;
+ return Objects.equals(refA.get(), refB.get());
+ }
+
+ @Override
+ public int hashCode(Object o) {
+ Reference<?> ref = (Reference<?>) o;
+ Object obj = ref.get();
+ return obj == null ? 0 : obj.hashCode();
+ }
+
+ }
}
--- a/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/HotSpotGraalRuntime.java Tue Jun 13 07:30:11 2017 -0400
+++ b/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/HotSpotGraalRuntime.java Tue Jun 13 09:19:35 2017 -0700
@@ -130,10 +130,12 @@
options = initialOptions;
}
- this.mBean = HotSpotGraalMBean.create();
-
snippetCounterGroups = GraalOptions.SnippetCounters.getValue(options) ? new ArrayList<>() : null;
CompilerConfiguration compilerConfiguration = compilerConfigurationFactory.createCompilerConfiguration();
+
+ HotSpotGraalCompiler compiler = new HotSpotGraalCompiler(jvmciRuntime, this, initialOptions);
+ this.mBean = HotSpotGraalMBean.create(compiler);
+
BackendMap backendMap = compilerConfigurationFactory.createBackendMap();
JVMCIBackend hostJvmciBackend = jvmciRuntime.getHostJVMCIBackend();
@@ -261,12 +263,12 @@
@Override
public OptionValues getOptions() {
- return mBean == null ? options : mBean.optionsFor(options, null);
+ return mBean.optionsFor(options, null);
}
@Override
public OptionValues getOptions(ResolvedJavaMethod forMethod) {
- return mBean == null ? options : mBean.optionsFor(options, forMethod);
+ return mBean.optionsFor(options, forMethod);
}
@Override
--- a/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/HotSpotGraalVMEventListener.java Tue Jun 13 07:30:11 2017 -0400
+++ b/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/HotSpotGraalVMEventListener.java Tue Jun 13 09:19:35 2017 -0700
@@ -22,21 +22,29 @@
*/
package org.graalvm.compiler.hotspot;
-import org.graalvm.compiler.code.CompilationResult;
-import org.graalvm.compiler.debug.Debug;
-import org.graalvm.compiler.debug.GraalDebugConfig;
-
import jdk.vm.ci.code.CompiledCode;
import jdk.vm.ci.code.InstalledCode;
import jdk.vm.ci.hotspot.HotSpotCodeCacheProvider;
import jdk.vm.ci.hotspot.HotSpotVMEventListener;
+import org.graalvm.compiler.code.CompilationResult;
+import org.graalvm.compiler.debug.Debug;
+import org.graalvm.compiler.debug.GraalDebugConfig;
+import org.graalvm.compiler.serviceprovider.GraalServices;
+
+import java.util.ArrayList;
+import java.util.List;
public class HotSpotGraalVMEventListener implements HotSpotVMEventListener {
private final HotSpotGraalRuntime runtime;
+ private List<HotSpotCodeCacheListener> listeners;
HotSpotGraalVMEventListener(HotSpotGraalRuntime runtime) {
this.runtime = runtime;
+ listeners = new ArrayList<>();
+ for (HotSpotCodeCacheListener listener : GraalServices.load(HotSpotCodeCacheListener.class)) {
+ listeners.add(listener);
+ }
}
@Override
@@ -54,6 +62,9 @@
if (Debug.isLogEnabled()) {
Debug.log("%s", codeCache.disassemble(installedCode));
}
+ for (HotSpotCodeCacheListener listener : listeners) {
+ listener.notifyInstall(codeCache, installedCode, compiledCode);
+ }
}
@Override
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/meta/AddressLoweringHotSpotSuitesProvider.java Tue Jun 13 09:19:35 2017 -0700
@@ -0,0 +1,64 @@
+/*
+ * Copyright (c) 2017, 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.
+ *
+ * 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.hotspot.meta;
+
+import java.util.ListIterator;
+
+import org.graalvm.compiler.hotspot.GraalHotSpotVMConfig;
+import org.graalvm.compiler.hotspot.HotSpotGraalRuntimeProvider;
+import org.graalvm.compiler.options.OptionValues;
+import org.graalvm.compiler.phases.BasePhase;
+import org.graalvm.compiler.phases.common.AddressLoweringPhase;
+import org.graalvm.compiler.phases.common.ExpandLogicPhase;
+import org.graalvm.compiler.phases.common.FixReadsPhase;
+import org.graalvm.compiler.phases.tiers.LowTierContext;
+import org.graalvm.compiler.phases.tiers.Suites;
+import org.graalvm.compiler.phases.tiers.SuitesCreator;
+
+/**
+ * Subclass to factor out management of address lowering.
+ */
+public class AddressLoweringHotSpotSuitesProvider extends HotSpotSuitesProvider {
+
+ private final AddressLoweringPhase.AddressLowering addressLowering;
+
+ public AddressLoweringHotSpotSuitesProvider(SuitesCreator defaultSuitesCreator, GraalHotSpotVMConfig config, HotSpotGraalRuntimeProvider runtime,
+ AddressLoweringPhase.AddressLowering addressLowering) {
+ super(defaultSuitesCreator, config, runtime);
+ this.addressLowering = addressLowering;
+ }
+
+ @Override
+ public Suites createSuites(OptionValues options) {
+ Suites suites = super.createSuites(options);
+
+ ListIterator<BasePhase<? super LowTierContext>> findPhase = suites.getLowTier().findPhase(FixReadsPhase.class);
+ if (findPhase == null) {
+ findPhase = suites.getLowTier().findPhase(ExpandLogicPhase.class);
+ }
+ findPhase.add(new AddressLoweringPhase(addressLowering));
+
+ return suites;
+ }
+}
--- a/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/meta/DefaultHotSpotLoweringProvider.java Tue Jun 13 07:30:11 2017 -0400
+++ b/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/meta/DefaultHotSpotLoweringProvider.java Tue Jun 13 09:19:35 2017 -0700
@@ -364,11 +364,17 @@
} else if (n instanceof IdentityHashCodeNode) {
hashCodeSnippets.lower((IdentityHashCodeNode) n, tool);
} else if (n instanceof ResolveConstantNode) {
- resolveConstantSnippets.lower((ResolveConstantNode) n, tool);
+ if (graph.getGuardsStage().areFrameStatesAtDeopts()) {
+ resolveConstantSnippets.lower((ResolveConstantNode) n, tool);
+ }
} else if (n instanceof ResolveMethodAndLoadCountersNode) {
- resolveConstantSnippets.lower((ResolveMethodAndLoadCountersNode) n, tool);
+ if (graph.getGuardsStage().areFrameStatesAtDeopts()) {
+ resolveConstantSnippets.lower((ResolveMethodAndLoadCountersNode) n, tool);
+ }
} else if (n instanceof InitializeKlassNode) {
- resolveConstantSnippets.lower((InitializeKlassNode) n, tool);
+ if (graph.getGuardsStage().areFrameStatesAtDeopts()) {
+ resolveConstantSnippets.lower((InitializeKlassNode) n, tool);
+ }
} else if (n instanceof ProfileNode) {
profileSnippets.lower((ProfileNode) n, tool);
} else {
--- a/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/meta/HotSpotSuitesProvider.java Tue Jun 13 07:30:11 2017 -0400
+++ b/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/meta/HotSpotSuitesProvider.java Tue Jun 13 09:19:35 2017 -0700
@@ -52,16 +52,11 @@
import org.graalvm.compiler.options.OptionValues;
import org.graalvm.compiler.phases.BasePhase;
import org.graalvm.compiler.phases.PhaseSuite;
-import org.graalvm.compiler.phases.common.AddressLoweringPhase;
-import org.graalvm.compiler.phases.common.AddressLoweringPhase.AddressLowering;
import org.graalvm.compiler.phases.common.CanonicalizerPhase;
-import org.graalvm.compiler.phases.common.ExpandLogicPhase;
-import org.graalvm.compiler.phases.common.FixReadsPhase;
-import org.graalvm.compiler.phases.common.LoopSafepointInsertionPhase;
import org.graalvm.compiler.phases.common.LoweringPhase;
import org.graalvm.compiler.phases.common.inlining.InliningPhase;
import org.graalvm.compiler.phases.tiers.HighTierContext;
-import org.graalvm.compiler.phases.tiers.LowTierContext;
+import org.graalvm.compiler.phases.tiers.MidTierContext;
import org.graalvm.compiler.phases.tiers.Suites;
import org.graalvm.compiler.phases.tiers.SuitesCreator;
@@ -73,14 +68,12 @@
protected final GraalHotSpotVMConfig config;
protected final HotSpotGraalRuntimeProvider runtime;
- private final AddressLowering addressLowering;
private final SuitesCreator defaultSuitesCreator;
- public HotSpotSuitesProvider(SuitesCreator defaultSuitesCreator, GraalHotSpotVMConfig config, HotSpotGraalRuntimeProvider runtime, AddressLowering addressLowering) {
+ public HotSpotSuitesProvider(SuitesCreator defaultSuitesCreator, GraalHotSpotVMConfig config, HotSpotGraalRuntimeProvider runtime) {
this.defaultSuitesCreator = defaultSuitesCreator;
this.config = config;
this.runtime = runtime;
- this.addressLowering = addressLowering;
this.defaultGraphBuilderSuite = createGraphBuilderSuite();
}
@@ -95,14 +88,14 @@
ret.getHighTier().appendPhase(new AheadOfTimeVerificationPhase());
}
if (GeneratePIC.getValue(options)) {
- // EliminateRedundantInitializationPhase must happen before the first lowering.
ListIterator<BasePhase<? super HighTierContext>> highTierLowering = ret.getHighTier().findPhase(LoweringPhase.class);
highTierLowering.previous();
highTierLowering.add(new EliminateRedundantInitializationPhase());
if (HotSpotAOTProfilingPlugin.Options.TieredAOT.getValue(options)) {
highTierLowering.add(new FinalizeProfileNodesPhase(HotSpotAOTProfilingPlugin.Options.TierAInvokeInlineeNotifyFreqLog.getValue(options)));
}
- ret.getMidTier().findPhase(LoopSafepointInsertionPhase.class).add(new ReplaceConstantNodesPhase());
+ ListIterator<BasePhase<? super MidTierContext>> midTierLowering = ret.getMidTier().findPhase(LoweringPhase.class);
+ midTierLowering.add(new ReplaceConstantNodesPhase());
// Replace inlining policy
ListIterator<BasePhase<? super HighTierContext>> iter = ret.getHighTier().findPhase(InliningPhase.class);
@@ -117,12 +110,6 @@
ret.getMidTier().appendPhase(new WriteBarrierVerificationPhase(config));
}
- ListIterator<BasePhase<? super LowTierContext>> findPhase = ret.getLowTier().findPhase(FixReadsPhase.class);
- if (findPhase == null) {
- findPhase = ret.getLowTier().findPhase(ExpandLogicPhase.class);
- }
- findPhase.add(new AddressLoweringPhase(addressLowering));
-
return ret;
}
--- a/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/nodes/aot/InitializeKlassNode.java Tue Jun 13 07:30:11 2017 -0400
+++ b/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/nodes/aot/InitializeKlassNode.java Tue Jun 13 09:19:35 2017 -0700
@@ -22,18 +22,21 @@
*/
package org.graalvm.compiler.hotspot.nodes.aot;
+import static org.graalvm.compiler.nodeinfo.InputType.Memory;
import static org.graalvm.compiler.nodeinfo.NodeCycles.CYCLES_4;
import static org.graalvm.compiler.nodeinfo.NodeSize.SIZE_16;
+import org.graalvm.api.word.LocationIdentity;
import org.graalvm.compiler.graph.NodeClass;
import org.graalvm.compiler.nodeinfo.NodeInfo;
import org.graalvm.compiler.nodes.DeoptimizingFixedWithNextNode;
import org.graalvm.compiler.nodes.ValueNode;
+import org.graalvm.compiler.nodes.memory.MemoryCheckpoint;
import org.graalvm.compiler.nodes.spi.Lowerable;
import org.graalvm.compiler.nodes.spi.LoweringTool;
-@NodeInfo(cycles = CYCLES_4, size = SIZE_16)
-public class InitializeKlassNode extends DeoptimizingFixedWithNextNode implements Lowerable {
+@NodeInfo(cycles = CYCLES_4, size = SIZE_16, allowedUsageTypes = {Memory})
+public class InitializeKlassNode extends DeoptimizingFixedWithNextNode implements Lowerable, MemoryCheckpoint.Single {
public static final NodeClass<InitializeKlassNode> TYPE = NodeClass.create(InitializeKlassNode.class);
@Input ValueNode value;
@@ -56,4 +59,9 @@
public boolean canDeoptimize() {
return true;
}
+
+ @Override
+ public LocationIdentity getLocationIdentity() {
+ return LocationIdentity.any();
+ }
}
--- a/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/nodes/aot/ResolveConstantNode.java Tue Jun 13 07:30:11 2017 -0400
+++ b/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/nodes/aot/ResolveConstantNode.java Tue Jun 13 09:19:35 2017 -0700
@@ -28,13 +28,13 @@
import org.graalvm.compiler.graph.NodeClass;
import org.graalvm.compiler.hotspot.meta.HotSpotConstantLoadAction;
import org.graalvm.compiler.nodeinfo.NodeInfo;
+import org.graalvm.compiler.nodes.DeoptimizingFixedWithNextNode;
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;
@NodeInfo(cycles = CYCLES_4, size = SIZE_16)
-public class ResolveConstantNode extends FloatingNode implements Lowerable {
+public class ResolveConstantNode extends DeoptimizingFixedWithNextNode implements Lowerable {
public static final NodeClass<ResolveConstantNode> TYPE = NodeClass.create(ResolveConstantNode.class);
@Input ValueNode value;
@@ -64,4 +64,9 @@
public HotSpotConstantLoadAction action() {
return action;
}
+
+ @Override
+ public boolean canDeoptimize() {
+ return true;
+ }
}
--- a/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/nodes/aot/ResolveConstantStubCall.java Tue Jun 13 07:30:11 2017 -0400
+++ b/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/nodes/aot/ResolveConstantStubCall.java Tue Jun 13 09:19:35 2017 -0700
@@ -110,5 +110,4 @@
}
gen.setResult(this, result);
}
-
}
--- a/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/nodes/aot/ResolveMethodAndLoadCountersNode.java Tue Jun 13 07:30:11 2017 -0400
+++ b/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/nodes/aot/ResolveMethodAndLoadCountersNode.java Tue Jun 13 09:19:35 2017 -0700
@@ -28,15 +28,15 @@
import org.graalvm.compiler.graph.NodeClass;
import org.graalvm.compiler.hotspot.nodes.type.MethodCountersPointerStamp;
import org.graalvm.compiler.nodeinfo.NodeInfo;
+import org.graalvm.compiler.nodes.DeoptimizingFixedWithNextNode;
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 jdk.vm.ci.meta.ResolvedJavaMethod;
@NodeInfo(cycles = CYCLES_4, size = SIZE_16)
-public class ResolveMethodAndLoadCountersNode extends FloatingNode implements Lowerable {
+public class ResolveMethodAndLoadCountersNode extends DeoptimizingFixedWithNextNode implements Lowerable {
public static final NodeClass<ResolveMethodAndLoadCountersNode> TYPE = NodeClass.create(ResolveMethodAndLoadCountersNode.class);
ResolvedJavaMethod method;
@@ -60,4 +60,9 @@
public ValueNode getHub() {
return hub;
}
+
+ @Override
+ public boolean canDeoptimize() {
+ return true;
+ }
}
--- a/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/phases/aot/ReplaceConstantNodesPhase.java Tue Jun 13 07:30:11 2017 -0400
+++ b/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/phases/aot/ReplaceConstantNodesPhase.java Tue Jun 13 09:19:35 2017 -0700
@@ -22,10 +22,12 @@
*/
package org.graalvm.compiler.hotspot.phases.aot;
+import static org.graalvm.compiler.core.common.cfg.AbstractControlFlowGraph.strictlyDominates;
import static org.graalvm.compiler.hotspot.nodes.aot.LoadMethodCountersNode.getLoadMethodCountersNodes;
import static org.graalvm.compiler.nodes.ConstantNode.getConstantNodes;
import java.util.HashSet;
+import java.util.List;
import jdk.vm.ci.hotspot.HotSpotMetaspaceConstant;
import jdk.vm.ci.hotspot.HotSpotObjectConstant;
@@ -35,11 +37,13 @@
import jdk.vm.ci.meta.ConstantReflectionProvider;
import jdk.vm.ci.meta.ResolvedJavaType;
+import org.graalvm.compiler.core.common.cfg.BlockMap;
import org.graalvm.compiler.core.common.type.ObjectStamp;
import org.graalvm.compiler.core.common.type.Stamp;
import org.graalvm.compiler.core.common.type.StampFactory;
import org.graalvm.compiler.debug.GraalError;
import org.graalvm.compiler.graph.Node;
+import org.graalvm.compiler.graph.NodeMap;
import org.graalvm.compiler.hotspot.FingerprintUtil;
import org.graalvm.compiler.hotspot.meta.HotSpotConstantLoadAction;
import org.graalvm.compiler.hotspot.nodes.aot.InitializeKlassNode;
@@ -49,14 +53,21 @@
import org.graalvm.compiler.hotspot.nodes.aot.ResolveConstantNode;
import org.graalvm.compiler.hotspot.nodes.aot.ResolveMethodAndLoadCountersNode;
import org.graalvm.compiler.nodes.ConstantNode;
+import org.graalvm.compiler.nodes.FixedWithNextNode;
import org.graalvm.compiler.nodes.StructuredGraph;
+import org.graalvm.compiler.nodes.StructuredGraph.ScheduleResult;
import org.graalvm.compiler.nodes.ValueNode;
+import org.graalvm.compiler.nodes.cfg.Block;
import org.graalvm.compiler.phases.BasePhase;
+import org.graalvm.compiler.phases.schedule.SchedulePhase;
+import org.graalvm.compiler.phases.schedule.SchedulePhase.SchedulingStrategy;
import org.graalvm.compiler.phases.tiers.PhaseContext;
+import org.graalvm.util.EconomicMap;
public class ReplaceConstantNodesPhase extends BasePhase<PhaseContext> {
private static final HashSet<Class<?>> builtIns = new HashSet<>();
+ private final boolean verifyFingerprints;
static {
builtIns.add(Boolean.class);
@@ -91,6 +102,14 @@
// @formatter:on
}
+ private static boolean anyUsagesNeedReplacement(ConstantNode node) {
+ return node.usages().filter(n -> !isReplacementNode(n)).isNotEmpty();
+ }
+
+ private static boolean anyUsagesNeedReplacement(LoadMethodCountersNode node) {
+ return node.usages().filter(n -> !(n instanceof ResolveMethodAndLoadCountersNode)).isNotEmpty();
+ }
+
private static boolean checkForBadFingerprint(HotSpotResolvedJavaType type) {
if (type.isArray()) {
if (type.getElementalType().isPrimitive()) {
@@ -101,80 +120,223 @@
return FingerprintUtil.getFingerprint((HotSpotResolvedObjectType) type) == 0;
}
- private static void handleHotSpotMetaspaceConstant(StructuredGraph graph, ConstantNode node) {
+ /**
+ * Replace {@link ConstantNode} containing a {@link HotSpotResolvedJavaType} with indirection.
+ *
+ * @param graph
+ * @param node {@link ConstantNode} containing a {@link HotSpotResolvedJavaType} that needs
+ * resolution.
+ */
+ private void handleHotSpotMetaspaceConstant(StructuredGraph graph, ConstantNode node) {
HotSpotMetaspaceConstant metaspaceConstant = (HotSpotMetaspaceConstant) node.asConstant();
HotSpotResolvedJavaType type = (HotSpotResolvedJavaType) metaspaceConstant.asResolvedJavaType();
if (type != null) {
- if (checkForBadFingerprint(type)) {
+ if (verifyFingerprints && checkForBadFingerprint(type)) {
throw new GraalError("Type with bad fingerprint: " + type);
}
-
assert !metaspaceConstant.isCompressed() : "No support for replacing compressed metaspace constants";
- ResolvedJavaType topMethodHolder = graph.method().getDeclaringClass();
- ValueNode replacement;
-
- if (type.isArray() && type.getComponentType().isPrimitive()) {
- // Special case for primitive arrays. The AOT runtime pre-resolves them, so we may
- // omit the resolution call.
- replacement = new LoadConstantIndirectlyNode(node);
- } else if (type.equals(topMethodHolder) || (type.isAssignableFrom(topMethodHolder) && !type.isInterface())) {
- // If it's a supertype of or the same class that declares the top method, we are
- // guaranteed to have it resolved already. If it's an interface, we just test for
- // equality.
- replacement = new LoadConstantIndirectlyNode(node);
- } else if (builtIns.contains(type.mirror())) {
- // Special case of klass constants that come from {@link BoxingSnippets}.
- replacement = new ResolveConstantNode(node, HotSpotConstantLoadAction.INITIALIZE);
- } else {
- replacement = new ResolveConstantNode(node);
+ replaceWithInitialization(graph, node);
+ if (anyUsagesNeedReplacement(node)) {
+ replaceWithResolution(graph, node);
}
-
- node.replaceAtUsages(graph.addOrUnique(replacement), n -> !isReplacementNode(n));
} else {
throw new GraalError("Unsupported metaspace constant type: " + type);
}
}
+ /**
+ * Find the lowest dominating {@link FixedWithNextNode} before given node.
+ *
+ * @param graph
+ * @param node
+ * @return the last {@link FixedWithNextNode} that is scheduled before node.
+ */
+ private static FixedWithNextNode findFixedWithNextBefore(StructuredGraph graph, Node node) {
+ ScheduleResult schedule = graph.getLastSchedule();
+ NodeMap<Block> nodeToBlock = schedule.getNodeToBlockMap();
+ BlockMap<List<Node>> blockToNodes = schedule.getBlockToNodesMap();
+
+ Block block = nodeToBlock.get(node);
+ FixedWithNextNode result = null;
+ for (Node n : blockToNodes.get(block)) {
+ if (n instanceof FixedWithNextNode) {
+ result = (FixedWithNextNode) n;
+ }
+ if (n.equals(node)) {
+ break;
+ }
+ }
+ assert result != null;
+ return result;
+ }
+
+ /**
+ * Try to find dominating {@link InitializeKlassNode} that can be reused.
+ *
+ * @param graph
+ * @param node {@link ConstantNode} containing a {@link HotSpotResolvedJavaType} that needs
+ * resolution.
+ */
+ private static void replaceWithInitialization(StructuredGraph graph, ConstantNode node) {
+ ScheduleResult schedule = graph.getLastSchedule();
+ NodeMap<Block> nodeToBlock = schedule.getNodeToBlockMap();
+ BlockMap<List<Node>> blockToNodes = schedule.getBlockToNodesMap();
+
+ EconomicMap<Block, Node> blockToInit = EconomicMap.create();
+ for (Node n : node.usages().filter(InitializeKlassNode.class)) {
+ blockToInit.put(nodeToBlock.get(n), n);
+ }
+ for (Node use : node.usages().filter(n -> !isReplacementNode(n)).snapshot()) {
+ boolean replaced = false;
+ Block b = nodeToBlock.get(use);
+ InitializeKlassNode i = (InitializeKlassNode) blockToInit.get(b);
+ if (i != null) {
+ // There is an initialization in the same block as the use, look if the use is
+ // scheduled after it.
+ for (Node n : blockToNodes.get(b)) {
+ if (n.equals(use)) {
+ // Usage is before initialization, can't use it
+ break;
+ }
+ if (n.equals(i)) {
+ use.replaceFirstInput(node, i);
+ replaced = true;
+ break;
+ }
+ }
+ }
+ if (!replaced) {
+ // Look for dominating blocks that have initializations
+ for (Block d : blockToInit.getKeys()) {
+ if (strictlyDominates(d, b)) {
+ use.replaceFirstInput(node, blockToInit.get(d));
+ break;
+ }
+ }
+ }
+ }
+ }
+
+ /**
+ * Replace the uses of a constant with either {@link LoadConstantIndirectlyNode} or
+ * {@link ResolveConstantNode}.
+ *
+ * @param graph
+ * @param node {@link ConstantNode} containing a {@link HotSpotResolvedJavaType} that needs
+ * resolution.
+ */
+ private static void replaceWithResolution(StructuredGraph graph, ConstantNode node) {
+ HotSpotMetaspaceConstant metaspaceConstant = (HotSpotMetaspaceConstant) node.asConstant();
+ HotSpotResolvedJavaType type = (HotSpotResolvedJavaType) metaspaceConstant.asResolvedJavaType();
+ ResolvedJavaType topMethodHolder = graph.method().getDeclaringClass();
+ ValueNode replacement;
+
+ if (type.isArray() && type.getComponentType().isPrimitive()) {
+ // Special case for primitive arrays. The AOT runtime pre-resolves them, so we may
+ // omit the resolution call.
+ replacement = graph.addOrUnique(new LoadConstantIndirectlyNode(node));
+ } else if (type.equals(topMethodHolder) || (type.isAssignableFrom(topMethodHolder) && !type.isInterface())) {
+ // If it's a supertype of or the same class that declares the top method, we are
+ // guaranteed to have it resolved already. If it's an interface, we just test for
+ // equality.
+ replacement = graph.addOrUnique(new LoadConstantIndirectlyNode(node));
+ } else {
+ FixedWithNextNode fixedReplacement;
+ if (builtIns.contains(type.mirror())) {
+ // Special case of klass constants that come from {@link BoxingSnippets}.
+ fixedReplacement = graph.add(new ResolveConstantNode(node, HotSpotConstantLoadAction.INITIALIZE));
+ } else {
+ fixedReplacement = graph.add(new ResolveConstantNode(node));
+ }
+ graph.addAfterFixed(findFixedWithNextBefore(graph, node), fixedReplacement);
+ replacement = fixedReplacement;
+ }
+ node.replaceAtUsages(replacement, n -> !isReplacementNode(n));
+ }
+
+ /**
+ * Replace an object constant with an indirect load {@link ResolveConstantNode}. Currently we
+ * support only strings.
+ *
+ * @param graph
+ * @param node {@link ConstantNode} containing a {@link HotSpotObjectConstant} that needs
+ * resolution.
+ */
private static void handleHotSpotObjectConstant(StructuredGraph graph, ConstantNode node) {
HotSpotObjectConstant constant = (HotSpotObjectConstant) node.asJavaConstant();
HotSpotResolvedJavaType type = (HotSpotResolvedJavaType) constant.getType();
if (type.mirror().equals(String.class)) {
assert !constant.isCompressed() : "No support for replacing compressed oop constants";
- ValueNode replacement = graph.unique(new ResolveConstantNode(node));
+ FixedWithNextNode replacement = graph.add(new ResolveConstantNode(node));
+ graph.addAfterFixed(findFixedWithNextBefore(graph, node), replacement);
node.replaceAtUsages(replacement, n -> !(n instanceof ResolveConstantNode));
} else {
throw new GraalError("Unsupported object constant type: " + type);
}
}
+ /**
+ * Replace {@link LoadMethodCountersNode} with indirect load
+ * {@link ResolveMethodAndLoadCountersNode}, expose a klass constant of the holder.
+ *
+ * @param graph
+ * @param node
+ * @param context
+ */
private static void handleLoadMethodCounters(StructuredGraph graph, LoadMethodCountersNode node, PhaseContext context) {
ResolvedJavaType type = node.getMethod().getDeclaringClass();
Stamp hubStamp = context.getStampProvider().createHubStamp((ObjectStamp) StampFactory.objectNonNull());
ConstantReflectionProvider constantReflection = context.getConstantReflection();
ConstantNode klassHint = ConstantNode.forConstant(hubStamp, constantReflection.asObjectHub(type), context.getMetaAccess(), graph);
- ValueNode replacement = graph.unique(new ResolveMethodAndLoadCountersNode(node.getMethod(), klassHint));
+ FixedWithNextNode replacement = graph.add(new ResolveMethodAndLoadCountersNode(node.getMethod(), klassHint));
+ graph.addAfterFixed(findFixedWithNextBefore(graph, node), replacement);
node.replaceAtUsages(replacement, n -> !(n instanceof ResolveMethodAndLoadCountersNode));
}
+ /**
+ * Replace {@link LoadMethodCountersNode} with {@link ResolveMethodAndLoadCountersNode}, expose
+ * klass constants.
+ *
+ * @param graph
+ * @param context
+ */
+ private static void replaceLoadMethodCounters(StructuredGraph graph, PhaseContext context) {
+ new SchedulePhase(SchedulingStrategy.LATEST_OUT_OF_LOOPS, true).apply(graph, false);
+ for (LoadMethodCountersNode node : getLoadMethodCountersNodes(graph)) {
+ if (anyUsagesNeedReplacement(node)) {
+ handleLoadMethodCounters(graph, node, context);
+ }
+ }
+ }
+
+ /**
+ * Replace object and klass constants with resolution nodes or reuse preceding initializations.
+ *
+ * @param graph
+ */
+ private void replaceKlassesAndObjects(StructuredGraph graph) {
+ new SchedulePhase(SchedulingStrategy.LATEST_OUT_OF_LOOPS, true).apply(graph, false);
+
+ for (ConstantNode node : getConstantNodes(graph)) {
+ Constant constant = node.asConstant();
+ if (constant instanceof HotSpotMetaspaceConstant && anyUsagesNeedReplacement(node)) {
+ handleHotSpotMetaspaceConstant(graph, node);
+ } else if (constant instanceof HotSpotObjectConstant && anyUsagesNeedReplacement(node)) {
+ handleHotSpotObjectConstant(graph, node);
+ }
+ }
+ }
+
@Override
protected void run(StructuredGraph graph, PhaseContext context) {
// Replace LoadMethodCountersNode with ResolveMethodAndLoadCountersNode, expose klass
// constants.
- for (LoadMethodCountersNode node : getLoadMethodCountersNodes(graph)) {
- handleLoadMethodCounters(graph, node, context);
- }
+ replaceLoadMethodCounters(graph, context);
// Replace object and klass constants (including the ones added in the previous pass) with
// resolution nodes.
- for (ConstantNode node : getConstantNodes(graph)) {
- Constant constant = node.asConstant();
- if (constant instanceof HotSpotMetaspaceConstant) {
- handleHotSpotMetaspaceConstant(graph, node);
- } else if (constant instanceof HotSpotObjectConstant) {
- handleHotSpotObjectConstant(graph, node);
- }
- }
+ replaceKlassesAndObjects(graph);
}
@Override
@@ -182,4 +344,11 @@
return false;
}
+ public ReplaceConstantNodesPhase() {
+ this(true);
+ }
+
+ public ReplaceConstantNodesPhase(boolean verifyFingerprints) {
+ this.verifyFingerprints = verifyFingerprints;
+ }
}
--- a/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/replacements/InstanceOfSnippets.java Tue Jun 13 07:30:11 2017 -0400
+++ b/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/replacements/InstanceOfSnippets.java Tue Jun 13 09:19:35 2017 -0700
@@ -49,7 +49,6 @@
import org.graalvm.compiler.hotspot.nodes.type.KlassPointerStamp;
import org.graalvm.compiler.hotspot.replacements.TypeCheckSnippetUtils.Counters;
import org.graalvm.compiler.hotspot.replacements.TypeCheckSnippetUtils.Hints;
-import org.graalvm.compiler.hotspot.replacements.aot.ResolveConstantSnippets;
import org.graalvm.compiler.hotspot.word.KlassPointer;
import org.graalvm.compiler.nodes.ConstantNode;
import org.graalvm.compiler.nodes.DeoptimizeNode;
@@ -147,12 +146,6 @@
return trueValue;
}
- @Snippet
- public static Object instanceofExactPIC(Object object, KlassPointer exactHub, Object trueValue, Object falseValue, @ConstantParameter Counters counters) {
- KlassPointer exactHubPIC = ResolveConstantSnippets.resolveKlassConstant(exactHub);
- return instanceofExact(object, exactHubPIC, trueValue, falseValue, counters);
- }
-
/**
* A test against a primary type.
*/
@@ -172,12 +165,6 @@
return trueValue;
}
- @Snippet
- public static Object instanceofPrimaryPIC(KlassPointer hub, Object object, @ConstantParameter int superCheckOffset, Object trueValue, Object falseValue, @ConstantParameter Counters counters) {
- KlassPointer resolvedHub = ResolveConstantSnippets.resolveKlassConstant(hub);
- return instanceofPrimary(resolvedHub, object, superCheckOffset, trueValue, falseValue, counters);
- }
-
/**
* A test against a restricted secondary type type.
*/
@@ -207,13 +194,6 @@
return trueValue;
}
- @Snippet
- public static Object instanceofSecondaryPIC(KlassPointer hub, Object object, @VarargsParameter KlassPointer[] hints, @VarargsParameter boolean[] hintIsPositive, Object trueValue,
- Object falseValue, @ConstantParameter Counters counters) {
- KlassPointer resolvedHub = ResolveConstantSnippets.resolveKlassConstant(hub);
- return instanceofSecondary(resolvedHub, object, hints, hintIsPositive, trueValue, falseValue, counters);
- }
-
/**
* Type test used when the type being tested against is not known at compile time.
*/
@@ -272,11 +252,8 @@
private final SnippetInfo instanceofWithProfile = snippet(InstanceOfSnippets.class, "instanceofWithProfile");
private final SnippetInfo instanceofExact = snippet(InstanceOfSnippets.class, "instanceofExact");
- private final SnippetInfo instanceofExactPIC = snippet(InstanceOfSnippets.class, "instanceofExactPIC");
private final SnippetInfo instanceofPrimary = snippet(InstanceOfSnippets.class, "instanceofPrimary");
- private final SnippetInfo instanceofPrimaryPIC = snippet(InstanceOfSnippets.class, "instanceofPrimaryPIC");
private final SnippetInfo instanceofSecondary = snippet(InstanceOfSnippets.class, "instanceofSecondary", SECONDARY_SUPER_CACHE_LOCATION);
- private final SnippetInfo instanceofSecondaryPIC = snippet(InstanceOfSnippets.class, "instanceofSecondaryPIC", SECONDARY_SUPER_CACHE_LOCATION);
private final SnippetInfo instanceofDynamic = snippet(InstanceOfSnippets.class, "instanceofDynamic", SECONDARY_SUPER_CACHE_LOCATION);
private final SnippetInfo isAssignableFrom = snippet(InstanceOfSnippets.class, "isAssignableFrom", SECONDARY_SUPER_CACHE_LOCATION);
@@ -316,20 +293,17 @@
args.addVarargs("hints", KlassPointer.class, KlassPointerStamp.klassNonNull(), hints.hubs);
args.addVarargs("hintIsPositive", boolean.class, StampFactory.forKind(JavaKind.Boolean), hints.isPositive);
} else if (hintInfo.exact != null) {
- SnippetInfo snippet = GeneratePIC.getValue(localOptions) ? instanceofExactPIC : instanceofExact;
- args = new Arguments(snippet, graph.getGuardsStage(), tool.getLoweringStage());
+ args = new Arguments(instanceofExact, graph.getGuardsStage(), tool.getLoweringStage());
args.add("object", object);
args.add("exactHub", ConstantNode.forConstant(KlassPointerStamp.klassNonNull(), ((HotSpotResolvedObjectType) hintInfo.exact).klass(), providers.getMetaAccess(), graph));
} else if (type.isPrimaryType()) {
- SnippetInfo snippet = GeneratePIC.getValue(localOptions) ? instanceofPrimaryPIC : instanceofPrimary;
- args = new Arguments(snippet, graph.getGuardsStage(), tool.getLoweringStage());
+ args = new Arguments(instanceofPrimary, graph.getGuardsStage(), tool.getLoweringStage());
args.add("hub", hub);
args.add("object", object);
args.addConst("superCheckOffset", type.superCheckOffset());
} else {
Hints hints = createHints(hintInfo, providers.getMetaAccess(), false, graph);
- SnippetInfo snippet = GeneratePIC.getValue(localOptions) ? instanceofSecondaryPIC : instanceofSecondary;
- args = new Arguments(snippet, graph.getGuardsStage(), tool.getLoweringStage());
+ args = new Arguments(instanceofSecondary, graph.getGuardsStage(), tool.getLoweringStage());
args.add("hub", hub);
args.add("object", object);
args.addVarargs("hints", KlassPointer.class, KlassPointerStamp.klassNonNull(), hints.hubs);
--- a/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/replacements/aot/ResolveConstantSnippets.java Tue Jun 13 07:30:11 2017 -0400
+++ b/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/replacements/aot/ResolveConstantSnippets.java Tue Jun 13 09:19:35 2017 -0700
@@ -149,7 +149,7 @@
args.add("constant", value);
SnippetTemplate template = template(args);
- template.instantiate(providers.getMetaAccess(), resolveConstantNode, DEFAULT_REPLACER, tool, args);
+ template.instantiate(providers.getMetaAccess(), resolveConstantNode, DEFAULT_REPLACER, args);
assert resolveConstantNode.hasNoUsages();
if (!resolveConstantNode.isDeleted()) {
@@ -187,7 +187,7 @@
args.add("method", method);
args.add("klassHint", resolveMethodAndLoadCountersNode.getHub());
SnippetTemplate template = template(args);
- template.instantiate(providers.getMetaAccess(), resolveMethodAndLoadCountersNode, DEFAULT_REPLACER, tool, args);
+ template.instantiate(providers.getMetaAccess(), resolveMethodAndLoadCountersNode, DEFAULT_REPLACER, args);
assert resolveMethodAndLoadCountersNode.hasNoUsages();
if (!resolveMethodAndLoadCountersNode.isDeleted()) {
--- a/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.java/src/org/graalvm/compiler/java/BytecodeParser.java Tue Jun 13 07:30:11 2017 -0400
+++ b/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.java/src/org/graalvm/compiler/java/BytecodeParser.java Tue Jun 13 09:19:35 2017 -0700
@@ -1422,7 +1422,7 @@
@Override
public void handleReplacedInvoke(CallTargetNode callTarget, JavaKind resultType) {
BytecodeParser intrinsicCallSiteParser = getNonIntrinsicAncestor();
- boolean withExceptionEdge = intrinsicCallSiteParser == null ? false : intrinsicCallSiteParser.omitInvokeExceptionEdge(null);
+ boolean withExceptionEdge = intrinsicCallSiteParser == null ? !omitInvokeExceptionEdge(null) : !intrinsicCallSiteParser.omitInvokeExceptionEdge(null);
createNonInlinedInvoke(withExceptionEdge, bci(), callTarget, resultType);
}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.java/src/org/graalvm/compiler/java/DefaultSuitesCreator.java Tue Jun 13 09:19:35 2017 -0700
@@ -0,0 +1,59 @@
+/*
+ * Copyright (c) 2012, 2015, 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.java;
+
+import org.graalvm.compiler.lir.phases.LIRSuites;
+import org.graalvm.compiler.nodes.graphbuilderconf.GraphBuilderConfiguration;
+import org.graalvm.compiler.nodes.graphbuilderconf.GraphBuilderConfiguration.Plugins;
+import org.graalvm.compiler.options.OptionValues;
+import org.graalvm.compiler.phases.PhaseSuite;
+import org.graalvm.compiler.phases.tiers.CompilerConfiguration;
+import org.graalvm.compiler.phases.tiers.HighTierContext;
+import org.graalvm.compiler.phases.tiers.Suites;
+
+public class DefaultSuitesCreator extends SuitesProviderBase {
+
+ private final CompilerConfiguration compilerConfiguration;
+
+ public DefaultSuitesCreator(CompilerConfiguration compilerConfiguration, Plugins plugins) {
+ super();
+ this.defaultGraphBuilderSuite = createGraphBuilderSuite(plugins);
+ this.compilerConfiguration = compilerConfiguration;
+ }
+
+ @Override
+ public Suites createSuites(OptionValues options) {
+ return Suites.createSuites(compilerConfiguration, options);
+ }
+
+ protected PhaseSuite<HighTierContext> createGraphBuilderSuite(Plugins plugins) {
+ PhaseSuite<HighTierContext> suite = new PhaseSuite<>();
+ suite.appendPhase(new GraphBuilderPhase(GraphBuilderConfiguration.getDefault(plugins)));
+ return suite;
+ }
+
+ @Override
+ public LIRSuites createLIRSuites(OptionValues options) {
+ return Suites.createLIRSuites(compilerConfiguration, options);
+ }
+}
--- a/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.java/src/org/graalvm/compiler/java/DefaultSuitesProvider.java Tue Jun 13 07:30:11 2017 -0400
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,59 +0,0 @@
-/*
- * Copyright (c) 2012, 2015, 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.java;
-
-import org.graalvm.compiler.lir.phases.LIRSuites;
-import org.graalvm.compiler.nodes.graphbuilderconf.GraphBuilderConfiguration;
-import org.graalvm.compiler.nodes.graphbuilderconf.GraphBuilderConfiguration.Plugins;
-import org.graalvm.compiler.options.OptionValues;
-import org.graalvm.compiler.phases.PhaseSuite;
-import org.graalvm.compiler.phases.tiers.CompilerConfiguration;
-import org.graalvm.compiler.phases.tiers.HighTierContext;
-import org.graalvm.compiler.phases.tiers.Suites;
-
-public class DefaultSuitesProvider extends SuitesProviderBase {
-
- private final CompilerConfiguration compilerConfiguration;
-
- public DefaultSuitesProvider(CompilerConfiguration compilerConfiguration, Plugins plugins) {
- super();
- this.defaultGraphBuilderSuite = createGraphBuilderSuite(plugins);
- this.compilerConfiguration = compilerConfiguration;
- }
-
- @Override
- public Suites createSuites(OptionValues options) {
- return Suites.createSuites(compilerConfiguration, options);
- }
-
- protected PhaseSuite<HighTierContext> createGraphBuilderSuite(Plugins plugins) {
- PhaseSuite<HighTierContext> suite = new PhaseSuite<>();
- suite.appendPhase(new GraphBuilderPhase(GraphBuilderConfiguration.getDefault(plugins)));
- return suite;
- }
-
- @Override
- public LIRSuites createLIRSuites(OptionValues options) {
- return Suites.createLIRSuites(compilerConfiguration, options);
- }
-}
--- a/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir.aarch64/src/org/graalvm/compiler/lir/aarch64/AArch64AddressValue.java Tue Jun 13 07:30:11 2017 -0400
+++ b/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir.aarch64/src/org/graalvm/compiler/lir/aarch64/AArch64AddressValue.java Tue Jun 13 09:19:35 2017 -0700
@@ -46,20 +46,20 @@
@Component({OperandFlag.REG, OperandFlag.ILLEGAL}) protected AllocatableValue base;
@Component({OperandFlag.REG, OperandFlag.ILLEGAL}) protected AllocatableValue offset;
- private final int immediate;
+ private final int displacement;
/**
* Whether register offset should be scaled or not.
*/
- private final boolean scaled;
+ private final int scaleFactor;
private final AddressingMode addressingMode;
- public AArch64AddressValue(ValueKind<?> kind, AllocatableValue base, AllocatableValue offset, int immediate, boolean scaled, AddressingMode addressingMode) {
+ public AArch64AddressValue(ValueKind<?> kind, AllocatableValue base, AllocatableValue offset, int displacement, int scaleFactor, AddressingMode addressingMode) {
super(kind);
this.base = base;
this.offset = offset;
- this.immediate = immediate;
- this.scaled = scaled;
+ this.displacement = displacement;
+ this.scaleFactor = scaleFactor;
this.addressingMode = addressingMode;
}
@@ -79,12 +79,16 @@
return offset;
}
- public int getImmediate() {
- return immediate;
+ public int getDisplacement() {
+ return displacement;
}
public boolean isScaled() {
- return scaled;
+ return scaleFactor != 1;
+ }
+
+ public int getScaleFactor() {
+ return scaleFactor;
}
public AddressingMode getAddressingMode() {
@@ -95,7 +99,7 @@
Register baseReg = toRegister(base);
Register offsetReg = toRegister(offset);
AArch64Assembler.ExtendType extendType = addressingMode == AddressingMode.EXTENDED_REGISTER_OFFSET ? ExtendType.SXTW : null;
- return AArch64Address.createAddress(addressingMode, baseReg, offsetReg, immediate, scaled, extendType);
+ return AArch64Address.createAddress(addressingMode, baseReg, offsetReg, displacement / scaleFactor, isScaled(), extendType);
}
@Override
@@ -103,7 +107,7 @@
AllocatableValue newBase = (AllocatableValue) proc.doValue(inst, base, mode, flags);
AllocatableValue newOffset = (AllocatableValue) proc.doValue(inst, offset, mode, flags);
if (!base.identityEquals(newBase) || !offset.identityEquals(newOffset)) {
- return new AArch64AddressValue(getValueKind(), newBase, newOffset, immediate, scaled, addressingMode);
+ return new AArch64AddressValue(getValueKind(), newBase, newOffset, displacement, scaleFactor, addressingMode);
}
return this;
}
--- a/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir.aarch64/src/org/graalvm/compiler/lir/aarch64/AArch64Move.java Tue Jun 13 07:30:11 2017 -0400
+++ b/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir.aarch64/src/org/graalvm/compiler/lir/aarch64/AArch64Move.java Tue Jun 13 09:19:35 2017 -0700
@@ -145,7 +145,7 @@
public void emitCode(CompilationResultBuilder crb, AArch64MacroAssembler masm) {
Register dst = asRegister(result);
AArch64Address adr = address.toAddress();
- masm.loadAddress(dst, adr, address.getPlatformKind().getSizeInBytes());
+ masm.loadAddress(dst, adr, address.getScaleFactor());
}
}
@@ -241,8 +241,8 @@
@Override
public boolean makeNullCheckFor(Value value, LIRFrameState nullCheckState, int implicitNullCheckLimit) {
- int immediate = addressValue.getImmediate();
- if (state == null && value.equals(addressValue.getBase()) && addressValue.getOffset().equals(Value.ILLEGAL) && immediate >= 0 && immediate < implicitNullCheckLimit) {
+ int displacement = addressValue.getDisplacement();
+ if (state == null && value.equals(addressValue.getBase()) && addressValue.getOffset().equals(Value.ILLEGAL) && displacement >= 0 && displacement < implicitNullCheckLimit) {
state = nullCheckState;
return true;
}
--- a/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir.aarch64/src/org/graalvm/compiler/lir/aarch64/AArch64Unary.java Tue Jun 13 07:30:11 2017 -0400
+++ b/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir.aarch64/src/org/graalvm/compiler/lir/aarch64/AArch64Unary.java Tue Jun 13 09:19:35 2017 -0700
@@ -84,8 +84,8 @@
@Override
public boolean makeNullCheckFor(Value value, LIRFrameState nullCheckState, int implicitNullCheckLimit) {
- int immediate = input.getImmediate();
- if (state == null && value.equals(input.getBase()) && input.getOffset().equals(Value.ILLEGAL) && immediate >= 0 && immediate < implicitNullCheckLimit) {
+ int displacement = input.getDisplacement();
+ if (state == null && value.equals(input.getBase()) && input.getOffset().equals(Value.ILLEGAL) && displacement >= 0 && displacement < implicitNullCheckLimit) {
state = nullCheckState;
return true;
}
--- a/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir/src/org/graalvm/compiler/lir/LIRInstruction.java Tue Jun 13 07:30:11 2017 -0400
+++ b/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir/src/org/graalvm/compiler/lir/LIRInstruction.java Tue Jun 13 09:19:35 2017 -0700
@@ -51,6 +51,7 @@
import org.graalvm.compiler.lir.StandardOp.MoveOp;
import org.graalvm.compiler.lir.StandardOp.ValueMoveOp;
import org.graalvm.compiler.lir.asm.CompilationResultBuilder;
+import org.graalvm.compiler.lir.gen.LIRGenerationResult;
import jdk.vm.ci.code.RegisterValue;
import jdk.vm.ci.code.StackSlot;
@@ -414,6 +415,20 @@
public void verify() {
}
+ /**
+ * Adds a comment to this instruction.
+ */
+ public final void setComment(LIRGenerationResult res, String comment) {
+ res.setComment(this, comment);
+ }
+
+ /**
+ * Gets the comment attached to this instruction.
+ */
+ public final String getComment(LIRGenerationResult res) {
+ return res.getComment(this);
+ }
+
public final String toStringWithIdPrefix() {
if (id != -1) {
return String.format("%4d %s", id, toString());
@@ -426,6 +441,18 @@
return instructionClass.toString(this);
}
+ public String toString(LIRGenerationResult res) {
+ String toString = toString();
+ if (res == null) {
+ return toString;
+ }
+ String comment = getComment(res);
+ if (comment == null) {
+ return toString;
+ }
+ return String.format("%s // %s", toString, comment);
+ }
+
public LIRInstructionClass<?> getLIRInstructionClass() {
return instructionClass;
}
--- a/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir/src/org/graalvm/compiler/lir/alloc/SaveCalleeSaveRegisters.java Tue Jun 13 07:30:11 2017 -0400
+++ b/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir/src/org/graalvm/compiler/lir/alloc/SaveCalleeSaveRegisters.java Tue Jun 13 09:19:35 2017 -0700
@@ -54,19 +54,19 @@
return;
}
LIR lir = lirGenRes.getLIR();
- RegisterMap<Variable> savedRegisters = saveAtEntry(lir, context.lirGen, calleeSaveRegisters, target.arch);
+ RegisterMap<Variable> savedRegisters = saveAtEntry(lir, context.lirGen, lirGenRes, calleeSaveRegisters, target.arch);
for (AbstractBlockBase<?> block : lir.codeEmittingOrder()) {
if (block == null) {
continue;
}
if (block.getSuccessorCount() == 0) {
- restoreAtExit(lir, context.lirGen.getSpillMoveFactory(), savedRegisters, block);
+ restoreAtExit(lir, context.lirGen.getSpillMoveFactory(), lirGenRes, savedRegisters, block);
}
}
}
- private static RegisterMap<Variable> saveAtEntry(LIR lir, LIRGeneratorTool lirGen, RegisterArray calleeSaveRegisters, Architecture arch) {
+ private static RegisterMap<Variable> saveAtEntry(LIR lir, LIRGeneratorTool lirGen, LIRGenerationResult lirGenRes, RegisterArray calleeSaveRegisters, Architecture arch) {
AbstractBlockBase<?> startBlock = lir.getControlFlowGraph().getStartBlock();
ArrayList<LIRInstruction> instructions = lir.getLIRforBlock(startBlock);
int insertionIndex = 1;
@@ -83,6 +83,7 @@
Variable saveVariable = lirGen.newVariable(lirKind);
LIRInstruction save = lirGen.getSpillMoveFactory().createMove(saveVariable, registerValue);
buffer.append(insertionIndex, save);
+ save.setComment(lirGenRes, "SaveCalleeSavedRegisters: saveAtEntry");
saveMap.put(register, saveVariable);
savedRegisterValues[savedRegisterValueIndex++] = registerValue;
}
@@ -91,7 +92,7 @@
return saveMap;
}
- private static void restoreAtExit(LIR lir, LIRGeneratorTool.MoveFactory moveFactory, RegisterMap<Variable> calleeSaveRegisters, AbstractBlockBase<?> block) {
+ private static void restoreAtExit(LIR lir, LIRGeneratorTool.MoveFactory moveFactory, LIRGenerationResult lirGenRes, RegisterMap<Variable> calleeSaveRegisters, AbstractBlockBase<?> block) {
ArrayList<LIRInstruction> instructions = lir.getLIRforBlock(block);
int insertionIndex = instructions.size() - 1;
LIRInsertionBuffer buffer = new LIRInsertionBuffer();
@@ -100,6 +101,7 @@
calleeSaveRegisters.forEach((Register register, Variable saved) -> {
LIRInstruction restore = moveFactory.createMove(register.asValue(saved.getValueKind()), saved);
buffer.append(insertionIndex, restore);
+ restore.setComment(lirGenRes, "SaveCalleeSavedRegisters: restoreAtExit");
});
buffer.finish();
}
--- a/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir/src/org/graalvm/compiler/lir/alloc/lsra/LinearScan.java Tue Jun 13 07:30:11 2017 -0400
+++ b/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir/src/org/graalvm/compiler/lir/alloc/lsra/LinearScan.java Tue Jun 13 09:19:35 2017 -0700
@@ -185,10 +185,12 @@
protected final Interval intervalEndMarker;
public final Range rangeEndMarker;
public final boolean detailedAsserts;
+ private final LIRGenerationResult res;
protected LinearScan(TargetDescription target, LIRGenerationResult res, MoveFactory spillMoveFactory, RegisterAllocationConfig regAllocConfig, AbstractBlockBase<?>[] sortedBlocks,
boolean neverSpillConstants) {
this.ir = res.getLIR();
+ this.res = res;
this.moveFactory = spillMoveFactory;
this.frameMapBuilder = res.getFrameMapBuilder();
this.sortedBlocks = sortedBlocks;
@@ -206,6 +208,10 @@
this.detailedAsserts = DetailedAsserts.getValue(ir.getOptions());
}
+ public LIRGenerationResult getLIRGenerationResult() {
+ return res;
+ }
+
public Interval intervalEndMarker() {
return intervalEndMarker;
}
--- a/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir/src/org/graalvm/compiler/lir/alloc/lsra/LinearScanEliminateSpillMovePhase.java Tue Jun 13 07:30:11 2017 -0400
+++ b/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir/src/org/graalvm/compiler/lir/alloc/lsra/LinearScanEliminateSpillMovePhase.java Tue Jun 13 09:19:35 2017 -0700
@@ -75,12 +75,12 @@
@Override
protected void run(TargetDescription target, LIRGenerationResult lirGenRes, AllocationContext context) {
- eliminateSpillMoves();
+ eliminateSpillMoves(lirGenRes);
}
/**
* @return the index of the first instruction that is of interest for
- * {@link #eliminateSpillMoves()}
+ * {@link #eliminateSpillMoves}
*/
protected int firstInstructionOfInterest() {
// skip the first because it is always a label
@@ -89,7 +89,7 @@
// called once before assignment of register numbers
@SuppressWarnings("try")
- void eliminateSpillMoves() {
+ void eliminateSpillMoves(LIRGenerationResult res) {
try (Indent indent = Debug.logAndIndent("Eliminating unnecessary spill moves")) {
/*
@@ -168,6 +168,7 @@
LIRInstruction move = allocator.getSpillMoveFactory().createMove(toLocation, fromLocation);
insertionBuffer.append(j + 1, move);
+ move.setComment(res, "LSRAEliminateSpillMove: store at definition");
if (Debug.isLogEnabled()) {
Debug.log("inserting move after definition of interval %d to stack slot %s at opId %d", interval.operandNumber, interval.spillSlot(), opId);
--- a/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir/src/org/graalvm/compiler/lir/alloc/lsra/LinearScanOptimizeSpillPositionPhase.java Tue Jun 13 07:30:11 2017 -0400
+++ b/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir/src/org/graalvm/compiler/lir/alloc/lsra/LinearScanOptimizeSpillPositionPhase.java Tue Jun 13 09:19:35 2017 -0700
@@ -55,16 +55,16 @@
@Override
protected void run(TargetDescription target, LIRGenerationResult lirGenRes, AllocationContext context) {
- optimizeSpillPosition();
+ optimizeSpillPosition(lirGenRes);
allocator.printIntervals("After optimize spill position");
}
@SuppressWarnings("try")
- private void optimizeSpillPosition() {
+ private void optimizeSpillPosition(LIRGenerationResult res) {
try (Indent indent0 = Debug.logAndIndent("OptimizeSpillPositions")) {
LIRInsertionBuffer[] insertionBuffers = new LIRInsertionBuffer[allocator.getLIR().linearScanOrder().length];
for (Interval interval : allocator.intervals()) {
- optimizeInterval(insertionBuffers, interval);
+ optimizeInterval(insertionBuffers, interval, res);
}
for (LIRInsertionBuffer insertionBuffer : insertionBuffers) {
if (insertionBuffer != null) {
@@ -76,7 +76,7 @@
}
@SuppressWarnings("try")
- private void optimizeInterval(LIRInsertionBuffer[] insertionBuffers, Interval interval) {
+ private void optimizeInterval(LIRInsertionBuffer[] insertionBuffers, Interval interval, LIRGenerationResult res) {
if (interval == null || !interval.isSplitParent() || interval.spillState() != SpillState.SpillInDominator) {
return;
}
@@ -165,6 +165,7 @@
AllocatableValue fromLocation = interval.getSplitChildAtOpId(spillOpId, OperandMode.DEF, allocator).location();
AllocatableValue toLocation = LinearScan.canonicalSpillOpr(interval);
LIRInstruction move = allocator.getSpillMoveFactory().createMove(toLocation, fromLocation);
+ move.setComment(res, "LSRAOptimizeSpillPos: optimize spill pos");
Debug.log(Debug.VERBOSE_LEVEL, "Insert spill move %s", move);
move.setId(LinearScan.DOMINATOR_SPILL_MOVE_ID);
/*
--- a/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir/src/org/graalvm/compiler/lir/alloc/lsra/MoveResolver.java Tue Jun 13 07:30:11 2017 -0400
+++ b/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir/src/org/graalvm/compiler/lir/alloc/lsra/MoveResolver.java Tue Jun 13 09:19:35 2017 -0700
@@ -36,6 +36,7 @@
import org.graalvm.compiler.lir.LIRInsertionBuffer;
import org.graalvm.compiler.lir.LIRInstruction;
import org.graalvm.compiler.lir.LIRValueUtil;
+import org.graalvm.compiler.lir.gen.LIRGenerationResult;
import org.graalvm.util.Equivalence;
import org.graalvm.util.EconomicSet;
@@ -60,6 +61,8 @@
private boolean multipleReadsAllowed;
private final int[] registerBlocked;
+ private final LIRGenerationResult res;
+
protected void setValueBlocked(Value location, int direction) {
assert direction == 1 || direction == -1 : "out of bounds";
if (isRegister(location)) {
@@ -101,7 +104,6 @@
}
protected MoveResolver(LinearScan allocator) {
-
this.allocator = allocator;
this.multipleReadsAllowed = false;
this.mappingFrom = new ArrayList<>(8);
@@ -110,6 +112,7 @@
this.insertIdx = -1;
this.insertionBuffer = new LIRInsertionBuffer();
this.registerBlocked = new int[allocator.getRegisters().size()];
+ this.res = allocator.getLIRGenerationResult();
}
protected boolean checkEmpty() {
@@ -265,16 +268,18 @@
insertIdx = -1;
}
- private void insertMove(Interval fromInterval, Interval toInterval) {
+ private LIRInstruction insertMove(Interval fromInterval, Interval toInterval) {
assert !fromInterval.operand.equals(toInterval.operand) : "from and to interval equal: " + fromInterval;
assert LIRKind.verifyMoveKinds(toInterval.kind(), fromInterval.kind(), allocator.getRegisterAllocationConfig()) : "move between different types";
assert insertIdx != -1 : "must setup insert position first";
- insertionBuffer.append(insertIdx, createMove(fromInterval.operand, toInterval.operand, fromInterval.location(), toInterval.location()));
+ LIRInstruction move = createMove(fromInterval.operand, toInterval.operand, fromInterval.location(), toInterval.location());
+ insertionBuffer.append(insertIdx, move);
if (Debug.isLogEnabled()) {
Debug.log("insert move from %s to %s at %d", fromInterval, toInterval, insertIdx);
}
+ return move;
}
/**
@@ -287,7 +292,7 @@
return getAllocator().getSpillMoveFactory().createMove(toOpr, fromOpr);
}
- private void insertMove(Constant fromOpr, Interval toInterval) {
+ private LIRInstruction insertMove(Constant fromOpr, Interval toInterval) {
assert insertIdx != -1 : "must setup insert position first";
AllocatableValue toOpr = toInterval.operand;
@@ -297,6 +302,7 @@
if (Debug.isLogEnabled()) {
Debug.log("insert move from value %s to %s at %d", fromOpr, toInterval, insertIdx);
}
+ return move;
}
@SuppressWarnings("try")
@@ -329,12 +335,14 @@
if (safeToProcessMove(fromInterval, toInterval)) {
// this interval can be processed because target is free
+ final LIRInstruction move;
if (fromInterval != null) {
- insertMove(fromInterval, toInterval);
+ move = insertMove(fromInterval, toInterval);
unblockRegisters(fromInterval);
} else {
- insertMove(mappingFromOpr.get(i), toInterval);
+ move = insertMove(mappingFromOpr.get(i), toInterval);
}
+ move.setComment(res, "MoveResolver resolve mapping");
if (LIRValueUtil.isStackSlotValue(toInterval.location())) {
if (busySpillSlots == null) {
busySpillSlots = new ArrayList<>(2);
@@ -404,9 +412,10 @@
blockRegisters(spillInterval);
// insert a move from register to stack and update the mapping
- insertMove(fromInterval, spillInterval);
+ LIRInstruction move = insertMove(fromInterval, spillInterval);
mappingFrom.set(spillCandidate, spillInterval);
unblockRegisters(fromInterval);
+ move.setComment(res, "MoveResolver break cycle");
}
@SuppressWarnings("try")
--- a/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir/src/org/graalvm/compiler/lir/alloc/trace/TraceGlobalMoveResolver.java Tue Jun 13 07:30:11 2017 -0400
+++ b/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir/src/org/graalvm/compiler/lir/alloc/trace/TraceGlobalMoveResolver.java Tue Jun 13 09:19:35 2017 -0700
@@ -81,6 +81,7 @@
private final FrameMapBuilder frameMapBuilder;
private final OptionValues options;
private final RegisterAllocationConfig registerAllocationConfig;
+ private final LIRGenerationResult res;
private void setValueBlocked(Value location, int direction) {
assert direction == 1 || direction == -1 : "out of bounds";
@@ -157,6 +158,7 @@
FrameMap frameMap = frameMapBuilderTool.getFrameMap();
this.firstVirtualStackIndex = !frameMap.frameNeedsAllocating() ? 0 : frameMap.currentFrameSize() + 1;
this.options = res.getLIR().getOptions();
+ this.res = res;
}
private boolean checkEmpty() {
@@ -314,16 +316,18 @@
insertIdx = -1;
}
- private void insertMove(Value fromOperand, AllocatableValue toOperand) {
+ private LIRInstruction insertMove(Value fromOperand, AllocatableValue toOperand) {
assert !fromOperand.equals(toOperand) : "from and to are equal: " + fromOperand + " vs. " + toOperand;
assert LIRKind.verifyMoveKinds(fromOperand.getValueKind(), fromOperand.getValueKind(), registerAllocationConfig) : "move between different types";
assert insertIdx != -1 : "must setup insert position first";
- insertionBuffer.append(insertIdx, createMove(fromOperand, toOperand));
+ LIRInstruction move = createMove(fromOperand, toOperand);
+ insertionBuffer.append(insertIdx, move);
if (Debug.isLogEnabled()) {
Debug.log("insert move from %s to %s at %d", fromOperand, toOperand, insertIdx);
}
+ return move;
}
/**
@@ -363,7 +367,8 @@
AllocatableValue toLocation = mappingTo.get(i);
if (safeToProcessMove(fromLocation, toLocation)) {
// this interval can be processed because target is free
- insertMove(fromLocation, toLocation);
+ LIRInstruction move = insertMove(fromLocation, toLocation);
+ move.setComment(res, "TraceGlobalMoveResolver: resolveMapping");
unblock(fromLocation);
if (isStackSlotValue(toLocation)) {
if (busySpillSlots == null) {
@@ -422,7 +427,8 @@
cycleBreakingSlotsAllocated.increment();
Debug.log("created new slot for spilling: %s", spillSlot);
// insert a move from register to stack and update the mapping
- insertMove(from, spillSlot);
+ LIRInstruction move = insertMove(from, spillSlot);
+ move.setComment(res, "TraceGlobalMoveResolver: breakCycle");
}
block(spillSlot);
mappingFrom.set(spillCandidate, spillSlot);
--- a/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir/src/org/graalvm/compiler/lir/alloc/trace/bu/BottomUpAllocator.java Tue Jun 13 07:30:11 2017 -0400
+++ b/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir/src/org/graalvm/compiler/lir/alloc/trace/bu/BottomUpAllocator.java Tue Jun 13 09:19:35 2017 -0700
@@ -308,6 +308,7 @@
private void insertSpillMoveBefore(AllocatableValue dst, Value src) {
LIRInstruction move = spillMoveFactory.createMove(dst, src);
insertInstructionsBefore.add(move);
+ move.setComment(lirGenRes, "BottomUp: spill move before");
Debug.log("insert before %s", move);
}
@@ -316,6 +317,7 @@
if (!(inst instanceof BlockEndOp)) {
LIRInstruction move = spillMoveFactory.createMove(dst, src);
insertInstructionsAfter.add(move);
+ move.setComment(lirGenRes, "BottomUp: spill move after");
Debug.log("insert after %s", move);
} else {
Debug.log("Block end op. No from %s to %s necessary.", src, dst);
@@ -409,6 +411,7 @@
move = spillMoveFactory.createMove(dest, asVariable(phiOut));
}
Debug.log("Inserting load %s", move);
+ move.setComment(lirGenRes, "BottomUp: phi resolution");
phiResolutionMoves.add(move);
}
--- a/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir/src/org/graalvm/compiler/lir/alloc/trace/lsra/TraceLinearScanEliminateSpillMovePhase.java Tue Jun 13 07:30:11 2017 -0400
+++ b/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir/src/org/graalvm/compiler/lir/alloc/trace/lsra/TraceLinearScanEliminateSpillMovePhase.java Tue Jun 13 09:19:35 2017 -0700
@@ -65,7 +65,7 @@
protected void run(TargetDescription target, LIRGenerationResult lirGenRes, Trace trace, MoveFactory spillMoveFactory, RegisterAllocationConfig registerAllocationConfig,
TraceBuilderResult traceBuilderResult, TraceLinearScan allocator) {
boolean shouldEliminateSpillMoves = shouldEliminateSpillMoves(traceBuilderResult, allocator);
- eliminateSpillMoves(allocator, shouldEliminateSpillMoves, traceBuilderResult);
+ eliminateSpillMoves(allocator, shouldEliminateSpillMoves, traceBuilderResult, lirGenRes);
}
private static boolean shouldEliminateSpillMoves(TraceBuilderResult traceBuilderResult, TraceLinearScan allocator) {
@@ -74,7 +74,7 @@
// called once before assignment of register numbers
@SuppressWarnings("try")
- private static void eliminateSpillMoves(TraceLinearScan allocator, boolean shouldEliminateSpillMoves, TraceBuilderResult traceBuilderResult) {
+ private static void eliminateSpillMoves(TraceLinearScan allocator, boolean shouldEliminateSpillMoves, TraceBuilderResult traceBuilderResult, LIRGenerationResult res) {
try (Indent indent = Debug.logAndIndent("Eliminating unnecessary spill moves: Trace%d", traceBuilderResult.getTraceForBlock(allocator.blockAt(0)).getId())) {
allocator.sortIntervalsBySpillPos();
@@ -166,6 +166,7 @@
LIRInstruction move = allocator.getSpillMoveFactory().createMove(toLocation, fromLocation);
insertionBuffer.append(j + 1, move);
+ move.setComment(res, "TraceLSRAEliminateSpillMove: spill def pos");
if (Debug.isLogEnabled()) {
Debug.log("inserting move after definition of interval %d to stack slot %s at opId %d", interval.operandNumber, interval.spillSlot(), opId);
--- a/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir/src/org/graalvm/compiler/lir/gen/LIRGenerationResult.java Tue Jun 13 07:30:11 2017 -0400
+++ b/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir/src/org/graalvm/compiler/lir/gen/LIRGenerationResult.java Tue Jun 13 09:19:35 2017 -0700
@@ -24,9 +24,13 @@
import org.graalvm.compiler.core.common.CompilationIdentifier;
import org.graalvm.compiler.core.common.CompilationIdentifier.Verbosity;
+import org.graalvm.compiler.debug.Debug;
import org.graalvm.compiler.lir.LIR;
+import org.graalvm.compiler.lir.LIRInstruction;
import org.graalvm.compiler.lir.framemap.FrameMap;
import org.graalvm.compiler.lir.framemap.FrameMapBuilder;
+import org.graalvm.util.EconomicMap;
+import org.graalvm.util.Equivalence;
import jdk.vm.ci.code.CallingConvention;
@@ -43,7 +47,12 @@
/**
* Unique identifier of this compilation.
*/
- private final CompilationIdentifier compilationId;
+ private CompilationIdentifier compilationId;
+
+ /**
+ * Stores comments about a {@link LIRInstruction} , e.g., which phase created it.
+ */
+ private EconomicMap<LIRInstruction, String> comments;
public LIRGenerationResult(CompilationIdentifier compilationId, LIR lir, FrameMapBuilder frameMapBuilder, CallingConvention callingConvention) {
this.lir = lir;
@@ -53,6 +62,28 @@
}
/**
+ * Adds a comment to a {@link LIRInstruction}. Existing comments are replaced.
+ */
+ public final void setComment(LIRInstruction op, String comment) {
+ if (Debug.isDumpEnabled(Debug.BASIC_LEVEL)) {
+ if (comments == null) {
+ comments = EconomicMap.create(Equivalence.IDENTITY);
+ }
+ comments.put(op, comment);
+ }
+ }
+
+ /**
+ * Gets the comment attached to a {@link LIRInstruction}.
+ */
+ public final String getComment(LIRInstruction op) {
+ if (comments == null) {
+ return null;
+ }
+ return comments.get(op);
+ }
+
+ /**
* Returns the incoming calling convention for the parameters of the method that is compiled.
*/
public CallingConvention getCallingConvention() {
--- a/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/SimplifyingGraphDecoder.java Tue Jun 13 07:30:11 2017 -0400
+++ b/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/SimplifyingGraphDecoder.java Tue Jun 13 09:19:35 2017 -0700
@@ -190,13 +190,20 @@
@Override
protected void handleFixedNode(MethodScope methodScope, LoopScope loopScope, int nodeOrderId, FixedNode node) {
- Node canonical = canonicalizeFixedNode(node);
+ Node canonical = canonicalizeFixedNode(methodScope, node);
if (canonical != node) {
handleCanonicalization(loopScope, nodeOrderId, node, canonical);
}
}
- private Node canonicalizeFixedNode(FixedNode node) {
+ /**
+ * Canonicalizes the provided node, which was originally a {@link FixedNode} but can already be
+ * canonicalized (and therefore be a non-fixed node).
+ *
+ * @param methodScope The current method.
+ * @param node The node to be canonicalized.
+ */
+ protected Node canonicalizeFixedNode(MethodScope methodScope, Node node) {
if (node instanceof LoadFieldNode) {
LoadFieldNode loadFieldNode = (LoadFieldNode) node;
return loadFieldNode.canonical(canonicalizerTool);
--- a/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/extended/RawLoadNode.java Tue Jun 13 07:30:11 2017 -0400
+++ b/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/extended/RawLoadNode.java Tue Jun 13 09:19:35 2017 -0700
@@ -57,7 +57,11 @@
* This constructor exists for node intrinsics that need a stamp based on {@code accessKind}.
*/
public RawLoadNode(ValueNode object, ValueNode offset, JavaKind accessKind, LocationIdentity locationIdentity) {
- super(TYPE, StampFactory.forKind(accessKind.getStackKind()), object, offset, accessKind, locationIdentity, false);
+ this(object, offset, accessKind, locationIdentity, false);
+ }
+
+ public RawLoadNode(ValueNode object, ValueNode offset, JavaKind accessKind, LocationIdentity locationIdentity, boolean forceAnyLocation) {
+ super(TYPE, StampFactory.forKind(accessKind.getStackKind()), object, offset, accessKind, locationIdentity, forceAnyLocation);
}
/**
--- a/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.phases.common/src/org/graalvm/compiler/phases/common/AbstractInliningPhase.java Tue Jun 13 07:30:11 2017 -0400
+++ b/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.phases.common/src/org/graalvm/compiler/phases/common/AbstractInliningPhase.java Tue Jun 13 09:19:35 2017 -0700
@@ -29,8 +29,4 @@
* Common superclass for phases that perform inlining.
*/
public abstract class AbstractInliningPhase extends BasePhase<HighTierContext> {
- @Override
- protected boolean isInliningPhase() {
- return true;
- }
}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.phases.common/src/org/graalvm/compiler/phases/common/AddressLoweringByUsePhase.java Tue Jun 13 09:19:35 2017 -0700
@@ -0,0 +1,116 @@
+/*
+ * Copyright (c) 2017, 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.
+ *
+ * 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.phases.common;
+
+import org.graalvm.compiler.core.common.type.Stamp;
+import org.graalvm.compiler.graph.Node;
+import org.graalvm.compiler.nodes.StructuredGraph;
+import org.graalvm.compiler.nodes.ValueNode;
+import org.graalvm.compiler.nodes.extended.JavaReadNode;
+import org.graalvm.compiler.nodes.memory.AbstractWriteNode;
+import org.graalvm.compiler.nodes.memory.FloatingReadNode;
+import org.graalvm.compiler.nodes.memory.ReadNode;
+import org.graalvm.compiler.nodes.memory.address.AddressNode;
+import org.graalvm.compiler.nodes.memory.address.OffsetAddressNode;
+import org.graalvm.compiler.nodes.memory.address.RawAddressNode;
+import org.graalvm.compiler.nodes.util.GraphUtil;
+import org.graalvm.compiler.phases.Phase;
+
+/**
+ * Created by adinn on 09/05/17.
+ */
+public class AddressLoweringByUsePhase extends Phase {
+ public abstract static class AddressLoweringByUse {
+
+ public abstract AddressNode lower(ValueNode use, Stamp stamp, AddressNode address);
+
+ public abstract AddressNode lower(AddressNode address);
+ }
+
+ private final AddressLoweringByUse lowering;
+
+ public AddressLoweringByUsePhase(AddressLoweringByUse lowering) {
+ this.lowering = lowering;
+ assert lowering != null;
+ }
+
+ @Override
+ protected void run(StructuredGraph graph) {
+ // first replace address nodes hanging off known usages
+ for (Node node : graph.getNodes()) {
+ AddressNode address;
+ AddressNode lowered;
+ if (node instanceof ReadNode) {
+ ReadNode readNode = (ReadNode) node;
+ Stamp stamp = readNode.stamp();
+ address = readNode.getAddress();
+ lowered = lowering.lower(readNode, stamp, address);
+ } else if (node instanceof JavaReadNode) {
+ JavaReadNode javaReadNode = (JavaReadNode) node;
+ Stamp stamp = javaReadNode.stamp();
+ address = javaReadNode.getAddress();
+ lowered = lowering.lower(javaReadNode, stamp, address);
+ } else if (node instanceof FloatingReadNode) {
+ FloatingReadNode floatingReadNode = (FloatingReadNode) node;
+ Stamp stamp = floatingReadNode.stamp();
+ address = floatingReadNode.getAddress();
+ lowered = lowering.lower(floatingReadNode, stamp, address);
+ } else if (node instanceof AbstractWriteNode) {
+ AbstractWriteNode abstractWriteNode = (AbstractWriteNode) node;
+ Stamp stamp = abstractWriteNode.value().stamp();
+ address = abstractWriteNode.getAddress();
+ lowered = lowering.lower(abstractWriteNode, stamp, address);
+ // TODO -- PrefetchAllocateNode is not yet implemented for AArch64
+ // } else if (node instanceof PrefetchAllocateNode) {
+ // PrefetchAllocateNode prefetchAllocateNode = (PrefetchAllocateNode) node;
+ // Stamp stamp = prefetchAllocateNode.value().stamp();
+ // n.b.this getter is not provided!
+ // address = prefetchAllocateNode.getAddress();
+ // lowered = lowering.lower(prefetchAllocateNode, stamp, address);
+ } else {
+ continue;
+ }
+ // the lowered address amy already be a replacement
+ // in which case we want to use it not delete it!
+ if (lowered != address) {
+ address.replaceAtUsages(lowered);
+ GraphUtil.killWithUnusedFloatingInputs(address);
+ }
+ }
+
+ // now replace any remaining unlowered address nodes
+ for (Node node : graph.getNodes()) {
+ AddressNode lowered;
+ if (node instanceof RawAddressNode || node instanceof OffsetAddressNode) {
+ AddressNode address = (AddressNode) node;
+ lowered = lowering.lower(address);
+ } else {
+ continue;
+ }
+ // will always be a new AddresNode
+ node.replaceAtUsages(lowered);
+ GraphUtil.killWithUnusedFloatingInputs(node);
+ }
+ }
+}
--- a/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.phases.common/src/org/graalvm/compiler/phases/common/LoweringPhase.java Tue Jun 13 07:30:11 2017 -0400
+++ b/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.phases.common/src/org/graalvm/compiler/phases/common/LoweringPhase.java Tue Jun 13 09:19:35 2017 -0700
@@ -225,6 +225,11 @@
this.loweringStage = loweringStage;
}
+ @Override
+ protected boolean shouldDumpBeforeAtBasicLevel() {
+ return loweringStage == LoweringTool.StandardLoweringStage.HIGH_TIER;
+ }
+
/**
* Checks that second lowering of a given graph did not introduce any new nodes.
*
--- a/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.phases.common/src/org/graalvm/compiler/phases/common/inlining/InliningUtil.java Tue Jun 13 07:30:11 2017 -0400
+++ b/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.phases.common/src/org/graalvm/compiler/phases/common/inlining/InliningUtil.java Tue Jun 13 09:19:35 2017 -0700
@@ -101,6 +101,7 @@
import java.util.ArrayDeque;
import java.util.ArrayList;
import java.util.List;
+import java.util.function.Consumer;
import static jdk.vm.ci.meta.DeoptimizationAction.InvalidateReprofile;
import static jdk.vm.ci.meta.DeoptimizationReason.NullCheckException;
@@ -408,6 +409,12 @@
*/
@SuppressWarnings("try")
public static EconomicSet<Node> inlineForCanonicalization(Invoke invoke, StructuredGraph inlineGraph, boolean receiverNullCheck, ResolvedJavaMethod inlineeMethod) {
+ return inlineForCanonicalization(invoke, inlineGraph, receiverNullCheck, inlineeMethod, null);
+ }
+
+ @SuppressWarnings("try")
+ public static EconomicSet<Node> inlineForCanonicalization(Invoke invoke, StructuredGraph inlineGraph, boolean receiverNullCheck, ResolvedJavaMethod inlineeMethod,
+ Consumer<UnmodifiableEconomicMap<Node, Node>> duplicatesConsumer) {
HashSetNodeEventListener listener = new HashSetNodeEventListener();
/*
* This code relies on the fact that Graph.addDuplicates doesn't trigger the
@@ -415,7 +422,10 @@
* the graph into the current graph.
*/
try (NodeEventScope nes = invoke.asNode().graph().trackNodeEvents(listener)) {
- InliningUtil.inline(invoke, inlineGraph, receiverNullCheck, inlineeMethod);
+ UnmodifiableEconomicMap<Node, Node> duplicates = InliningUtil.inline(invoke, inlineGraph, receiverNullCheck, inlineeMethod);
+ if (duplicatesConsumer != null) {
+ duplicatesConsumer.accept(duplicates);
+ }
}
return listener.getNodes();
}
--- a/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.phases.common/src/org/graalvm/compiler/phases/common/inlining/info/MultiTypeGuardInlineInfo.java Tue Jun 13 07:30:11 2017 -0400
+++ b/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.phases.common/src/org/graalvm/compiler/phases/common/inlining/info/MultiTypeGuardInlineInfo.java Tue Jun 13 09:19:35 2017 -0700
@@ -277,7 +277,7 @@
// do the actual inlining for every invoke
for (int i = 0; i < numberOfMethods; i++) {
Invoke invokeForInlining = (Invoke) successors[i].next();
- canonicalizeNodes.addAll(inline(invokeForInlining, methodAt(i), inlineableElementAt(i), false));
+ canonicalizeNodes.addAll(doInline(i, invokeForInlining));
}
if (returnValuePhi != null) {
canonicalizeNodes.add(returnValuePhi);
@@ -285,6 +285,10 @@
return canonicalizeNodes;
}
+ protected EconomicSet<Node> doInline(int index, Invoke invokeForInlining) {
+ return inline(invokeForInlining, methodAt(index), inlineableElementAt(index), false);
+ }
+
private int getTypeCount(int concreteMethodIndex) {
int count = 0;
for (int i = 0; i < typesToConcretes.size(); i++) {
--- a/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.phases/src/org/graalvm/compiler/phases/BasePhase.java Tue Jun 13 07:30:11 2017 -0400
+++ b/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.phases/src/org/graalvm/compiler/phases/BasePhase.java Tue Jun 13 09:19:35 2017 -0700
@@ -150,8 +150,12 @@
}
private boolean dumpBefore(final StructuredGraph graph, final C context, boolean isTopLevel) {
- if (isTopLevel && Debug.isDumpEnabled(Debug.VERBOSE_LEVEL)) {
- Debug.dump(Debug.VERBOSE_LEVEL, graph, "Before phase %s", getName());
+ if (isTopLevel && (Debug.isDumpEnabled(Debug.VERBOSE_LEVEL) || shouldDumpBeforeAtBasicLevel() && Debug.isDumpEnabled(Debug.BASIC_LEVEL))) {
+ if (shouldDumpBeforeAtBasicLevel()) {
+ Debug.dump(Debug.BASIC_LEVEL, graph, "Before phase %s", getName());
+ } else {
+ Debug.dump(Debug.VERBOSE_LEVEL, graph, "Before phase %s", getName());
+ }
} else if (!isTopLevel && Debug.isDumpEnabled(Debug.VERBOSE_LEVEL + 1)) {
Debug.dump(Debug.VERBOSE_LEVEL + 1, graph, "Before subphase %s", getName());
} else if (Debug.isDumpEnabled(Debug.ENABLED_LEVEL) && shouldDump(graph, context)) {
@@ -161,7 +165,11 @@
return false;
}
- protected boolean isInliningPhase() {
+ protected boolean shouldDumpBeforeAtBasicLevel() {
+ return false;
+ }
+
+ protected boolean shouldDumpAfterAtBasicLevel() {
return false;
}
@@ -207,7 +215,7 @@
private void dumpAfter(final StructuredGraph graph, boolean isTopLevel, boolean dumpedBefore) {
boolean dumped = false;
if (isTopLevel) {
- if (isInliningPhase()) {
+ if (shouldDumpAfterAtBasicLevel()) {
if (Debug.isDumpEnabled(Debug.BASIC_LEVEL)) {
Debug.dump(Debug.BASIC_LEVEL, graph, "After phase %s", getName());
dumped = true;
--- a/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.phases/src/org/graalvm/compiler/phases/verify/VerifyDebugUsage.java Tue Jun 13 07:30:11 2017 -0400
+++ b/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.phases/src/org/graalvm/compiler/phases/verify/VerifyDebugUsage.java Tue Jun 13 09:19:35 2017 -0700
@@ -150,6 +150,7 @@
*/
private static final Set<String> BasicLevelStructuredGraphDumpWhitelist = new HashSet<>(Arrays.asList(
"org.graalvm.compiler.phases.BasePhase.dumpAfter",
+ "org.graalvm.compiler.phases.BasePhase.dumpBefore",
"org.graalvm.compiler.core.GraalCompiler.emitFrontEnd",
"org.graalvm.compiler.truffle.PartialEvaluator.fastPartialEvaluation",
"org.graalvm.compiler.truffle.PartialEvaluator$PerformanceInformationHandler.reportPerformanceWarnings",
--- a/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.printer/src/org/graalvm/compiler/printer/BinaryGraphPrinter.java Tue Jun 13 07:30:11 2017 -0400
+++ b/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.printer/src/org/graalvm/compiler/printer/BinaryGraphPrinter.java Tue Jun 13 09:19:35 2017 -0700
@@ -175,7 +175,7 @@
@Override
public void print(Graph graph, Map<Object, Object> properties, int id, String format, Object... args) throws IOException {
writeByte(BEGIN_GRAPH);
- if (CURRENT_MAJOR_VERSION == 3) {
+ if (CURRENT_MAJOR_VERSION >= 3) {
writeInt(id);
writeString(format);
writeInt(args.length);
@@ -183,7 +183,7 @@
writePropertyObject(a);
}
} else {
- writePoolObject(String.format(format, args));
+ writePoolObject(formatTitle(id, format, args));
}
writeGraph(graph, properties);
flush();
@@ -386,12 +386,14 @@
} else if (object instanceof NodeClass) {
NodeClass<?> nodeClass = (NodeClass<?>) object;
writeByte(POOL_NODE_CLASS);
- if (CURRENT_MAJOR_VERSION == 3) {
+ if (CURRENT_MAJOR_VERSION >= 3) {
writePoolObject(nodeClass.getJavaClass());
+ writeString(nodeClass.getNameTemplate());
} else {
writeString(nodeClass.getJavaClass().getSimpleName());
+ String nameTemplate = nodeClass.getNameTemplate();
+ writeString(nameTemplate.isEmpty() ? nodeClass.shortName() : nameTemplate);
}
- writeString(nodeClass.getNameTemplate());
writeEdgesInfo(nodeClass, Inputs);
writeEdgesInfo(nodeClass, Successors);
} else if (object instanceof ResolvedJavaMethod || object instanceof Bytecode) {
--- a/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.printer/src/org/graalvm/compiler/printer/CFGPrinter.java Tue Jun 13 07:30:11 2017 -0400
+++ b/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.printer/src/org/graalvm/compiler/printer/CFGPrinter.java Tue Jun 13 09:19:35 2017 -0700
@@ -50,6 +50,7 @@
import org.graalvm.compiler.lir.alloc.trace.GlobalLivenessInfo;
import org.graalvm.compiler.lir.debug.IntervalDumper;
import org.graalvm.compiler.lir.debug.IntervalDumper.IntervalVisitor;
+import org.graalvm.compiler.lir.gen.LIRGenerationResult;
import org.graalvm.compiler.nodeinfo.Verbosity;
import org.graalvm.compiler.nodes.AbstractBeginNode;
import org.graalvm.compiler.nodes.AbstractEndNode;
@@ -85,6 +86,7 @@
protected ScheduleResult schedule;
protected ResolvedJavaMethod method;
protected GlobalLivenessInfo livenessInfo;
+ protected LIRGenerationResult res;
/**
* Creates a control flow graph printer.
@@ -555,7 +557,7 @@
out.adjustIndentation(level);
}
- out.print(" instruction ").print(inst.toString()).print(COLUMN_END);
+ out.print(" instruction ").print(inst.toString(res)).print(COLUMN_END);
out.println(COLUMN_END);
}
}
--- a/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.printer/src/org/graalvm/compiler/printer/CFGPrinterObserver.java Tue Jun 13 07:30:11 2017 -0400
+++ b/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.printer/src/org/graalvm/compiler/printer/CFGPrinterObserver.java Tue Jun 13 09:19:35 2017 -0700
@@ -51,6 +51,7 @@
import org.graalvm.compiler.lir.LIR;
import org.graalvm.compiler.lir.alloc.trace.GlobalLivenessInfo;
import org.graalvm.compiler.lir.debug.IntervalDumper;
+import org.graalvm.compiler.lir.gen.LIRGenerationResult;
import org.graalvm.compiler.nodes.StructuredGraph;
import org.graalvm.compiler.nodes.StructuredGraph.ScheduleResult;
import org.graalvm.compiler.nodes.cfg.ControlFlowGraph;
@@ -173,6 +174,7 @@
}
cfgPrinter.nodeLirGenerator = Debug.contextLookup(NodeLIRBuilder.class);
cfgPrinter.livenessInfo = Debug.contextLookup(GlobalLivenessInfo.class);
+ cfgPrinter.res = Debug.contextLookup(LIRGenerationResult.class);
if (cfgPrinter.nodeLirGenerator != null) {
cfgPrinter.target = cfgPrinter.nodeLirGenerator.getLIRGeneratorTool().target();
}
@@ -238,6 +240,7 @@
} finally {
cfgPrinter.target = null;
cfgPrinter.lir = null;
+ cfgPrinter.res = null;
cfgPrinter.nodeLirGenerator = null;
cfgPrinter.livenessInfo = null;
cfgPrinter.cfg = null;
--- a/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.printer/src/org/graalvm/compiler/printer/CanonicalStringGraphPrinter.java Tue Jun 13 07:30:11 2017 -0400
+++ b/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.printer/src/org/graalvm/compiler/printer/CanonicalStringGraphPrinter.java Tue Jun 13 09:19:35 2017 -0700
@@ -267,7 +267,7 @@
TTY.println("Dumping string graphs in %s", this.root);
this.root = null;
}
- String title = id + ": " + String.format(format, args);
+ String title = formatTitle(id, format, args);
Path filePath = currentDirectory.resolve(escapeFileName(title));
try (PrintWriter writer = new PrintWriter(new BufferedWriter(new FileWriter(filePath.toFile())))) {
switch (PrintCanonicalGraphStringFlavor.getValue(options)) {
--- a/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.printer/src/org/graalvm/compiler/printer/GraphPrinter.java Tue Jun 13 07:30:11 2017 -0400
+++ b/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.printer/src/org/graalvm/compiler/printer/GraphPrinter.java Tue Jun 13 09:19:35 2017 -0700
@@ -36,6 +36,7 @@
import jdk.vm.ci.meta.JavaConstant;
import jdk.vm.ci.meta.JavaKind;
+import jdk.vm.ci.meta.JavaType;
import jdk.vm.ci.meta.MetaUtil;
import jdk.vm.ci.meta.ResolvedJavaMethod;
import jdk.vm.ci.runtime.JVMCI;
@@ -141,6 +142,22 @@
}
}
+ default String formatTitle(int id, String format, Object... args) {
+ /*
+ * If an argument is a Class, replace it with the simple name.
+ */
+ Object[] newArgs = new Object[args.length];
+ for (int i = 0; i < newArgs.length; i++) {
+ Object arg = args[i];
+ if (arg instanceof JavaType) {
+ newArgs[i] = ((JavaType) arg).getUnqualifiedName();
+ } else {
+ newArgs[i] = arg;
+ }
+ }
+ return id + ": " + String.format(format, newArgs);
+ }
+
static String truncate(String s) {
if (s.length() > MAX_CONSTANT_TO_STRING_LENGTH) {
return s.substring(0, MAX_CONSTANT_TO_STRING_LENGTH - 3) + "...";
--- a/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.printer/src/org/graalvm/compiler/printer/IdealGraphPrinter.java Tue Jun 13 07:30:11 2017 -0400
+++ b/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.printer/src/org/graalvm/compiler/printer/IdealGraphPrinter.java Tue Jun 13 09:19:35 2017 -0700
@@ -115,7 +115,7 @@
*/
@Override
public void print(Graph graph, Map<Object, Object> properties, int id, String format, Object... args) {
- String title = id + ": " + String.format(format, args);
+ String title = formatTitle(id, format, args);
beginGraph(title);
EconomicSet<Node> noBlockNodes = EconomicSet.create(Equivalence.IDENTITY);
ScheduleResult schedule = null;
--- a/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements.test/src/org/graalvm/compiler/replacements/test/ReplacementsParseTest.java Tue Jun 13 07:30:11 2017 -0400
+++ b/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements.test/src/org/graalvm/compiler/replacements/test/ReplacementsParseTest.java Tue Jun 13 09:19:35 2017 -0700
@@ -68,6 +68,7 @@
private static final String IN_INTERPRETED_HANDLER_MARKER = "*** in interpreted handler ***";
private InlineInvokePlugin.InlineInfo inlineInvokeDecision;
+ private String inlineInvokeMethodName = null;
@SuppressWarnings("serial")
static class CustomError extends Error {
@@ -351,12 +352,15 @@
test(options, "callStringize", Boolean.TRUE);
String standardReturnValue = IN_INTERPRETED_HANDLER_MARKER;
String compiledReturnValue = IN_COMPILED_HANDLER_MARKER;
- for (int i = 0; i < 1000; i++) {
- // Ensures 'exception seen' bit is set for call to stringize
- callStringize(THROW_EXCEPTION_MARKER);
+ forceCompileOverride = true;
+ inlineInvokeDecision = InlineInvokePlugin.InlineInfo.DO_NOT_INLINE_WITH_EXCEPTION;
+ inlineInvokeMethodName = "stringizeId";
+ try {
+ testWithDifferentReturnValues(options, standardReturnValue, compiledReturnValue, "callStringize", THROW_EXCEPTION_MARKER);
+ } finally {
+ inlineInvokeDecision = null;
+ inlineInvokeMethodName = null;
}
- forceCompileOverride = true;
- testWithDifferentReturnValues(options, standardReturnValue, compiledReturnValue, "callStringize", THROW_EXCEPTION_MARKER);
}
@Test
@@ -378,14 +382,17 @@
test(options, "callStringizeId", new TestObject("a string"));
test(options, "callStringizeId", new TestObject(Boolean.TRUE));
TestObject exceptionTestObject = new TestObject(THROW_EXCEPTION_MARKER);
- for (int i = 0; i < 1000; i++) {
- // Ensures 'exception seen' bit is set for call to stringizeId
- callStringizeId(exceptionTestObject);
- }
String standardReturnValue = IN_INTERPRETED_HANDLER_MARKER;
String compiledReturnValue = IN_COMPILED_HANDLER_MARKER;
forceCompileOverride = true;
- testWithDifferentReturnValues(options, standardReturnValue, compiledReturnValue, "callStringizeId", exceptionTestObject);
+ inlineInvokeDecision = InlineInvokePlugin.InlineInfo.DO_NOT_INLINE_WITH_EXCEPTION;
+ inlineInvokeMethodName = "stringizeId";
+ try {
+ testWithDifferentReturnValues(options, standardReturnValue, compiledReturnValue, "callStringizeId", exceptionTestObject);
+ } finally {
+ inlineInvokeDecision = null;
+ inlineInvokeMethodName = null;
+ }
}
public static Object callStringize(Object obj) {
@@ -474,7 +481,10 @@
@Override
protected InlineInvokePlugin.InlineInfo bytecodeParserShouldInlineInvoke(GraphBuilderContext b, ResolvedJavaMethod method, ValueNode[] args) {
- return inlineInvokeDecision;
+ if (inlineInvokeMethodName == null || inlineInvokeMethodName.equals(method.getName())) {
+ return inlineInvokeDecision;
+ }
+ return null;
}
@Test
--- a/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/PEGraphDecoder.java Tue Jun 13 07:30:11 2017 -0400
+++ b/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/PEGraphDecoder.java Tue Jun 13 09:19:35 2017 -0700
@@ -94,6 +94,7 @@
import org.graalvm.compiler.nodes.java.StoreFieldNode;
import org.graalvm.compiler.nodes.java.StoreIndexedNode;
import org.graalvm.compiler.nodes.spi.StampProvider;
+import org.graalvm.compiler.nodes.type.StampTool;
import org.graalvm.compiler.nodes.util.GraphUtil;
import org.graalvm.compiler.options.Option;
import org.graalvm.compiler.options.OptionKey;
@@ -375,56 +376,6 @@
}
}
- /**
- * A graph builder context that allows appending one node to the graph. If a node is appended,
- * the target fixed node is replaced with the new node, and clients must afterwards call commit
- * to complete the replacement.
- *
- * This graph builder context is intended to be used with the {@link NodePlugin} objects passed
- * to the graph decoder.
- */
- protected class PEOnDemandAppendGraphBuilderContext extends PEAppendGraphBuilderContext {
- private final FixedNode targetNode;
- private FixedWithNextNode predecessor;
-
- public PEOnDemandAppendGraphBuilderContext(PEMethodScope inlineScope, FixedNode targetNode) {
- super(inlineScope, targetNode.predecessor() instanceof FixedWithNextNode ? (FixedWithNextNode) targetNode.predecessor() : null);
- this.targetNode = targetNode;
- this.predecessor = targetNode.predecessor() instanceof FixedWithNextNode ? (FixedWithNextNode) targetNode.predecessor() : null;
- }
-
- @Override
- public void push(JavaKind kind, ValueNode value) {
- super.push(kind, value);
- }
-
- private void checkPopLastInstruction() {
- if (predecessor != null) {
- targetNode.replaceAtPredecessor(null);
- lastInstr = predecessor;
- predecessor = null;
- }
- }
-
- @Override
- public <T extends ValueNode> T append(T v) {
- checkPopLastInstruction();
- return super.append(v);
- }
-
- public FixedNode commit(LoopScope loopScope, int nodeOrderId, FixedWithNextNode oldAsFixedWithNextNode) {
- registerNode(loopScope, nodeOrderId, pushedNode, true, false);
- targetNode.replaceAtUsages(pushedNode);
- if (oldAsFixedWithNextNode != null) {
- FixedNode successor = oldAsFixedWithNextNode.next();
- successor.replaceAtPredecessor(null);
- lastInstr.setNext(successor);
- deleteFixedNode(targetNode);
- }
- return lastInstr;
- }
- }
-
@NodeInfo(cycles = CYCLES_IGNORED, size = SIZE_IGNORED)
static class ExceptionPlaceholderNode extends ValueNode {
public static final NodeClass<ExceptionPlaceholderNode> TYPE = NodeClass.create(ExceptionPlaceholderNode.class);
@@ -737,6 +688,26 @@
PEMethodScope inlineScope = new PEMethodScope(graph, methodScope, loopScope, graphToInline, inlineMethod, invokeData, methodScope.inliningDepth + 1,
loopExplosionPlugin, arguments);
+ if (!inlineMethod.isStatic()) {
+ if (StampTool.isPointerAlwaysNull(arguments[0])) {
+ /*
+ * The receiver is null, so we can unconditionally throw a NullPointerException
+ * instead of performing any inlining.
+ */
+ DeoptimizeNode deoptimizeNode = graph.add(new DeoptimizeNode(DeoptimizationAction.InvalidateReprofile, DeoptimizationReason.NullCheckException));
+ predecessor.setNext(deoptimizeNode);
+ finishInlining(inlineScope);
+ /* Continue decoding in the caller. */
+ return loopScope;
+
+ } else if (!StampTool.isPointerNonNull(arguments[0])) {
+ /* The receiver might be null, so we need to insert a null check. */
+ PEAppendGraphBuilderContext graphBuilderContext = new PEAppendGraphBuilderContext(inlineScope, predecessor);
+ arguments[0] = graphBuilderContext.nullCheckedValue(arguments[0]);
+ predecessor = graphBuilderContext.lastInstr;
+ }
+ }
+
/*
* Do the actual inlining by returning the initial loop scope for the inlined method scope.
*/
@@ -926,26 +897,35 @@
protected abstract EncodedGraph lookupEncodedGraph(ResolvedJavaMethod method, BytecodeProvider intrinsicBytecodeProvider);
- @SuppressWarnings("try")
@Override
protected void handleFixedNode(MethodScope s, LoopScope loopScope, int nodeOrderId, FixedNode node) {
PEMethodScope methodScope = (PEMethodScope) s;
- FixedNode replacedNode = node;
if (node instanceof ForeignCallNode) {
ForeignCallNode foreignCall = (ForeignCallNode) node;
if (foreignCall.getBci() == BytecodeFrame.UNKNOWN_BCI && methodScope.invokeData != null) {
foreignCall.setBci(methodScope.invokeData.invoke.bci());
}
- } else if (nodePlugins != null && nodePlugins.length > 0) {
+ }
+
+ super.handleFixedNode(methodScope, loopScope, nodeOrderId, node);
+ }
+
+ @SuppressWarnings("try")
+ @Override
+ protected Node canonicalizeFixedNode(MethodScope s, Node node) {
+ PEMethodScope methodScope = (PEMethodScope) s;
+
+ Node replacedNode = node;
+ if (nodePlugins != null && nodePlugins.length > 0) {
if (node instanceof LoadFieldNode) {
- PEOnDemandAppendGraphBuilderContext graphBuilderContext = new PEOnDemandAppendGraphBuilderContext(methodScope, node);
LoadFieldNode loadFieldNode = (LoadFieldNode) node;
+ PEAppendGraphBuilderContext graphBuilderContext = new PEAppendGraphBuilderContext(methodScope, loadFieldNode);
ResolvedJavaField field = loadFieldNode.field();
if (loadFieldNode.isStatic()) {
for (NodePlugin nodePlugin : nodePlugins) {
if (nodePlugin.handleLoadStaticField(graphBuilderContext, field)) {
- replacedNode = graphBuilderContext.commit(loopScope, nodeOrderId, loadFieldNode);
+ replacedNode = graphBuilderContext.pushedNode;
break;
}
}
@@ -953,20 +933,20 @@
ValueNode object = loadFieldNode.object();
for (NodePlugin nodePlugin : nodePlugins) {
if (nodePlugin.handleLoadField(graphBuilderContext, object, field)) {
- replacedNode = graphBuilderContext.commit(loopScope, nodeOrderId, loadFieldNode);
+ replacedNode = graphBuilderContext.pushedNode;
break;
}
}
}
} else if (node instanceof StoreFieldNode) {
- PEOnDemandAppendGraphBuilderContext graphBuilderContext = new PEOnDemandAppendGraphBuilderContext(methodScope, node);
StoreFieldNode storeFieldNode = (StoreFieldNode) node;
+ PEAppendGraphBuilderContext graphBuilderContext = new PEAppendGraphBuilderContext(methodScope, storeFieldNode);
ResolvedJavaField field = storeFieldNode.field();
if (storeFieldNode.isStatic()) {
ValueNode value = storeFieldNode.value();
for (NodePlugin nodePlugin : nodePlugins) {
if (nodePlugin.handleStoreStaticField(graphBuilderContext, field, value)) {
- replacedNode = graphBuilderContext.commit(loopScope, nodeOrderId, storeFieldNode);
+ replacedNode = graphBuilderContext.pushedNode;
break;
}
}
@@ -975,93 +955,70 @@
ValueNode value = storeFieldNode.value();
for (NodePlugin nodePlugin : nodePlugins) {
if (nodePlugin.handleStoreField(graphBuilderContext, object, field, value)) {
- replacedNode = graphBuilderContext.commit(loopScope, nodeOrderId, storeFieldNode);
+ replacedNode = graphBuilderContext.pushedNode;
break;
}
}
}
} else if (node instanceof LoadIndexedNode) {
- PEOnDemandAppendGraphBuilderContext graphBuilderContext = new PEOnDemandAppendGraphBuilderContext(methodScope, node);
LoadIndexedNode loadIndexedNode = (LoadIndexedNode) node;
+ PEAppendGraphBuilderContext graphBuilderContext = new PEAppendGraphBuilderContext(methodScope, loadIndexedNode);
ValueNode array = loadIndexedNode.array();
ValueNode index = loadIndexedNode.index();
for (NodePlugin nodePlugin : nodePlugins) {
if (nodePlugin.handleLoadIndexed(graphBuilderContext, array, index, loadIndexedNode.elementKind())) {
- replacedNode = graphBuilderContext.commit(loopScope, nodeOrderId, loadIndexedNode);
+ replacedNode = graphBuilderContext.pushedNode;
break;
}
}
} else if (node instanceof StoreIndexedNode) {
- PEOnDemandAppendGraphBuilderContext graphBuilderContext = new PEOnDemandAppendGraphBuilderContext(methodScope, node);
StoreIndexedNode storeIndexedNode = (StoreIndexedNode) node;
+ PEAppendGraphBuilderContext graphBuilderContext = new PEAppendGraphBuilderContext(methodScope, storeIndexedNode);
ValueNode array = storeIndexedNode.array();
ValueNode index = storeIndexedNode.index();
ValueNode value = storeIndexedNode.value();
for (NodePlugin nodePlugin : nodePlugins) {
if (nodePlugin.handleStoreIndexed(graphBuilderContext, array, index, storeIndexedNode.elementKind(), value)) {
- replacedNode = graphBuilderContext.commit(loopScope, nodeOrderId, storeIndexedNode);
+ replacedNode = graphBuilderContext.pushedNode;
break;
}
}
} else if (node instanceof NewInstanceNode) {
- PEOnDemandAppendGraphBuilderContext graphBuilderContext = new PEOnDemandAppendGraphBuilderContext(methodScope, node);
NewInstanceNode newInstanceNode = (NewInstanceNode) node;
+ PEAppendGraphBuilderContext graphBuilderContext = new PEAppendGraphBuilderContext(methodScope, newInstanceNode);
ResolvedJavaType type = newInstanceNode.instanceClass();
for (NodePlugin nodePlugin : nodePlugins) {
if (nodePlugin.handleNewInstance(graphBuilderContext, type)) {
- replacedNode = graphBuilderContext.commit(loopScope, nodeOrderId, newInstanceNode);
+ replacedNode = graphBuilderContext.pushedNode;
break;
}
}
} else if (node instanceof NewArrayNode) {
- PEOnDemandAppendGraphBuilderContext graphBuilderContext = new PEOnDemandAppendGraphBuilderContext(methodScope, node);
NewArrayNode newArrayNode = (NewArrayNode) node;
+ PEAppendGraphBuilderContext graphBuilderContext = new PEAppendGraphBuilderContext(methodScope, newArrayNode);
ResolvedJavaType elementType = newArrayNode.elementType();
ValueNode length = newArrayNode.length();
for (NodePlugin nodePlugin : nodePlugins) {
if (nodePlugin.handleNewArray(graphBuilderContext, elementType, length)) {
- replacedNode = graphBuilderContext.commit(loopScope, nodeOrderId, newArrayNode);
+ replacedNode = graphBuilderContext.pushedNode;
break;
}
}
} else if (node instanceof NewMultiArrayNode) {
- PEOnDemandAppendGraphBuilderContext graphBuilderContext = new PEOnDemandAppendGraphBuilderContext(methodScope, node);
NewMultiArrayNode newArrayNode = (NewMultiArrayNode) node;
+ PEAppendGraphBuilderContext graphBuilderContext = new PEAppendGraphBuilderContext(methodScope, newArrayNode);
ResolvedJavaType elementType = newArrayNode.type();
ValueNode[] dimensions = newArrayNode.dimensions().toArray(new ValueNode[0]);
for (NodePlugin nodePlugin : nodePlugins) {
if (nodePlugin.handleNewMultiArray(graphBuilderContext, elementType, dimensions)) {
- replacedNode = graphBuilderContext.commit(loopScope, nodeOrderId, newArrayNode);
+ replacedNode = graphBuilderContext.pushedNode;
break;
}
}
}
}
- NodeSourcePosition pos = replacedNode.getNodeSourcePosition();
- if (pos != null && methodScope.isInlinedMethod()) {
- NodeSourcePosition newPosition = pos.addCaller(methodScope.getCallerBytecodePosition());
- try (DebugCloseable scope = replacedNode.graph().withNodeSourcePosition(newPosition)) {
- super.handleFixedNode(s, loopScope, nodeOrderId, replacedNode);
- }
- if (replacedNode.isAlive()) {
- replacedNode.setNodeSourcePosition(newPosition);
- }
- } else {
- super.handleFixedNode(s, loopScope, nodeOrderId, replacedNode);
- }
-
- }
-
- private static void deleteFixedNode(FixedNode node) {
- FrameState frameState = null;
- if (node instanceof StateSplit) {
- frameState = ((StateSplit) node).stateAfter();
- }
- node.safeDelete();
- if (frameState != null && frameState.hasNoUsages()) {
- frameState.safeDelete();
- }
+ return super.canonicalizeFixedNode(methodScope, replacedNode);
}
@Override
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.options/src/org/graalvm/options/OptionCategory.java Tue Jun 13 09:19:35 2017 -0700
@@ -0,0 +1,55 @@
+/*
+ * Copyright (c) 2017, 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 org.graalvm.options;
+
+/**
+ * Classifies options in several categories depending on who this option is relevant for.
+ *
+ * @since 1.0
+ */
+public enum OptionCategory {
+
+ /**
+ * An option common for users to apply.
+ *
+ * @since 1.0
+ */
+ USER,
+
+ /**
+ * An option only relevant in corner cases and for fine-tuning.
+ *
+ * @since 1.0
+ */
+ EXPERT,
+
+ /**
+ * An option only relevant when debugging language or instrument implementations.
+ *
+ * @since 1.0
+ */
+ DEBUG
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.options/src/org/graalvm/options/OptionDescriptor.java Tue Jun 13 09:19:35 2017 -0700
@@ -0,0 +1,173 @@
+/*
+ * Copyright (c) 2017, 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 org.graalvm.options;
+
+/**
+ * Represents meta-data for a single option.
+ *
+ * @since 1.0
+ */
+public final class OptionDescriptor {
+
+ private final OptionKey<?> key;
+ private final String name;
+ private final String help;
+ private final OptionCategory kind;
+ private final boolean deprecated;
+
+ OptionDescriptor(OptionKey<?> key, String name, String help, OptionCategory kind, boolean deprecated) {
+ this.key = key;
+ this.name = name;
+ this.help = help;
+ this.kind = kind;
+ this.deprecated = deprecated;
+ }
+
+ /**
+ * Returns the option name of the option represented by this descriptor.
+ *
+ * @since 1.0
+ */
+ public String getName() {
+ return name;
+ }
+
+ /**
+ * Returns the key for this option.
+ *
+ * @since 1.0
+ */
+ public OptionKey<?> getKey() {
+ return key;
+ }
+
+ /**
+ * Returns <code>true</code> if this option was marked deprecated. This indicates that the
+ * option is going to be removed in a future release or its use is not recommended.
+ *
+ * @since 1.0
+ */
+ public boolean isDeprecated() {
+ return deprecated;
+ }
+
+ /**
+ * Returns the user category of this option.
+ *
+ * @since 1.0
+ */
+ public OptionCategory getCategory() {
+ return kind;
+ }
+
+ /**
+ * Returns a human-readable description on how to use the option.
+ *
+ * @since 1.0
+ */
+ public String getHelp() {
+ return help;
+ }
+
+ /**
+ * @since 1.0
+ */
+ @Override
+ public String toString() {
+ return "OptionDescriptor [key=" + key + ", help=" + help + ", kind=" + kind + ", deprecated=" + deprecated + "]";
+ }
+
+ /**
+ * Creates a new option descriptor builder by key. The option group and name is inferred by the
+ * key.
+ *
+ * @since 1.0
+ */
+ public static <T> Builder newBuilder(OptionKey<T> key, String name) {
+ return new Builder(key, name);
+ }
+
+ /**
+ * Represents an option descriptor builder.
+ *
+ * @since 1.0
+ */
+ public static final class Builder {
+
+ private final OptionKey<?> key;
+ private final String name;
+ private boolean deprecated;
+ private OptionCategory category;
+ private String help;
+
+ Builder(OptionKey<?> key, String name) {
+ this.key = key;
+ this.name = name;
+ }
+
+ /**
+ * Defines the user category for this option. The default value is
+ * {@link OptionCategory#DEBUG}.
+ *
+ * @since 1.0
+ */
+ public Builder category(@SuppressWarnings("hiding") OptionCategory category) {
+ this.category = category;
+ return this;
+ }
+
+ /**
+ * Defines whether this option is deprecated. The default value for deprecated is
+ * <code>false</code>. This can be used to evolve options between releases.
+ *
+ * @since 1.0
+ */
+ public Builder deprecated(@SuppressWarnings("hiding") boolean deprecated) {
+ this.deprecated = deprecated;
+ return this;
+ }
+
+ /**
+ * Specifies a human-readable description on how to use the option.
+ *
+ * @since 1.0
+ */
+ public Builder help(@SuppressWarnings("hiding") String help) {
+ this.help = help;
+ return this;
+ }
+
+ /**
+ * Builds and returns a new option descriptor.
+ *
+ * @since 1.0
+ */
+ public OptionDescriptor build() {
+ return new OptionDescriptor(key, name, help, category, deprecated);
+ }
+
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.options/src/org/graalvm/options/OptionDescriptors.java Tue Jun 13 09:19:35 2017 -0700
@@ -0,0 +1,140 @@
+/*
+ * Copyright (c) 2017, 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 org.graalvm.options;
+
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.Iterator;
+import java.util.NoSuchElementException;
+
+/**
+ * An interface to a set of {@link OptionDescriptor}s.
+ *
+ * @since 1.0
+ */
+public interface OptionDescriptors extends Iterable<OptionDescriptor> {
+
+ /**
+ * An empty set of option descriptors.
+ *
+ * @since 1.0
+ */
+ OptionDescriptors EMPTY = new OptionDescriptors() {
+
+ public Iterator<OptionDescriptor> iterator() {
+ return Collections.<OptionDescriptor> emptyList().iterator();
+ }
+
+ public OptionDescriptor get(String key) {
+ return null;
+ }
+ };
+
+ /**
+ * Gets the {@link OptionDescriptor} matching a given option name or {@code null} if this option
+ * descriptor set doesn't contain a matching option name.
+ *
+ * @since 1.0
+ */
+ OptionDescriptor get(String optionName);
+
+ /**
+ * Create a union options descriptor out of multiple given descriptors. The operation
+ * descriptors are not checked for duplicate keys. The option descriptors are iterated in
+ * declaration order.
+ *
+ * @since 1.0
+ */
+ static OptionDescriptors createUnion(OptionDescriptors... descriptors) {
+ if (descriptors.length == 0) {
+ return EMPTY;
+ } else if (descriptors.length == 1) {
+ return descriptors[0];
+ } else {
+ return new UnionOptionDescriptors(descriptors);
+ }
+ }
+}
+
+final class UnionOptionDescriptors implements OptionDescriptors {
+
+ final OptionDescriptors[] descriptorsList;
+
+ UnionOptionDescriptors(OptionDescriptors[] descriptors) {
+ // defensive copy
+ this.descriptorsList = Arrays.copyOf(descriptors, descriptors.length);
+ }
+
+ public Iterator<OptionDescriptor> iterator() {
+ return new Iterator<OptionDescriptor>() {
+
+ Iterator<OptionDescriptor> descriptors = descriptorsList[0].iterator();
+ int descriptorsIndex = 0;
+ OptionDescriptor next = null;
+
+ public boolean hasNext() {
+ return fetchNext() != null;
+ }
+
+ private OptionDescriptor fetchNext() {
+ if (next != null) {
+ return next;
+ }
+ if (descriptors.hasNext()) {
+ next = descriptors.next();
+ return next;
+ } else if (descriptorsIndex < descriptorsList.length - 1) {
+ descriptorsIndex++;
+ descriptors = descriptorsList[descriptorsIndex].iterator();
+ return fetchNext();
+ } else {
+ return null;
+ }
+ }
+
+ public OptionDescriptor next() {
+ OptionDescriptor fetchedNext = fetchNext();
+ if (fetchedNext != null) {
+ // consume next
+ this.next = null;
+ return fetchedNext;
+ } else {
+ throw new NoSuchElementException();
+ }
+ }
+ };
+ }
+
+ public OptionDescriptor get(String value) {
+ for (OptionDescriptors descriptors : descriptorsList) {
+ OptionDescriptor descriptor = descriptors.get(value);
+ if (descriptor != null) {
+ return descriptor;
+ }
+ }
+ return null;
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.options/src/org/graalvm/options/OptionKey.java Tue Jun 13 09:19:35 2017 -0700
@@ -0,0 +1,95 @@
+/*
+ * Copyright (c) 2017, 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 org.graalvm.options;
+
+import java.util.Objects;
+
+/**
+ * Represents the option key for a option specification.
+ *
+ * @since 1.0
+ */
+public final class OptionKey<T> {
+
+ private final OptionType<T> type;
+ private final T defaultValue;
+
+ /**
+ * Constructs a new option key given a default value. Throws {@link IllegalArgumentException} if
+ * no default {@link OptionType} could be {@link OptionType#defaultType(Object) resolved} for
+ * the given type. The default value must not be <code>null</code>.
+ *
+ * @since 1.0
+ */
+ public OptionKey(T defaultValue) {
+ Objects.requireNonNull(defaultValue);
+ this.defaultValue = defaultValue;
+ this.type = OptionType.defaultType(defaultValue);
+ if (type == null) {
+ throw new IllegalArgumentException("No default type specified for type " + defaultValue.getClass().getName() + ". Specify the option type explicitely to resolve this.");
+ }
+ }
+
+ /**
+ * Contructs a new option key givena default value and option key. The default value and the
+ * type must not be <code>null</code>.
+ *
+ * @since 1.0
+ */
+ public OptionKey(T defaultValue, OptionType<T> type) {
+ Objects.requireNonNull(defaultValue);
+ Objects.requireNonNull(type);
+ this.defaultValue = defaultValue;
+ this.type = type;
+ }
+
+ /**
+ * Returns the option type of this key.
+ *
+ * @since 1.0
+ */
+ public OptionType<T> getType() {
+ return type;
+ }
+
+ /**
+ * Returns the default value for this option.
+ *
+ * @since 1.0
+ */
+ public T getDefaultValue() {
+ return defaultValue;
+ }
+
+ /**
+ * Returns the value of this key given the {@link OptionValues values}.
+ *
+ * @since 1.0
+ */
+ public T getValue(OptionValues values) {
+ return values.get(this);
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.options/src/org/graalvm/options/OptionType.java Tue Jun 13 09:19:35 2017 -0700
@@ -0,0 +1,211 @@
+/*
+ * Copyright (c) 2017, 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 org.graalvm.options;
+
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Objects;
+import java.util.function.Consumer;
+import java.util.function.Function;
+
+/**
+ * Represents a type of an option that allows to convert string values to a java value.
+ *
+ * @since 1.0
+ */
+public final class OptionType<T> {
+
+ private final String name;
+ private final Function<String, T> stringConverter;
+ private final Consumer<T> validator;
+ private final T defaultValue;
+
+ /**
+ * Constructs a new option type with name, defaultValue and function that allows to convert a
+ * string to the option type.
+ *
+ * @param name the name of the type to identify it
+ * @param defaultValue the default value to use if no value is given
+ * @param stringConverter a function that converts a string value to the actual option value.
+ * Can throw {@link IllegalArgumentException} to indicate an invalid string.
+ * @param validator used for validating the option value. Throws
+ * {@link IllegalArgumentException} if the value is invalid.
+ *
+ * @since 1.0
+ */
+ public OptionType(String name, T defaultValue, Function<String, T> stringConverter, Consumer<T> validator) {
+ Objects.requireNonNull(name);
+ Objects.requireNonNull(defaultValue);
+ Objects.requireNonNull(stringConverter);
+ Objects.requireNonNull(validator);
+ this.name = name;
+ this.stringConverter = stringConverter;
+ this.defaultValue = defaultValue;
+ this.validator = validator;
+ }
+
+ /**
+ * Constructs a new option type with name, defaultValue and function that allows to convert a
+ * string to the option type.
+ *
+ * @param name the name of the type to identify it
+ * @param defaultValue the default value to use if no value is given
+ * @param stringConverter a function that converts a string value to the actual option value.
+ * Can throw {@link IllegalArgumentException} to indicate an invalid string.
+ *
+ * @since 1.0
+ */
+ public OptionType(String name, T defaultValue, Function<String, T> stringConverter) {
+ this(name, defaultValue, stringConverter, new Consumer<T>() {
+ public void accept(T t) {
+ }
+ });
+ }
+
+ /**
+ * Returns the default value of this type, to be used if no value is available.
+ *
+ * @since 1.0
+ */
+ public T getDefaultValue() {
+ return defaultValue;
+ }
+
+ /**
+ * Returns the name of this type.
+ *
+ * @since 1.0
+ */
+ public String getName() {
+ return name;
+ }
+
+ /**
+ * Converts a string value, validates it and converts it to an object of this type.
+ *
+ * @throws IllegalArgumentException if the value is invalid or cannot be converted.
+ * @since 1.0
+ */
+ public T convert(String value) {
+ T v = stringConverter.apply(value);
+ validate(v);
+ return v;
+ }
+
+ /**
+ * Validates an option value and throws an {@link IllegalArgumentException} if it is invalid.
+ *
+ * @throws IllegalArgumentException if the value is invalid or cannot be converted.
+ * @since 1.0
+ */
+ public void validate(T value) {
+ validator.accept(value);
+ }
+
+ /**
+ * @since 1.0
+ */
+ @Override
+ public String toString() {
+ return "OptionType[name=" + name + ", defaultValue=" + defaultValue + "]";
+ }
+
+ private static Map<Class<?>, OptionType<?>> DEFAULTTYPES = new HashMap<>();
+ static {
+ DEFAULTTYPES.put(Boolean.class, new OptionType<>("Boolean", false, new Function<String, Boolean>() {
+ public Boolean apply(String t) {
+ if ("true".equals(t)) {
+ return Boolean.TRUE;
+ } else if ("false".equals(t)) {
+ return Boolean.FALSE;
+ } else {
+ throw new IllegalArgumentException(String.format("Invalid boolean option value '%s'. The value of the option must be '%s' or '%s'.", t, "true", "false"));
+ }
+ }
+ }));
+ DEFAULTTYPES.put(Byte.class, new OptionType<>("Byte", (byte) 0, new Function<String, Byte>() {
+ public Byte apply(String t) {
+ try {
+ return Byte.parseByte(t);
+ } catch (NumberFormatException e) {
+ throw new IllegalArgumentException(e.getMessage(), e);
+ }
+ }
+ }));
+ DEFAULTTYPES.put(Integer.class, new OptionType<>("Integer", 0, new Function<String, Integer>() {
+ public Integer apply(String t) {
+ try {
+ return Integer.parseInt(t);
+ } catch (NumberFormatException e) {
+ throw new IllegalArgumentException(e.getMessage(), e);
+ }
+ }
+ }));
+ DEFAULTTYPES.put(Long.class, new OptionType<>("Long", 0L, new Function<String, Long>() {
+ public Long apply(String t) {
+ try {
+ return Long.parseLong(t);
+ } catch (NumberFormatException e) {
+ throw new IllegalArgumentException(e.getMessage(), e);
+ }
+ }
+ }));
+ DEFAULTTYPES.put(Float.class, new OptionType<>("Float", 0.0f, new Function<String, Float>() {
+ public Float apply(String t) {
+ try {
+ return Float.parseFloat(t);
+ } catch (NumberFormatException e) {
+ throw new IllegalArgumentException(e.getMessage(), e);
+ }
+ }
+ }));
+ DEFAULTTYPES.put(Double.class, new OptionType<>("Double", 0.0d, new Function<String, Double>() {
+ public Double apply(String t) {
+ try {
+ return Double.parseDouble(t);
+ } catch (NumberFormatException e) {
+ throw new IllegalArgumentException(e.getMessage(), e);
+ }
+ }
+ }));
+ DEFAULTTYPES.put(String.class, new OptionType<>("String", "0", new Function<String, String>() {
+ public String apply(String t) {
+ return t;
+ }
+ }));
+ }
+
+ /**
+ * Returns the default option type for a given value. Returns <code>null</code> if no default
+ * option type is available for this java type.
+ *
+ * @since 1.0
+ */
+ @SuppressWarnings("unchecked")
+ public static <T> OptionType<T> defaultType(Object value) {
+ return (OptionType<T>) DEFAULTTYPES.get(value.getClass());
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.options/src/org/graalvm/options/OptionValues.java Tue Jun 13 09:19:35 2017 -0700
@@ -0,0 +1,55 @@
+/*
+ * Copyright (c) 2017, 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 org.graalvm.options;
+
+/**
+ * Represents a set of option values based on an {@link OptionDescriptor}.
+ *
+ * @since 1.0
+ */
+public interface OptionValues {
+
+ /**
+ * Returns all available options.
+ *
+ * @since 1.0
+ */
+ OptionDescriptors getDescriptors();
+
+ /**
+ * Sets the value of {@code optionKey} to {@code value}.
+ *
+ * @since 1.0
+ */
+ <T> void set(OptionKey<T> optionKey, T value);
+
+ /**
+ * Returns the value of a given option. Returns <code>null</code> if the option does not exist.
+ *
+ * @since 1.0
+ */
+ <T> T get(OptionKey<T> optionKey);
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.options/src/org/graalvm/options/package-info.java Tue Jun 13 09:19:35 2017 -0700
@@ -0,0 +1,33 @@
+/*
+ * Copyright (c) 2017, 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.
+ */
+/**
+ * The Graal-SDK options package contains reusable collection classes for options.
+ *
+ * @see org.graalvm.options.OptionDescriptor
+ * @see org.graalvm.options.OptionValues
+ *
+ * @since 1.0
+ */
+package org.graalvm.options;
\ No newline at end of file