# HG changeset patch # User iveresov # Date 1492575056 0 # Node ID ab5b504181d8a249669a393fa0280d7ab5c8b9c5 # Parent d5572756efd6ce814f4eccc6122915ebb96a852d# Parent c5bfe8f7bb1e11eb9edf11db4df81451f2a5d425 Merge diff -r d5572756efd6 -r ab5b504181d8 hotspot/src/jdk.internal.vm.compiler/.mx.graal/suite.py --- a/hotspot/src/jdk.internal.vm.compiler/.mx.graal/suite.py Tue Apr 18 20:10:55 2017 -0700 +++ b/hotspot/src/jdk.internal.vm.compiler/.mx.graal/suite.py Wed Apr 19 04:10:56 2017 +0000 @@ -199,6 +199,7 @@ "dependencies" : [ "org.graalvm.compiler.api.runtime", "org.graalvm.compiler.replacements", + "org.graalvm.compiler.printer", "org.graalvm.compiler.runtime", ], "imports" : [ @@ -929,6 +930,7 @@ "subDir" : "share/classes", "sourceDirs" : ["src"], "dependencies" : [ + "org.graalvm.util", "mx:JUNIT", ], "checkstyle" : "org.graalvm.compiler.graph", diff -r d5572756efd6 -r ab5b504181d8 hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.asm.aarch64/src/org/graalvm/compiler/asm/aarch64/AArch64Address.java --- a/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.asm.aarch64/src/org/graalvm/compiler/asm/aarch64/AArch64Address.java Tue Apr 18 20:10:55 2017 -0700 +++ b/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.asm.aarch64/src/org/graalvm/compiler/asm/aarch64/AArch64Address.java Wed Apr 19 04:10:56 2017 +0000 @@ -286,7 +286,7 @@ return immediate & NumUtil.getNbitNumberInt(9); case IMMEDIATE_SCALED: // Unsigned value can be returned as-is. - assert NumUtil.isUnsignedNbit(9, immediate); + assert NumUtil.isUnsignedNbit(12, immediate); return immediate; case PC_LITERAL: // 21-bit signed value, but lower 2 bits are always 0 and are shifted out. diff -r d5572756efd6 -r ab5b504181d8 hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/ByteBufferTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/ByteBufferTest.java Wed Apr 19 04:10:56 2017 +0000 @@ -0,0 +1,174 @@ +/* + * 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.core.test; + +import java.nio.ByteBuffer; +import java.nio.ByteOrder; +import java.util.ArrayList; +import java.util.Collection; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.Parameterized; +import org.junit.runners.Parameterized.Parameter; +import org.junit.runners.Parameterized.Parameters; + +@RunWith(Parameterized.class) +public class ByteBufferTest extends GraalCompilerTest { + + class Ret { + + byte byteValue = 0; + short shortValue = 0; + int intValue = 0; + float floatValue = 0.0f; + double doubleValue = 0.0d; + + @Override + public boolean equals(Object obj) { + if (!(obj instanceof Ret)) { + return false; + } + + Ret other = (Ret) obj; + if (this.byteValue != other.byteValue) { + return false; + } + if (this.shortValue != other.shortValue) { + return false; + } + if (this.intValue != other.intValue) { + return false; + } + if (Float.floatToRawIntBits(this.floatValue) != Float.floatToRawIntBits(other.floatValue)) { + return false; + } + if (Double.doubleToRawLongBits(this.doubleValue) != Double.doubleToRawLongBits(other.doubleValue)) { + return false; + } + + return true; + } + + @Override + public int hashCode() { + return 0; + } + + @Override + public String toString() { + return String.format("0x%02x, 0x%04x, 0x%08x, 0x%04x, 0x%08x", byteValue, shortValue, intValue, Float.floatToRawIntBits(floatValue), Double.doubleToRawLongBits(doubleValue)); + } + } + + @Parameters(name = "{0}") + public static Collection data() { + ArrayList ret = new ArrayList<>(); + ret.add(new Object[]{ByteOrder.BIG_ENDIAN}); + ret.add(new Object[]{ByteOrder.LITTLE_ENDIAN}); + return ret; + } + + @Parameter public ByteOrder byteOrder; + + Ret alignedReadSnippet(byte[] arg) { + ByteBuffer buffer = ByteBuffer.wrap(arg).order(byteOrder); + + Ret ret = new Ret(); + ret.byteValue = buffer.get(); + ret.byteValue += buffer.get(); + ret.shortValue = buffer.getShort(); + ret.intValue = buffer.getInt(); + ret.doubleValue = buffer.getDouble(); + ret.floatValue = buffer.getFloat(); + + return ret; + } + + @Test + public void testReadAligned() { + byte[] input = new byte[20]; + for (int i = 0; i < 20; i++) { + input[i] = (byte) (7 * (i + 42)); + } + test("alignedReadSnippet", input); + } + + byte[] alignedWriteSnippet(byte a, byte b, short c, int d, double e, float f) { + byte[] ret = new byte[20]; + ByteBuffer buffer = ByteBuffer.wrap(ret).order(byteOrder); + + buffer.put(a); + buffer.put(b); + buffer.putShort(c); + buffer.putInt(d); + buffer.putDouble(e); + buffer.putFloat(f); + + return ret; + } + + @Test + public void testWriteAligned() { + test("alignedWriteSnippet", (byte) 5, (byte) -3, (short) 17, 42, 84.72, 1.23f); + } + + Ret unalignedReadSnippet(byte[] arg) { + ByteBuffer buffer = ByteBuffer.wrap(arg).order(byteOrder); + + Ret ret = new Ret(); + ret.byteValue = buffer.get(); + ret.shortValue = buffer.getShort(); + ret.intValue = buffer.getInt(); + ret.doubleValue = buffer.getDouble(); + ret.floatValue = buffer.getFloat(); + + return ret; + } + + @Test + public void testReadUnaligned() { + byte[] input = new byte[19]; + for (int i = 0; i < 19; i++) { + input[i] = (byte) (7 * (i + 42)); + } + test("unalignedReadSnippet", input); + } + + byte[] unalignedWriteSnippet(byte a, short b, int c, double d, float e) { + byte[] ret = new byte[20]; + ByteBuffer buffer = ByteBuffer.wrap(ret).order(byteOrder); + + buffer.put(a); + buffer.putShort(b); + buffer.putInt(c); + buffer.putDouble(d); + buffer.putFloat(e); + + return ret; + } + + @Test + public void testWriteUnaligned() { + test("unalignedWriteSnippet", (byte) -3, (short) 17, 42, 84.72, 1.23f); + } +} diff -r d5572756efd6 -r ab5b504181d8 hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/CheckGraalInvariants.java --- a/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/CheckGraalInvariants.java Tue Apr 18 20:10:55 2017 -0700 +++ b/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/CheckGraalInvariants.java Wed Apr 19 04:10:56 2017 +0000 @@ -57,6 +57,7 @@ import org.graalvm.compiler.debug.DebugEnvironment; import org.graalvm.compiler.debug.DelegatingDebugConfig; import org.graalvm.compiler.debug.GraalDebugConfig; +import org.graalvm.compiler.debug.GraalError; import org.graalvm.compiler.graph.Node; import org.graalvm.compiler.graph.NodeClass; import org.graalvm.compiler.java.GraphBuilderPhase; @@ -72,6 +73,7 @@ import org.graalvm.compiler.phases.PhaseSuite; import org.graalvm.compiler.phases.VerifyPhase; import org.graalvm.compiler.phases.VerifyPhase.VerificationError; +import org.graalvm.compiler.phases.contract.VerifyNodeCosts; import org.graalvm.compiler.phases.tiers.HighTierContext; import org.graalvm.compiler.phases.util.Providers; import org.graalvm.compiler.phases.verify.VerifyBailoutUsage; @@ -114,17 +116,52 @@ return true; } - private static boolean shouldProcess(String classpathEntry) { - if (classpathEntry.endsWith(".jar")) { - String name = new File(classpathEntry).getName(); - return name.contains("jvmci") || name.contains("graal") || name.contains("jdk.internal.vm.compiler"); + public static String relativeFileName(String absolutePath) { + int lastFileSeparatorIndex = absolutePath.lastIndexOf(File.separator); + return absolutePath.substring(lastFileSeparatorIndex >= 0 ? lastFileSeparatorIndex : 0); + } + + public static class InvariantsTool { + + protected boolean shouldProcess(String classpathEntry) { + if (classpathEntry.endsWith(".jar")) { + String name = new File(classpathEntry).getName(); + return name.contains("jvmci") || name.contains("graal") || name.contains("jdk.internal.vm.compiler"); + } + return false; } - return false; + + protected String getClassPath() { + String bootclasspath; + if (Java8OrEarlier) { + bootclasspath = System.getProperty("sun.boot.class.path"); + } else { + bootclasspath = System.getProperty("jdk.module.path") + File.pathSeparatorChar + System.getProperty("jdk.module.upgrade.path"); + } + return bootclasspath; + } + + protected boolean shouldLoadClass(String className) { + return !className.equals("module-info"); + } + + protected void handleClassLoadingException(Throwable t) { + GraalError.shouldNotReachHere(t); + } + + protected void handleParsingException(Throwable t) { + GraalError.shouldNotReachHere(t); + } } @Test @SuppressWarnings("try") public void test() { + runTest(new InvariantsTool()); + } + + @SuppressWarnings("try") + public static void runTest(InvariantsTool tool) { RuntimeProvider rt = Graal.getRequiredCapability(RuntimeProvider.class); Providers providers = rt.getHostBackend().getProviders(); MetaAccessProvider metaAccess = providers.getMetaAccess(); @@ -137,17 +174,12 @@ Assume.assumeTrue(VerifyPhase.class.desiredAssertionStatus()); - String bootclasspath; - if (Java8OrEarlier) { - bootclasspath = System.getProperty("sun.boot.class.path"); - } else { - bootclasspath = System.getProperty("jdk.module.path") + File.pathSeparatorChar + System.getProperty("jdk.module.upgrade.path"); - } + String bootclasspath = tool.getClassPath(); Assert.assertNotNull("Cannot find boot class path", bootclasspath); final List classNames = new ArrayList<>(); for (String path : bootclasspath.split(File.pathSeparator)) { - if (shouldProcess(path)) { + if (tool.shouldProcess(path)) { try { final ZipFile zipFile = new ZipFile(new File(path)); for (final Enumeration entry = zipFile.entries(); entry.hasMoreElements();) { @@ -200,7 +232,7 @@ // Order outer classes before the inner classes classNames.sort((String a, String b) -> a.compareTo(b)); // Initialize classes in single thread to avoid deadlocking issues during initialization - List> classes = initializeClasses(classNames); + List> classes = initializeClasses(tool, classNames); for (Class c : classes) { String className = c.getName(); executor.execute(() -> { @@ -234,7 +266,11 @@ // Graal bail outs on certain patterns in Java bytecode (e.g., // unbalanced monitors introduced by jacoco). } catch (Throwable e) { - errors.add(String.format("Error while checking %s:%n%s", methodName, printStackTraceToString(e))); + try { + tool.handleParsingException(e); + } catch (Throwable t) { + errors.add(String.format("Error while checking %s:%n%s", methodName, printStackTraceToString(e))); + } } }); } @@ -261,17 +297,17 @@ } } - private static List> initializeClasses(List classNames) { + private static List> initializeClasses(InvariantsTool tool, List classNames) { List> classes = new ArrayList<>(classNames.size()); for (String className : classNames) { - if (className.equals("module-info")) { + if (!tool.shouldLoadClass(className)) { continue; } try { Class c = Class.forName(className, true, CheckGraalInvariants.class.getClassLoader()); classes.add(c); - } catch (ClassNotFoundException e) { - e.printStackTrace(); + } catch (Throwable t) { + tool.handleClassLoadingException(t); } } return classes; @@ -285,6 +321,7 @@ if (c.getAnnotation(NodeInfo.class) == null) { throw new AssertionError(String.format("Node subclass %s requires %s annotation", c.getName(), NodeClass.class.getSimpleName())); } + VerifyNodeCosts.verifyNodeClass(c); } } diff -r d5572756efd6 -r ab5b504181d8 hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/NodePropertiesTest.java --- a/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/NodePropertiesTest.java Tue Apr 18 20:10:55 2017 -0700 +++ b/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/NodePropertiesTest.java Wed Apr 19 04:10:56 2017 +0000 @@ -22,9 +22,6 @@ */ package org.graalvm.compiler.core.test; -import org.junit.Assert; -import org.junit.Test; - import org.graalvm.compiler.api.directives.GraalDirectives; import org.graalvm.compiler.debug.Debug; import org.graalvm.compiler.graph.Node; @@ -35,13 +32,14 @@ import org.graalvm.compiler.nodes.LoopBeginNode; import org.graalvm.compiler.nodes.StructuredGraph; import org.graalvm.compiler.nodes.ValueNode; -import org.graalvm.compiler.nodes.spi.NodeCostProvider; import org.graalvm.compiler.phases.BasePhase; import org.graalvm.compiler.phases.common.CanonicalizerPhase; import org.graalvm.compiler.phases.common.CanonicalizerPhase.CustomCanonicalizer; import org.graalvm.compiler.phases.contract.NodeCostUtil; import org.graalvm.compiler.phases.tiers.HighTierContext; import org.graalvm.compiler.phases.tiers.PhaseContext; +import org.junit.Assert; +import org.junit.Test; public class NodePropertiesTest extends GraalCompilerTest { @@ -147,9 +145,8 @@ } public static int arrayStoreTest(int a) { - String s = String.valueOf(a); - array[2] = s; - return s.length(); + array[2] = a; + return a; } public static int fieldLoad(int a) { @@ -164,10 +161,10 @@ @Test public void testCanonicalizationExample() { HighTierContext htc = getDefaultHighTierContext(); - ImprovementSavingCanonicalizer c1 = new ImprovementSavingCanonicalizer(htc.getNodeCostProvider()); + ImprovementSavingCanonicalizer c1 = new ImprovementSavingCanonicalizer(); StructuredGraph g1 = parseForCompile(getResolvedJavaMethod("test1Snippet")); new CanonicalizerPhase(c1).apply(g1, htc); - ImprovementSavingCanonicalizer c2 = new ImprovementSavingCanonicalizer(htc.getNodeCostProvider()); + ImprovementSavingCanonicalizer c2 = new ImprovementSavingCanonicalizer(); StructuredGraph g2 = parseForCompile(getResolvedJavaMethod("test2Snippet")); new CanonicalizerPhase(c2).apply(g2, htc); Assert.assertTrue(c1.savedCycles > c2.savedCycles); @@ -270,7 +267,7 @@ new CanonicalizerPhase().apply(g1, htc); GraphCostPhase gc1 = new GraphCostPhase(); gc1.apply(g1, htc); - Assert.assertEquals(35, gc1.finalCycles, 25); + Assert.assertEquals(15, gc1.finalCycles, 25); } @Test @@ -280,7 +277,7 @@ new CanonicalizerPhase().apply(g1, htc); GraphCostPhase gc1 = new GraphCostPhase(); gc1.apply(g1, htc); - Assert.assertEquals(50, gc1.finalCycles, 25); + Assert.assertEquals(15, gc1.finalCycles, 25); } @Test @@ -290,7 +287,7 @@ new CanonicalizerPhase().apply(g1, htc); GraphCostPhase gc1 = new GraphCostPhase(); gc1.apply(g1, htc); - Assert.assertEquals(30, gc1.finalCycles, 25); + Assert.assertEquals(15, gc1.finalCycles, 25); } @Test @@ -300,16 +297,11 @@ new CanonicalizerPhase().apply(g1, htc); GraphCostPhase gc1 = new GraphCostPhase(); gc1.apply(g1, htc); - Assert.assertEquals(40, gc1.finalCycles, 25); + Assert.assertEquals(15, gc1.finalCycles, 25); } static class ImprovementSavingCanonicalizer extends CustomCanonicalizer { private int savedCycles; - private final NodeCostProvider nodeCostProvider; - - ImprovementSavingCanonicalizer(NodeCostProvider nodeCostProvider) { - this.nodeCostProvider = nodeCostProvider; - } @Override public void simplify(Node node, SimplifierTool tool) { @@ -318,7 +310,7 @@ Canonicalizable.Binary bc = (Canonicalizable.Binary) node; Node canonicalized = bc.canonical(tool, bc.getX(), bc.getY()); if (canonicalized != node) { - savedCycles += nodeCostProvider.getEstimatedCPUCycles(node) - nodeCostProvider.getEstimatedCPUCycles(canonicalized); + savedCycles += node.estimatedNodeCycles().value - canonicalized.estimatedNodeCycles().value; } } } @@ -330,8 +322,8 @@ @Override protected void run(StructuredGraph graph, PhaseContext context) { - finalCycles = NodeCostUtil.computeGraphCycles(graph, context.getNodeCostProvider(), true); - finalSize = NodeCostUtil.computeGraphSize(graph, context.getNodeCostProvider()); + finalCycles = NodeCostUtil.computeGraphCycles(graph, true); + finalSize = NodeCostUtil.computeGraphSize(graph); } } diff -r d5572756efd6 -r ab5b504181d8 hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/ReflectionOptionDescriptors.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/ReflectionOptionDescriptors.java Wed Apr 19 04:10:56 2017 +0000 @@ -0,0 +1,127 @@ +/* + * Copyright (c) 2013, 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.test; + +import java.lang.annotation.RetentionPolicy; +import java.lang.reflect.Field; +import java.lang.reflect.Modifier; +import java.lang.reflect.ParameterizedType; +import java.lang.reflect.Type; +import java.util.Iterator; +import java.util.Map; +import java.util.Properties; + +import org.graalvm.compiler.options.Option; +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.util.EconomicMap; +import org.graalvm.util.MapCursor; + +/** + * An implementation of {@link OptionDescriptor} that uses reflection to create descriptors from a + * list of field name and help text pairs. We cannot use the {@link Option} annotation as it has a + * {@link RetentionPolicy#SOURCE} retention policy. + * + * This class is useful for working with {@link OptionKey} and {@link OptionValues} but without + * having to rely on {@link Option} and its associated annotation processor. + */ +public class ReflectionOptionDescriptors implements OptionDescriptors { + + /** + * Extracts name/value entries from a set of properties based on a given name prefix. + * + * @param properties the properties set to extract from + * @param prefix entries whose names start with this prefix are extracted + * @param stripPrefix specifies whether to remove the prefix from the names in the returned map + */ + public static EconomicMap extractEntries(Properties properties, String prefix, boolean stripPrefix) { + EconomicMap matches = EconomicMap.create(); + for (Map.Entry e : properties.entrySet()) { + String name = (String) e.getKey(); + if (name.startsWith(prefix)) { + String value = (String) e.getValue(); + if (stripPrefix) { + name = name.substring(prefix.length()); + } + matches.put(name, value); + } + } + return matches; + } + + private final EconomicMap descriptors = EconomicMap.create(); + + public ReflectionOptionDescriptors(Class declaringClass, String... fieldsAndHelp) { + assert fieldsAndHelp.length % 2 == 0; + for (int i = 0; i < fieldsAndHelp.length; i += 2) { + String fieldName = fieldsAndHelp[i]; + String help = fieldsAndHelp[i + 1]; + addOption(declaringClass, fieldName, help); + } + } + + public ReflectionOptionDescriptors(Class declaringClass, EconomicMap fieldsAndHelp) { + MapCursor cursor = fieldsAndHelp.getEntries(); + while (cursor.advance()) { + String fieldName = cursor.getKey(); + String help = cursor.getValue(); + addOption(declaringClass, fieldName, help); + } + } + + private void addOption(Class declaringClass, String fieldName, String help) { + try { + Field f = declaringClass.getDeclaredField(fieldName); + if (!OptionKey.class.isAssignableFrom(f.getType())) { + throw new IllegalArgumentException(String.format("Option field must be of type %s: %s", OptionKey.class.getName(), f)); + } + if (!Modifier.isStatic(f.getModifiers())) { + throw new IllegalArgumentException(String.format("Option field must be static: %s", f)); + } + f.setAccessible(true); + Type declaredType = f.getAnnotatedType().getType(); + if (!(declaredType instanceof ParameterizedType)) { + throw new IllegalArgumentException(String.format("Option field must have a parameterized type: %s", f)); + } + ParameterizedType pt = (ParameterizedType) declaredType; + Type[] actualTypeArguments = pt.getActualTypeArguments(); + assert actualTypeArguments.length == 1; + Class optionType = (Class) actualTypeArguments[0]; + descriptors.put(fieldName, OptionDescriptor.create(fieldName, optionType, help, declaringClass, fieldName, (OptionKey) f.get(null))); + } catch (IllegalAccessException | NoSuchFieldException e) { + throw new IllegalArgumentException(e); + } + } + + @Override + public Iterator iterator() { + return descriptors.getValues().iterator(); + } + + @Override + public OptionDescriptor get(String value) { + return descriptors.get(value); + } +} diff -r d5572756efd6 -r ab5b504181d8 hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/VerifyDebugUsageTest.java --- a/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/VerifyDebugUsageTest.java Tue Apr 18 20:10:55 2017 -0700 +++ b/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/VerifyDebugUsageTest.java Wed Apr 19 04:10:56 2017 +0000 @@ -205,7 +205,7 @@ private static class InvalidGraalErrorGuaranteePhase extends Phase { @Override protected void run(StructuredGraph graph) { - GraalError.guarantee(graph.getNodes().count() > 0, "Graph must contain nodes %s %s %s", graph, graph, graph, graph.toString()); + GraalError.guarantee(graph.getNodes().count() > 0, "Graph must contain nodes %s %s %s", graph, graph, graph.toString()); } } diff -r d5572756efd6 -r ab5b504181d8 hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core/src/org/graalvm/compiler/core/GraalCompiler.java --- a/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core/src/org/graalvm/compiler/core/GraalCompiler.java Tue Apr 18 20:10:55 2017 -0700 +++ b/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core/src/org/graalvm/compiler/core/GraalCompiler.java Wed Apr 19 04:10:56 2017 +0000 @@ -298,18 +298,10 @@ assert startBlock != null; assert startBlock.getPredecessorCount() == 0; - LIR lir = null; - AbstractBlockBase[] codeEmittingOrder = null; - AbstractBlockBase[] linearScanOrder = null; - try (Scope s = Debug.scope("ComputeLinearScanOrder", lir)) { - codeEmittingOrder = ComputeBlockOrder.computeCodeEmittingOrder(blocks.length, startBlock); - linearScanOrder = ComputeBlockOrder.computeLinearScanOrder(blocks.length, startBlock); + AbstractBlockBase[] codeEmittingOrder = ComputeBlockOrder.computeCodeEmittingOrder(blocks.length, startBlock); + AbstractBlockBase[] linearScanOrder = ComputeBlockOrder.computeLinearScanOrder(blocks.length, startBlock); + LIR lir = new LIR(schedule.getCFG(), linearScanOrder, codeEmittingOrder, graph.getOptions()); - lir = new LIR(schedule.getCFG(), linearScanOrder, codeEmittingOrder, graph.getOptions()); - Debug.dump(Debug.INFO_LEVEL, lir, "After linear scan order"); - } catch (Throwable e) { - throw Debug.handle(e); - } FrameMapBuilder frameMapBuilder = backend.newFrameMapBuilder(registerConfig); LIRGenerationResult lirGenRes = backend.newLIRGenerationResult(graph.compilationId(), lir, frameMapBuilder, graph, stub); LIRGeneratorTool lirGen = backend.newLIRGenerator(lirGenRes); @@ -320,9 +312,9 @@ new LIRGenerationPhase().apply(backend.getTarget(), lirGenRes, context); try (Scope s = Debug.scope("LIRStages", nodeLirGen, lir)) { - Debug.dump(Debug.BASIC_LEVEL, lir, "After LIR generation"); + // 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)); - Debug.dump(Debug.BASIC_LEVEL, lir, "Before code generation"); return result; } catch (Throwable e) { throw Debug.handle(e); @@ -349,12 +341,15 @@ RegisterAllocationConfig registerAllocationConfig) { PreAllocationOptimizationContext preAllocOptContext = new PreAllocationOptimizationContext(lirGen); lirSuites.getPreAllocationOptimizationStage().apply(target, lirGenRes, preAllocOptContext); + Debug.dump(Debug.BASIC_LEVEL, lirGenRes.getLIR(), "After PreAllocationOptimizationStage"); AllocationContext allocContext = new AllocationContext(lirGen.getSpillMoveFactory(), registerAllocationConfig); lirSuites.getAllocationStage().apply(target, lirGenRes, allocContext); + Debug.dump(Debug.BASIC_LEVEL, lirGenRes.getLIR(), "After AllocationStage"); PostAllocationOptimizationContext postAllocOptContext = new PostAllocationOptimizationContext(lirGen); lirSuites.getPostAllocationOptimizationStage().apply(target, lirGenRes, postAllocOptContext); + Debug.dump(Debug.BASIC_LEVEL, lirGenRes.getLIR(), "After PostAllocationOptimizationStage"); return lirGenRes; } diff -r d5572756efd6 -r ab5b504181d8 hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.debug/src/org/graalvm/compiler/debug/Debug.java --- a/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.debug/src/org/graalvm/compiler/debug/Debug.java Tue Apr 18 20:10:55 2017 -0700 +++ b/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.debug/src/org/graalvm/compiler/debug/Debug.java Wed Apr 19 04:10:56 2017 +0000 @@ -127,6 +127,9 @@ * * For HIR dumping, only ~5 graphs per method: after parsing, after inlining, after high tier, * after mid tier, after low tier. + * + * LIR dumping: After LIR generation, after each pre-allocation, allocation and post allocation + * stage, and after code installation. */ public static final int BASIC_LEVEL = 1; @@ -134,6 +137,8 @@ * Informational debug level. * * HIR dumping: One graph after each applied top-level phase. + * + * LIR dumping: After each applied phase. */ public static final int INFO_LEVEL = 2; @@ -141,6 +146,8 @@ * Verbose debug level. * * HIR dumping: One graph after each phase (including sub phases). + * + * LIR dumping: After each phase including sub phases. */ public static final int VERBOSE_LEVEL = 3; @@ -148,6 +155,8 @@ * Detailed debug level. * * HIR dumping: Graphs within phases where interesting for a phase, max ~5 per phase. + * + * LIR dumping: Dump CFG within phases where interesting. */ public static final int DETAILED_LEVEL = 4; @@ -155,6 +164,8 @@ * Very detailed debug level. * * HIR dumping: Graphs per node granularity graph change (before/after change). + * + * LIR dumping: Intermediate CFGs of phases where interesting. */ public static final int VERY_DETAILED_LEVEL = 5; diff -r d5572756efd6 -r ab5b504181d8 hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.debug/src/org/graalvm/compiler/debug/GraalDebugConfig.java --- a/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.debug/src/org/graalvm/compiler/debug/GraalDebugConfig.java Tue Apr 18 20:10:55 2017 -0700 +++ b/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.debug/src/org/graalvm/compiler/debug/GraalDebugConfig.java Wed Apr 19 04:10:56 2017 +0000 @@ -117,6 +117,7 @@ public static final OptionKey PrintBinaryGraphPort = new OptionKey<>(4445); @Option(help = "Schedule graphs as they are dumped.", type = OptionType.Debug) public static final OptionKey PrintGraphWithSchedule = new OptionKey<>(false); + @Option(help = "Enable dumping Truffle ASTs to the IdealGraphVisualizer.", type = OptionType.Debug) public static final OptionKey PrintTruffleTrees = new OptionKey<>(true); diff -r d5572756efd6 -r ab5b504181d8 hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.debug/src/org/graalvm/compiler/debug/GraalError.java --- a/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.debug/src/org/graalvm/compiler/debug/GraalError.java Tue Apr 18 20:10:55 2017 -0700 +++ b/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.debug/src/org/graalvm/compiler/debug/GraalError.java Wed Apr 19 04:10:56 2017 +0000 @@ -60,10 +60,75 @@ * if possible. * * @param condition the condition to check + * @param msg the message that will be associated with the error + */ + public static void guarantee(boolean condition, String msg) { + if (!condition) { + throw new GraalError("failed guarantee: " + msg); + } + } + + /** + * Checks a given condition and throws a {@link GraalError} if it is false. Guarantees are + * stronger than assertions in that they are always checked. Error messages for guarantee + * violations should clearly indicate the nature of the problem as well as a suggested solution + * if possible. + * + * @param condition the condition to check + * @param msg the message that will be associated with the error, in + * {@link String#format(String, Object...)} syntax + * @param arg argument to the format string in {@code msg} + */ + public static void guarantee(boolean condition, String msg, Object arg) { + if (!condition) { + throw new GraalError("failed guarantee: " + msg, arg); + } + } + + /** + * Checks a given condition and throws a {@link GraalError} if it is false. Guarantees are + * stronger than assertions in that they are always checked. Error messages for guarantee + * violations should clearly indicate the nature of the problem as well as a suggested solution + * if possible. + * + * @param condition the condition to check * @param msg the message that will be associated with the error, in * {@link String#format(String, Object...)} syntax - * @param args arguments to the format string + * @param arg1 argument to the format string in {@code msg} + * @param arg2 argument to the format string in {@code msg} */ + public static void guarantee(boolean condition, String msg, Object arg1, Object arg2) { + if (!condition) { + throw new GraalError("failed guarantee: " + msg, arg1, arg2); + } + } + + /** + * Checks a given condition and throws a {@link GraalError} if it is false. Guarantees are + * stronger than assertions in that they are always checked. Error messages for guarantee + * violations should clearly indicate the nature of the problem as well as a suggested solution + * if possible. + * + * @param condition the condition to check + * @param msg the message that will be associated with the error, in + * {@link String#format(String, Object...)} syntax + * @param arg1 argument to the format string in {@code msg} + * @param arg2 argument to the format string in {@code msg} + * @param arg3 argument to the format string in {@code msg} + */ + public static void guarantee(boolean condition, String msg, Object arg1, Object arg2, Object arg3) { + if (!condition) { + throw new GraalError("failed guarantee: " + msg, arg1, arg2, arg3); + } + } + + /** + * This override exists to catch cases when {@link #guarantee(boolean, String, Object)} is + * called with one argument bound to a varargs method parameter. It will bind to this method + * instead of the single arg variant and produce a deprecation warning instead of silently + * wrapping the Object[] inside of another Object[]. + */ + @Deprecated public static void guarantee(boolean condition, String msg, Object... args) { if (!condition) { throw new GraalError("failed guarantee: " + msg, args); diff -r d5572756efd6 -r ab5b504181d8 hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.graph/src/org/graalvm/compiler/graph/Graph.java --- a/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.graph/src/org/graalvm/compiler/graph/Graph.java Tue Apr 18 20:10:55 2017 -0700 +++ b/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.graph/src/org/graalvm/compiler/graph/Graph.java Wed Apr 19 04:10:56 2017 +0000 @@ -22,6 +22,9 @@ */ package org.graalvm.compiler.graph; +import static org.graalvm.compiler.nodeinfo.NodeCycles.CYCLES_IGNORED; +import static org.graalvm.compiler.nodeinfo.NodeSize.SIZE_IGNORED; + import java.util.ArrayList; import java.util.Arrays; import java.util.Iterator; @@ -793,7 +796,7 @@ } // Fully qualified annotation name is required to satisfy javac - @org.graalvm.compiler.nodeinfo.NodeInfo + @org.graalvm.compiler.nodeinfo.NodeInfo(cycles = CYCLES_IGNORED, size = SIZE_IGNORED) static final class PlaceHolderNode extends Node { public static final NodeClass TYPE = NodeClass.create(PlaceHolderNode.class); diff -r d5572756efd6 -r ab5b504181d8 hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.graph/src/org/graalvm/compiler/graph/Node.java --- a/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.graph/src/org/graalvm/compiler/graph/Node.java Tue Apr 18 20:10:55 2017 -0700 +++ b/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.graph/src/org/graalvm/compiler/graph/Node.java Wed Apr 19 04:10:56 2017 +0000 @@ -52,7 +52,9 @@ import org.graalvm.compiler.graph.spi.Simplifiable; import org.graalvm.compiler.graph.spi.SimplifierTool; import org.graalvm.compiler.nodeinfo.InputType; +import org.graalvm.compiler.nodeinfo.NodeCycles; import org.graalvm.compiler.nodeinfo.NodeInfo; +import org.graalvm.compiler.nodeinfo.NodeSize; import org.graalvm.compiler.nodeinfo.Verbosity; import org.graalvm.compiler.options.OptionValues; @@ -606,10 +608,18 @@ } private boolean checkReplaceWith(Node other) { - assert assertTrue(graph == null || !graph.isFrozen(), "cannot modify frozen graph"); - assert assertFalse(other == this, "cannot replace a node with itself"); - assert assertFalse(isDeleted(), "cannot replace deleted node"); - assert assertTrue(other == null || !other.isDeleted(), "cannot replace with deleted node %s", other); + if (graph != null && graph.isFrozen()) { + fail("cannot modify frozen graph"); + } + if (other == this) { + fail("cannot replace a node with itself"); + } + if (isDeleted()) { + fail("cannot replace deleted node"); + } + if (other != null && other.isDeleted()) { + fail("cannot replace with deleted node %s", other); + } return true; } @@ -640,7 +650,7 @@ } protected void replaceAtAllUsages(Node other, Node toBeDeleted) { - assert checkReplaceWith(other); + checkReplaceWith(other); if (usage0 == null) { return; } @@ -679,12 +689,14 @@ } private void replaceAtMatchingUsages(Node other, Predicate filter, Node toBeDeleted) { - assert filter != null; - assert checkReplaceWith(other); + if (filter == null) { + fail("filter cannot be null"); + } + checkReplaceWith(other); int i = 0; while (i < this.getUsageCount()) { Node usage = this.getUsageAt(i); - if (filter == null || filter.test(usage)) { + if (filter.test(usage)) { replaceAtUsage(other, toBeDeleted, usage); this.movUsageFromEndTo(i); } else { @@ -704,12 +716,12 @@ } public void replaceAtMatchingUsages(Node other, NodePredicate usagePredicate) { - assert checkReplaceWith(other); + checkReplaceWith(other); replaceAtMatchingUsages(other, usagePredicate, null); } public void replaceAtUsages(InputType type, Node other) { - assert checkReplaceWith(other); + checkReplaceWith(other); for (Node usage : usages().snapshot()) { for (Position pos : usage.inputPositions()) { if (pos.getInputType() == type && pos.get(usage) == this) { @@ -746,17 +758,20 @@ } public void replaceAtPredecessor(Node other) { - assert checkReplaceWith(other); + checkReplaceWith(other); if (predecessor != null) { - boolean result = predecessor.getNodeClass().replaceFirstSuccessor(predecessor, this, other); - assert assertTrue(result, "not found in successors, predecessor: %s", predecessor); + if (!predecessor.getNodeClass().replaceFirstSuccessor(predecessor, this, other)) { + fail("not found in successors, predecessor: %s", predecessor); + } predecessor.updatePredecessor(this, other); } } public void replaceAndDelete(Node other) { - assert checkReplaceWith(other); - assert other != null; + checkReplaceWith(other); + if (other == null) { + fail("cannot replace with null"); + } if (this.hasUsages()) { replaceAtUsages(other); } @@ -1173,4 +1188,13 @@ public final void pushInputs(NodeStack stack) { getNodeClass().pushInputs(this, stack); } + + public NodeSize estimatedNodeSize() { + return nodeClass.size(); + } + + public NodeCycles estimatedNodeCycles() { + return nodeClass.cycles(); + } + } diff -r d5572756efd6 -r ab5b504181d8 hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.graph/src/org/graalvm/compiler/graph/NodeClass.java --- a/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.graph/src/org/graalvm/compiler/graph/NodeClass.java Tue Apr 18 20:10:55 2017 -0700 +++ b/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.graph/src/org/graalvm/compiler/graph/NodeClass.java Wed Apr 19 04:10:56 2017 +0000 @@ -941,6 +941,10 @@ return this.leafId; } + public NodeClass getSuperNodeClass() { + return superNodeClass; + } + public long inputsIteration() { return inputsIteration; } diff -r d5572756efd6 -r ab5b504181d8 hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.graph/src/org/graalvm/compiler/graph/spi/CanonicalizerTool.java --- a/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.graph/src/org/graalvm/compiler/graph/spi/CanonicalizerTool.java Tue Apr 18 20:10:55 2017 -0700 +++ b/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.graph/src/org/graalvm/compiler/graph/spi/CanonicalizerTool.java Wed Apr 19 04:10:56 2017 +0000 @@ -50,10 +50,10 @@ boolean allUsagesAvailable(); /** - * Indicates whether the target platform supports comparison of integers of a particular bit - * width. This check is used by canonicalizations that might introduce subword compares. + * Indicates the smallest width for comparing an integer value on the target platform. If this + * method returns null, then there is no known smallest compare width. */ - boolean supportSubwordCompare(int bits); + Integer smallestCompareWidth(); OptionValues getOptions(); } diff -r d5572756efd6 -r ab5b504181d8 hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.aarch64/src/org/graalvm/compiler/hotspot/aarch64/AArch64HotSpotBackendFactory.java --- a/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.aarch64/src/org/graalvm/compiler/hotspot/aarch64/AArch64HotSpotBackendFactory.java Tue Apr 18 20:10:55 2017 -0700 +++ b/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.aarch64/src/org/graalvm/compiler/hotspot/aarch64/AArch64HotSpotBackendFactory.java Wed Apr 19 04:10:56 2017 +0000 @@ -46,10 +46,8 @@ import org.graalvm.compiler.hotspot.meta.HotSpotSnippetReflectionProvider; import org.graalvm.compiler.hotspot.meta.HotSpotStampProvider; import org.graalvm.compiler.hotspot.meta.HotSpotSuitesProvider; -import org.graalvm.compiler.hotspot.nodes.HotSpotNodeCostProvider; import org.graalvm.compiler.hotspot.word.HotSpotWordTypes; import org.graalvm.compiler.nodes.graphbuilderconf.GraphBuilderConfiguration.Plugins; -import org.graalvm.compiler.nodes.spi.NodeCostProvider; import org.graalvm.compiler.options.OptionValues; import org.graalvm.compiler.phases.tiers.CompilerConfiguration; import org.graalvm.compiler.phases.util.Providers; @@ -107,7 +105,6 @@ HotSpotSuitesProvider suites; HotSpotWordTypes wordTypes; Plugins plugins; - NodeCostProvider nodeCostProvider; BytecodeProvider bytecodeProvider; try (InitTimer t = timer("create providers")) { try (InitTimer rt = timer("create HotSpotRegisters provider")) { @@ -125,11 +122,8 @@ try (InitTimer rt = timer("create Lowerer provider")) { lowerer = createLowerer(graalRuntime, metaAccess, foreignCalls, registers, constantReflection, target); } - try (InitTimer rt = timer("create NodeCost provider")) { - nodeCostProvider = createNodeCostProvider(); - } HotSpotStampProvider stampProvider = new HotSpotStampProvider(); - Providers p = new Providers(metaAccess, codeCache, constantReflection, constantFieldProvider, foreignCalls, lowerer, null, stampProvider, nodeCostProvider); + Providers p = new Providers(metaAccess, codeCache, constantReflection, constantFieldProvider, foreignCalls, lowerer, null, stampProvider); try (InitTimer rt = timer("create SnippetReflection provider")) { snippetReflection = createSnippetReflection(graalRuntime, constantReflection, wordTypes); @@ -147,7 +141,7 @@ try (InitTimer rt = timer("create Suites provider")) { suites = createSuites(config, graalRuntime, compilerConfiguration, plugins); } - providers = new HotSpotProviders(metaAccess, codeCache, constantReflection, constantFieldProvider, foreignCalls, lowerer, replacements, nodeCostProvider, suites, registers, + providers = new HotSpotProviders(metaAccess, codeCache, constantReflection, constantFieldProvider, foreignCalls, lowerer, replacements, suites, registers, snippetReflection, wordTypes, plugins); } @@ -194,10 +188,6 @@ return new AArch64HotSpotLoweringProvider(runtime, metaAccess, foreignCalls, registers, constantReflection, target); } - protected HotSpotNodeCostProvider createNodeCostProvider() { - return new AArchHotSpotNodeCostProvider(); - } - protected static Value[] createNativeABICallerSaveRegisters(@SuppressWarnings("unused") GraalHotSpotVMConfig config, RegisterConfig regConfig) { AArch64HotSpotRegisterConfig conf = (AArch64HotSpotRegisterConfig) regConfig; RegisterArray callerSavedRegisters = conf.getCallerSaveRegisters(); diff -r d5572756efd6 -r ab5b504181d8 hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.aarch64/src/org/graalvm/compiler/hotspot/aarch64/AArch64HotSpotMove.java --- a/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.aarch64/src/org/graalvm/compiler/hotspot/aarch64/AArch64HotSpotMove.java Tue Apr 18 20:10:55 2017 -0700 +++ b/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.aarch64/src/org/graalvm/compiler/hotspot/aarch64/AArch64HotSpotMove.java Wed Apr 19 04:10:56 2017 +0000 @@ -24,6 +24,7 @@ import static jdk.vm.ci.aarch64.AArch64.zr; import static jdk.vm.ci.code.ValueUtil.asRegister; +import static jdk.vm.ci.code.ValueUtil.isRegister; import static org.graalvm.compiler.lir.LIRInstruction.OperandFlag.HINT; import static org.graalvm.compiler.lir.LIRInstruction.OperandFlag.ILLEGAL; import static org.graalvm.compiler.lir.LIRInstruction.OperandFlag.REG; @@ -105,7 +106,7 @@ public void emitCode(CompilationResultBuilder crb, AArch64MacroAssembler masm) { Register resultRegister = asRegister(result); Register ptr = asRegister(input); - Register base = asRegister(baseRegister); + Register base = (isRegister(baseRegister) ? asRegister(baseRegister) : zr); // result = (ptr - base) >> shift if (!encoding.hasBase()) { if (encoding.hasShift()) { @@ -156,7 +157,7 @@ public void emitCode(CompilationResultBuilder crb, AArch64MacroAssembler masm) { Register ptr = asRegister(input); Register resultRegister = asRegister(result); - Register base = asRegister(baseRegister); + Register base = (isRegister(baseRegister) ? asRegister(baseRegister) : zr); // result = base + (ptr << shift) if (nonNull) { masm.add(64, resultRegister, base, ptr, AArch64Assembler.ShiftType.LSL, encoding.getShift()); diff -r d5572756efd6 -r ab5b504181d8 hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.aarch64/src/org/graalvm/compiler/hotspot/aarch64/AArch64RawNativeCallNode.java --- a/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.aarch64/src/org/graalvm/compiler/hotspot/aarch64/AArch64RawNativeCallNode.java Tue Apr 18 20:10:55 2017 -0700 +++ b/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.aarch64/src/org/graalvm/compiler/hotspot/aarch64/AArch64RawNativeCallNode.java Wed Apr 19 04:10:56 2017 +0000 @@ -23,7 +23,7 @@ package org.graalvm.compiler.hotspot.aarch64; import static org.graalvm.compiler.nodeinfo.NodeCycles.CYCLES_UNKNOWN; -import static org.graalvm.compiler.nodeinfo.NodeSize.SIZE_20; +import static org.graalvm.compiler.nodeinfo.NodeSize.SIZE_UNKNOWN; import org.graalvm.compiler.core.aarch64.AArch64NodeLIRBuilder; import org.graalvm.compiler.core.common.type.RawPointerStamp; @@ -46,7 +46,7 @@ import jdk.vm.ci.meta.ResolvedJavaType; import jdk.vm.ci.meta.Value; -@NodeInfo(cycles = CYCLES_UNKNOWN, cyclesRationale = "Native call is a block hole", size = SIZE_20) +@NodeInfo(cycles = CYCLES_UNKNOWN, cyclesRationale = "Native call is a block hole", size = SIZE_UNKNOWN) public final class AArch64RawNativeCallNode extends FixedWithNextNode implements LIRLowerable { public static final NodeClass TYPE = NodeClass.create(AArch64RawNativeCallNode.class); diff -r d5572756efd6 -r ab5b504181d8 hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.aarch64/src/org/graalvm/compiler/hotspot/aarch64/AArchHotSpotNodeCostProvider.java --- a/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.aarch64/src/org/graalvm/compiler/hotspot/aarch64/AArchHotSpotNodeCostProvider.java Tue Apr 18 20:10:55 2017 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,41 +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.aarch64; - -import org.graalvm.compiler.graph.Node; -import org.graalvm.compiler.hotspot.nodes.HotSpotNodeCostProvider; -import org.graalvm.compiler.nodeinfo.NodeCycles; -import org.graalvm.compiler.nodeinfo.NodeSize; - -public class AArchHotSpotNodeCostProvider extends HotSpotNodeCostProvider { - - @Override - public NodeCycles cycles(Node n) { - return super.cycles(n); - } - - @Override - public NodeSize size(Node n) { - return super.size(n); - } -} diff -r d5572756efd6 -r ab5b504181d8 hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.amd64/src/org/graalvm/compiler/hotspot/amd64/AMD64HotSpotBackendFactory.java --- a/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.amd64/src/org/graalvm/compiler/hotspot/amd64/AMD64HotSpotBackendFactory.java Tue Apr 18 20:10:55 2017 -0700 +++ b/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.amd64/src/org/graalvm/compiler/hotspot/amd64/AMD64HotSpotBackendFactory.java Wed Apr 19 04:10:56 2017 +0000 @@ -46,10 +46,8 @@ import org.graalvm.compiler.hotspot.meta.HotSpotSnippetReflectionProvider; import org.graalvm.compiler.hotspot.meta.HotSpotStampProvider; import org.graalvm.compiler.hotspot.meta.HotSpotSuitesProvider; -import org.graalvm.compiler.hotspot.nodes.HotSpotNodeCostProvider; import org.graalvm.compiler.hotspot.word.HotSpotWordTypes; import org.graalvm.compiler.nodes.graphbuilderconf.GraphBuilderConfiguration.Plugins; -import org.graalvm.compiler.nodes.spi.NodeCostProvider; import org.graalvm.compiler.nodes.spi.Replacements; import org.graalvm.compiler.options.OptionValues; import org.graalvm.compiler.phases.tiers.CompilerConfiguration; @@ -108,7 +106,6 @@ HotSpotSuitesProvider suites; HotSpotWordTypes wordTypes; Plugins plugins; - NodeCostProvider nodeCostProvider; BytecodeProvider bytecodeProvider; try (InitTimer t = timer("create providers")) { try (InitTimer rt = timer("create HotSpotRegisters provider")) { @@ -126,11 +123,8 @@ try (InitTimer rt = timer("create Lowerer provider")) { lowerer = createLowerer(graalRuntime, metaAccess, foreignCalls, registers, constantReflection, target); } - try (InitTimer rt = timer("create NodeCost provider")) { - nodeCostProvider = createNodeCostProvider(target); - } HotSpotStampProvider stampProvider = new HotSpotStampProvider(); - Providers p = new Providers(metaAccess, codeCache, constantReflection, constantFieldProvider, foreignCalls, lowerer, null, stampProvider, nodeCostProvider); + Providers p = new Providers(metaAccess, codeCache, constantReflection, constantFieldProvider, foreignCalls, lowerer, null, stampProvider); try (InitTimer rt = timer("create SnippetReflection provider")) { snippetReflection = createSnippetReflection(graalRuntime, constantReflection, wordTypes); @@ -148,7 +142,7 @@ try (InitTimer rt = timer("create Suites provider")) { suites = createSuites(config, graalRuntime, compilerConfiguration, plugins, registers, replacements, options); } - providers = new HotSpotProviders(metaAccess, codeCache, constantReflection, constantFieldProvider, foreignCalls, lowerer, replacements, nodeCostProvider, suites, registers, + providers = new HotSpotProviders(metaAccess, codeCache, constantReflection, constantFieldProvider, foreignCalls, lowerer, replacements, suites, registers, snippetReflection, wordTypes, plugins); } @@ -201,10 +195,6 @@ return new AMD64HotSpotLoweringProvider(runtime, metaAccess, foreignCalls, registers, constantReflection, target); } - protected HotSpotNodeCostProvider createNodeCostProvider(TargetDescription target) { - return new AMD64HotSpotNodeCostProvider(target); - } - protected Value[] createNativeABICallerSaveRegisters(GraalHotSpotVMConfig config, RegisterConfig regConfig) { List callerSave = new ArrayList<>(regConfig.getAllocatableRegisters().asList()); if (config.windowsOs) { diff -r d5572756efd6 -r ab5b504181d8 hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.amd64/src/org/graalvm/compiler/hotspot/amd64/AMD64HotSpotLoweringProvider.java --- a/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.amd64/src/org/graalvm/compiler/hotspot/amd64/AMD64HotSpotLoweringProvider.java Tue Apr 18 20:10:55 2017 -0700 +++ b/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.amd64/src/org/graalvm/compiler/hotspot/amd64/AMD64HotSpotLoweringProvider.java Wed Apr 19 04:10:56 2017 +0000 @@ -120,7 +120,7 @@ } @Override - public boolean supportSubwordCompare(int bits) { - return true; + public Integer smallestCompareWidth() { + return 8; } } diff -r d5572756efd6 -r ab5b504181d8 hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.amd64/src/org/graalvm/compiler/hotspot/amd64/AMD64HotSpotNodeCostProvider.java --- a/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.amd64/src/org/graalvm/compiler/hotspot/amd64/AMD64HotSpotNodeCostProvider.java Tue Apr 18 20:10:55 2017 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,93 +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 static org.graalvm.compiler.nodeinfo.NodeCycles.CYCLES_15; -import static org.graalvm.compiler.nodeinfo.NodeCycles.CYCLES_50; -import static org.graalvm.compiler.nodeinfo.NodeCycles.CYCLES_6; -import static org.graalvm.compiler.nodeinfo.NodeCycles.CYCLES_80; -import static org.graalvm.compiler.nodeinfo.NodeSize.SIZE_30; -import static org.graalvm.compiler.nodeinfo.NodeSize.SIZE_4; - -import org.graalvm.compiler.graph.Node; -import org.graalvm.compiler.hotspot.nodes.HotSpotNodeCostProvider; -import org.graalvm.compiler.nodeinfo.NodeCycles; -import org.graalvm.compiler.nodeinfo.NodeSize; -import org.graalvm.compiler.nodes.ReturnNode; -import org.graalvm.compiler.replacements.nodes.ArrayEqualsNode; -import org.graalvm.compiler.replacements.nodes.UnaryMathIntrinsicNode; - -import jdk.vm.ci.amd64.AMD64; -import jdk.vm.ci.amd64.AMD64.CPUFeature; -import jdk.vm.ci.code.TargetDescription; - -public class AMD64HotSpotNodeCostProvider extends HotSpotNodeCostProvider { - private final boolean avx2; - private final boolean sse41; - - public AMD64HotSpotNodeCostProvider(TargetDescription target) { - this.avx2 = ((AMD64) target.arch).getFeatures().contains(CPUFeature.AVX2); - this.sse41 = ((AMD64) target.arch).getFeatures().contains(CPUFeature.SSE4_1); - } - - @Override - public NodeCycles cycles(Node n) { - if (n instanceof UnaryMathIntrinsicNode) { - UnaryMathIntrinsicNode u = (UnaryMathIntrinsicNode) n; - switch (u.getOperation()) { - case LOG: - case LOG10: - return CYCLES_15; - default: - break; - } - } else if (n instanceof ReturnNode) { - return CYCLES_6; - } else if (n instanceof ArrayEqualsNode) { - if (avx2) { - return CYCLES_50; - } else if (sse41) { - return CYCLES_80; - } - } - return super.cycles(n); - } - - @Override - public NodeSize size(Node n) { - if (n instanceof UnaryMathIntrinsicNode) { - UnaryMathIntrinsicNode u = (UnaryMathIntrinsicNode) n; - switch (u.getOperation()) { - case LOG: - case LOG10: - return SIZE_30; - default: - break; - } - } else if (n instanceof ReturnNode) { - return SIZE_4; - } - return super.size(n); - } - -} diff -r d5572756efd6 -r ab5b504181d8 hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.amd64/src/org/graalvm/compiler/hotspot/amd64/AMD64RawNativeCallNode.java --- a/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.amd64/src/org/graalvm/compiler/hotspot/amd64/AMD64RawNativeCallNode.java Tue Apr 18 20:10:55 2017 -0700 +++ b/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.amd64/src/org/graalvm/compiler/hotspot/amd64/AMD64RawNativeCallNode.java Wed Apr 19 04:10:56 2017 +0000 @@ -23,7 +23,6 @@ package org.graalvm.compiler.hotspot.amd64; import static org.graalvm.compiler.nodeinfo.NodeCycles.CYCLES_UNKNOWN; -import static org.graalvm.compiler.nodeinfo.NodeSize.SIZE_20; import org.graalvm.compiler.core.amd64.AMD64NodeLIRBuilder; import org.graalvm.compiler.core.common.type.RawPointerStamp; @@ -32,6 +31,7 @@ import org.graalvm.compiler.graph.NodeClass; import org.graalvm.compiler.graph.NodeInputList; import org.graalvm.compiler.nodeinfo.NodeInfo; +import org.graalvm.compiler.nodeinfo.NodeSize; import org.graalvm.compiler.nodes.FixedWithNextNode; import org.graalvm.compiler.nodes.ValueNode; import org.graalvm.compiler.nodes.spi.LIRLowerable; @@ -46,7 +46,7 @@ import jdk.vm.ci.meta.ResolvedJavaType; import jdk.vm.ci.meta.Value; -@NodeInfo(cycles = CYCLES_UNKNOWN, cyclesRationale = "Native call is a block hole", size = SIZE_20) +@NodeInfo(cycles = CYCLES_UNKNOWN, cyclesRationale = "Native call is a block hole", size = NodeSize.SIZE_UNKNOWN) public final class AMD64RawNativeCallNode extends FixedWithNextNode implements LIRLowerable { public static final NodeClass TYPE = NodeClass.create(AMD64RawNativeCallNode.class); diff -r d5572756efd6 -r ab5b504181d8 hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.sparc/src/org/graalvm/compiler/hotspot/sparc/SPARCHotSpotBackendFactory.java --- a/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.sparc/src/org/graalvm/compiler/hotspot/sparc/SPARCHotSpotBackendFactory.java Tue Apr 18 20:10:55 2017 -0700 +++ b/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.sparc/src/org/graalvm/compiler/hotspot/sparc/SPARCHotSpotBackendFactory.java Wed Apr 19 04:10:56 2017 +0000 @@ -44,11 +44,9 @@ import org.graalvm.compiler.hotspot.meta.HotSpotSnippetReflectionProvider; import org.graalvm.compiler.hotspot.meta.HotSpotStampProvider; import org.graalvm.compiler.hotspot.meta.HotSpotSuitesProvider; -import org.graalvm.compiler.hotspot.nodes.HotSpotNodeCostProvider; import org.graalvm.compiler.hotspot.word.HotSpotWordTypes; import org.graalvm.compiler.nodes.graphbuilderconf.GraphBuilderConfiguration.Plugins; import org.graalvm.compiler.nodes.spi.LoweringProvider; -import org.graalvm.compiler.nodes.spi.NodeCostProvider; import org.graalvm.compiler.nodes.spi.Replacements; import org.graalvm.compiler.phases.tiers.CompilerConfiguration; import org.graalvm.compiler.phases.util.Providers; @@ -98,15 +96,14 @@ HotSpotForeignCallsProvider foreignCalls = new SPARCHotSpotForeignCallsProvider(jvmciRuntime, runtime, metaAccess, codeCache, wordTypes, nativeABICallerSaveRegisters); LoweringProvider lowerer = createLowerer(runtime, metaAccess, foreignCalls, registers, constantReflection, target); HotSpotStampProvider stampProvider = new HotSpotStampProvider(); - NodeCostProvider nodeCostProvider = new SPARCHotSpotNodeCostProvider(); - Providers p = new Providers(metaAccess, codeCache, constantReflection, constantFieldProvider, foreignCalls, lowerer, null, stampProvider, nodeCostProvider); + Providers p = new Providers(metaAccess, codeCache, constantReflection, constantFieldProvider, foreignCalls, lowerer, null, stampProvider); HotSpotSnippetReflectionProvider snippetReflection = new HotSpotSnippetReflectionProvider(runtime, constantReflection, wordTypes); BytecodeProvider bytecodeProvider = new ClassfileBytecodeProvider(metaAccess, snippetReflection); HotSpotReplacementsImpl replacements = new HotSpotReplacementsImpl(runtime.getOptions(), p, snippetReflection, bytecodeProvider, target); Plugins plugins = createGraphBuilderPlugins(config, metaAccess, constantReflection, foreignCalls, stampProvider, snippetReflection, replacements, wordTypes); replacements.setGraphBuilderPlugins(plugins); HotSpotSuitesProvider suites = createSuites(config, runtime, compilerConfiguration, plugins, replacements); - HotSpotProviders providers = new HotSpotProviders(metaAccess, codeCache, constantReflection, constantFieldProvider, foreignCalls, lowerer, replacements, nodeCostProvider, suites, registers, + HotSpotProviders providers = new HotSpotProviders(metaAccess, codeCache, constantReflection, constantFieldProvider, foreignCalls, lowerer, replacements, suites, registers, snippetReflection, wordTypes, plugins); @@ -142,10 +139,6 @@ return new HotSpotRegisters(SPARC.g2, SPARC.g6, SPARC.sp); } - protected HotSpotNodeCostProvider createNodeCostProvider() { - return new SPARCHotSpotNodeCostProvider(); - } - @SuppressWarnings("unused") private static Value[] createNativeABICallerSaveRegisters(GraalHotSpotVMConfig config, RegisterConfig regConfig) { Set callerSavedRegisters = new HashSet<>(); diff -r d5572756efd6 -r ab5b504181d8 hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.sparc/src/org/graalvm/compiler/hotspot/sparc/SPARCHotSpotNodeCostProvider.java --- a/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.sparc/src/org/graalvm/compiler/hotspot/sparc/SPARCHotSpotNodeCostProvider.java Tue Apr 18 20:10:55 2017 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,55 +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.sparc; - -import org.graalvm.compiler.graph.Node; -import org.graalvm.compiler.hotspot.nodes.HotSpotNodeCostProvider; -import org.graalvm.compiler.hotspot.nodes.JumpToExceptionHandlerNode; -import org.graalvm.compiler.nodeinfo.NodeCycles; -import org.graalvm.compiler.nodeinfo.NodeSize; -import org.graalvm.compiler.nodes.ReturnNode; - -public class SPARCHotSpotNodeCostProvider extends HotSpotNodeCostProvider { - - @Override - public NodeCycles cycles(Node n) { - if (n instanceof ReturnNode) { - return NodeCycles.CYCLES_6; - } else if (n instanceof JumpToExceptionHandlerNode) { - // restore caller window - return NodeCycles.CYCLES_3; - } - return super.cycles(n); - } - - @Override - public NodeSize size(Node n) { - if (n instanceof ReturnNode) { - return NodeSize.SIZE_4; - } else if (n instanceof JumpToExceptionHandlerNode) { - // restore caller window - return NodeSize.SIZE_3; - } - return super.size(n); - } -} diff -r d5572756efd6 -r ab5b504181d8 hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.test/src/org/graalvm/compiler/hotspot/test/CompileTheWorld.java --- /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/CompileTheWorld.java Wed Apr 19 04:10:56 2017 +0000 @@ -0,0 +1,829 @@ +/* + * Copyright (c) 2013, 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.hotspot.test; + +import static java.util.Collections.singletonList; +import static org.graalvm.compiler.core.GraalCompilerOptions.ExitVMOnException; +import static org.graalvm.compiler.core.GraalCompilerOptions.PrintBailout; +import static org.graalvm.compiler.core.GraalCompilerOptions.PrintStackTraceOnException; +import static org.graalvm.compiler.core.common.util.Util.Java8OrEarlier; +import static org.graalvm.compiler.core.test.ReflectionOptionDescriptors.extractEntries; +import static org.graalvm.compiler.hotspot.test.CompileTheWorld.Options.DESCRIPTORS; + +import java.io.Closeable; +import java.io.File; +import java.io.IOException; +import java.lang.annotation.Annotation; +import java.lang.reflect.Constructor; +import java.lang.reflect.Method; +import java.lang.reflect.Modifier; +import java.net.URI; +import java.net.URL; +import java.net.URLClassLoader; +import java.nio.file.FileSystem; +import java.nio.file.FileSystems; +import java.nio.file.FileVisitResult; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.SimpleFileVisitor; +import java.nio.file.attribute.BasicFileAttributes; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.Enumeration; +import java.util.HashSet; +import java.util.List; +import java.util.ServiceLoader; +import java.util.Set; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.Future; +import java.util.concurrent.LinkedBlockingQueue; +import java.util.concurrent.ThreadPoolExecutor; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.atomic.AtomicLong; +import java.util.jar.JarEntry; +import java.util.jar.JarFile; +import java.util.stream.Collectors; + +import org.graalvm.compiler.api.replacements.Snippet; +import org.graalvm.compiler.bytecode.Bytecodes; +import org.graalvm.compiler.core.CompilerThreadFactory; +import org.graalvm.compiler.core.CompilerThreadFactory.DebugConfigAccess; +import org.graalvm.compiler.core.common.util.Util; +import org.graalvm.compiler.core.test.ReflectionOptionDescriptors; +import org.graalvm.compiler.debug.DebugEnvironment; +import org.graalvm.compiler.debug.GraalDebugConfig; +import org.graalvm.compiler.debug.GraalError; +import org.graalvm.compiler.debug.MethodFilter; +import org.graalvm.compiler.debug.TTY; +import org.graalvm.compiler.debug.internal.MemUseTrackerImpl; +import org.graalvm.compiler.hotspot.CompilationTask; +import org.graalvm.compiler.hotspot.GraalHotSpotVMConfig; +import org.graalvm.compiler.hotspot.HotSpotGraalCompiler; +import org.graalvm.compiler.hotspot.HotSpotGraalRuntimeProvider; +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 jdk.vm.ci.hotspot.HotSpotCodeCacheProvider; +import jdk.vm.ci.hotspot.HotSpotCompilationRequest; +import jdk.vm.ci.hotspot.HotSpotInstalledCode; +import jdk.vm.ci.hotspot.HotSpotJVMCIRuntime; +import jdk.vm.ci.hotspot.HotSpotJVMCIRuntimeProvider; +import jdk.vm.ci.hotspot.HotSpotResolvedJavaMethod; +import jdk.vm.ci.hotspot.HotSpotResolvedObjectType; +import jdk.vm.ci.meta.ConstantPool; +import jdk.vm.ci.meta.MetaAccessProvider; +import jdk.vm.ci.runtime.JVMCI; +import jdk.vm.ci.runtime.JVMCICompiler; +import jdk.vm.ci.services.Services; + +/** + * This class implements compile-the-world functionality with JVMCI. + */ +public final class CompileTheWorld { + + /** + * Magic token to denote that JDK classes are to be compiled. If {@link Util#Java8OrEarlier}, + * then the classes in {@code rt.jar} are compiled. Otherwise the classes in the Java runtime + * image are compiled. + */ + public static final String SUN_BOOT_CLASS_PATH = "sun.boot.class.path"; + + /** + * Magic token to denote the classes in the Java runtime image (i.e. in the {@code jrt:/} file + * system). + */ + public static final String JRT_CLASS_PATH_ENTRY = ""; + + /** + * @param options a space separated set of option value settings with each option setting in a + * {@code -Dgraal.=} format but without the leading {@code -Dgraal.}. + * Ignored if null. + */ + public static EconomicMap, Object> parseOptions(String options) { + if (options != null) { + EconomicMap optionSettings = EconomicMap.create(); + for (String optionSetting : options.split("\\s+|#")) { + OptionsParser.parseOptionSettingTo(optionSetting, optionSettings); + } + EconomicMap, Object> values = OptionValues.newOptionMap(); + ServiceLoader loader = ServiceLoader.load(OptionDescriptors.class, OptionDescriptors.class.getClassLoader()); + OptionsParser.parseOptions(optionSettings, values, loader); + return values; + } + return EconomicMap.create(); + } + + private final HotSpotJVMCIRuntimeProvider jvmciRuntime; + + private final HotSpotGraalCompiler compiler; + + /** + * Class path denoting classes to compile. + * + * @see Options#Classpath + */ + private final String inputClassPath; + + /** + * Class index to start compilation at. + * + * @see Options#StartAt + */ + private final int startAt; + + /** + * Class index to stop compilation at. + * + * @see Options#StopAt + */ + private final int stopAt; + + /** Only compile methods matching one of the filters in this array if the array is non-null. */ + private final MethodFilter[] methodFilters; + + /** Exclude methods matching one of the filters in this array if the array is non-null. */ + private final MethodFilter[] excludeMethodFilters; + + // Counters + private int classFileCounter = 0; + private AtomicLong compiledMethodsCounter = new AtomicLong(); + private AtomicLong compileTime = new AtomicLong(); + private AtomicLong memoryUsed = new AtomicLong(); + + private boolean verbose; + + /** + * Signal that the threads should start compiling in multithreaded mode. + */ + private boolean running; + + private ThreadPoolExecutor threadPool; + + private OptionValues currentOptions; + private final EconomicMap, Object> compilationOptions; + + /** + * Creates a compile-the-world instance. + * + * @param files {@link File#pathSeparator} separated list of Zip/Jar files to compile + * @param startAt index of the class file to start compilation at + * @param stopAt index of the class file to stop compilation at + * @param methodFilters + * @param excludeMethodFilters + */ + public CompileTheWorld(HotSpotJVMCIRuntimeProvider jvmciRuntime, HotSpotGraalCompiler compiler, String files, int startAt, int stopAt, String methodFilters, String excludeMethodFilters, + boolean verbose, OptionValues initialOptions, EconomicMap, Object> compilationOptions) { + this.jvmciRuntime = jvmciRuntime; + this.compiler = compiler; + this.inputClassPath = files; + this.startAt = startAt; + this.stopAt = stopAt; + this.methodFilters = methodFilters == null || methodFilters.isEmpty() ? null : MethodFilter.parse(methodFilters); + this.excludeMethodFilters = excludeMethodFilters == null || excludeMethodFilters.isEmpty() ? null : MethodFilter.parse(excludeMethodFilters); + this.verbose = verbose; + EconomicMap, Object> compilationOptionsCopy = EconomicMap.create(compilationOptions); + this.currentOptions = initialOptions; + + // We don't want the VM to exit when a method fails to compile... + ExitVMOnException.update(compilationOptionsCopy, false); + + // ...but we want to see exceptions. + PrintBailout.update(compilationOptionsCopy, true); + PrintStackTraceOnException.update(compilationOptionsCopy, true); + + // By default only report statistics for the CTW threads themselves + if (!GraalDebugConfig.Options.DebugValueThreadFilter.hasBeenSet(initialOptions)) { + GraalDebugConfig.Options.DebugValueThreadFilter.update(compilationOptionsCopy, "^CompileTheWorld"); + } + this.compilationOptions = EconomicMap.create(compilationOptionsCopy); + } + + public CompileTheWorld(HotSpotJVMCIRuntimeProvider jvmciRuntime, HotSpotGraalCompiler compiler, OptionValues options) { + this(jvmciRuntime, compiler, Options.Classpath.getValue(options), + Options.StartAt.getValue(options), + Options.StopAt.getValue(options), + Options.MethodFilter.getValue(options), + Options.ExcludeMethodFilter.getValue(options), + Options.Verbose.getValue(options), + options, + parseOptions(Options.Config.getValue(options))); + } + + /** + * Compiles all methods in all classes in {@link #inputClassPath}. If {@link #inputClassPath} + * equals {@link #SUN_BOOT_CLASS_PATH} the boot classes are used. + */ + public void compile() throws Throwable { + if (SUN_BOOT_CLASS_PATH.equals(inputClassPath)) { + String bcpEntry = null; + if (Java8OrEarlier) { + final String[] entries = System.getProperty(SUN_BOOT_CLASS_PATH).split(File.pathSeparator); + for (int i = 0; i < entries.length && bcpEntry == null; i++) { + String entry = entries[i]; + File entryFile = new File(entry); + if (entryFile.getName().endsWith("rt.jar") && entryFile.isFile()) { + bcpEntry = entry; + } + } + if (bcpEntry == null) { + throw new GraalError("Could not find rt.jar on boot class path %s", System.getProperty(SUN_BOOT_CLASS_PATH)); + } + } else { + bcpEntry = JRT_CLASS_PATH_ENTRY; + } + compile(bcpEntry); + } else { + compile(inputClassPath); + } + } + + public void println() { + println(""); + } + + public void println(String format, Object... args) { + println(String.format(format, args)); + } + + public void println(String s) { + println(verbose, s); + } + + public static void println(boolean cond, String s) { + if (cond) { + TTY.println(s); + } + } + + public void printStackTrace(Throwable t) { + if (verbose) { + t.printStackTrace(TTY.out); + } + } + + @SuppressWarnings("unused") + private static void dummy() { + } + + /** + * Abstraction over different types of class path entries. + */ + abstract static class ClassPathEntry implements Closeable { + final String name; + + ClassPathEntry(String name) { + this.name = name; + } + + /** + * Creates a {@link ClassLoader} for loading classes from this entry. + */ + public abstract ClassLoader createClassLoader() throws IOException; + + /** + * Gets the list of classes available under this entry. + */ + public abstract List getClassNames() throws IOException; + + @Override + public String toString() { + return name; + } + + @Override + public void close() throws IOException { + } + } + + /** + * A class path entry that is a normal file system directory. + */ + static class DirClassPathEntry extends ClassPathEntry { + + private final File dir; + + DirClassPathEntry(String name) { + super(name); + dir = new File(name); + assert dir.isDirectory(); + } + + @Override + public ClassLoader createClassLoader() throws IOException { + URL url = dir.toURI().toURL(); + return new URLClassLoader(new URL[]{url}); + } + + @Override + public List getClassNames() throws IOException { + List classNames = new ArrayList<>(); + String root = dir.getPath(); + SimpleFileVisitor visitor = new SimpleFileVisitor() { + @Override + public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException { + if (attrs.isRegularFile()) { + File path = file.toFile(); + if (path.getName().endsWith(".class")) { + String pathString = path.getPath(); + assert pathString.startsWith(root); + String classFile = pathString.substring(root.length() + 1); + String className = classFile.replace(File.separatorChar, '.'); + classNames.add(className.replace('/', '.').substring(0, className.length() - ".class".length())); + } + } + return super.visitFile(file, attrs); + } + }; + Files.walkFileTree(dir.toPath(), visitor); + return classNames; + } + } + + /** + * A class path entry that is a jar or zip file. + */ + static class JarClassPathEntry extends ClassPathEntry { + + private final JarFile jarFile; + + JarClassPathEntry(String name) throws IOException { + super(name); + jarFile = new JarFile(name); + } + + @Override + public ClassLoader createClassLoader() throws IOException { + URL url = new URL("jar", "", "file:" + name + "!/"); + return new URLClassLoader(new URL[]{url}); + } + + @Override + public List getClassNames() throws IOException { + Enumeration e = jarFile.entries(); + List classNames = new ArrayList<>(jarFile.size()); + while (e.hasMoreElements()) { + JarEntry je = e.nextElement(); + if (je.isDirectory() || !je.getName().endsWith(".class")) { + continue; + } + String className = je.getName().substring(0, je.getName().length() - ".class".length()); + classNames.add(className.replace('/', '.')); + } + return classNames; + } + + @Override + public void close() throws IOException { + jarFile.close(); + } + } + + /** + * A class path entry representing the {@code jrt:/} file system. + */ + static class JRTClassPathEntry extends ClassPathEntry { + + private final String limitModules; + + JRTClassPathEntry(String name, String limitModules) { + super(name); + this.limitModules = limitModules; + } + + @Override + public ClassLoader createClassLoader() throws IOException { + URL url = URI.create("jrt:/").toURL(); + return new URLClassLoader(new URL[]{url}); + } + + @Override + public List getClassNames() throws IOException { + Set negative = new HashSet<>(); + Set positive = new HashSet<>(); + if (limitModules != null && !limitModules.isEmpty()) { + for (String s : limitModules.split(",")) { + if (s.startsWith("~")) { + negative.add(s.substring(1)); + } else { + positive.add(s); + } + } + } + List classNames = new ArrayList<>(); + FileSystem fs = FileSystems.newFileSystem(URI.create("jrt:/"), Collections.emptyMap()); + Path top = fs.getPath("/modules/"); + Files.find(top, Integer.MAX_VALUE, + (path, attrs) -> attrs.isRegularFile()).forEach(p -> { + int nameCount = p.getNameCount(); + if (nameCount > 2) { + String base = p.getName(nameCount - 1).toString(); + if (base.endsWith(".class") && !base.equals("module-info.class")) { + String module = p.getName(1).toString(); + if (positive.isEmpty() || positive.contains(module)) { + if (negative.isEmpty() || !negative.contains(module)) { + // Strip module prefix and convert to dotted form + String className = p.subpath(2, nameCount).toString().replace('/', '.'); + // Strip ".class" suffix + className = className.replace('/', '.').substring(0, className.length() - ".class".length()); + classNames.add(className); + } + } + } + } + }); + return classNames; + } + } + + private boolean isClassIncluded(String className) { + if (methodFilters != null && !MethodFilter.matchesClassName(methodFilters, className)) { + return false; + } + if (excludeMethodFilters != null && MethodFilter.matchesClassName(excludeMethodFilters, className)) { + return false; + } + return true; + } + + /** + * Compiles all methods in all classes in a given class path. + * + * @param classPath class path denoting classes to compile + * @throws IOException + */ + @SuppressWarnings("try") + private void compile(String classPath) throws IOException { + final String[] entries = classPath.split(File.pathSeparator); + long start = System.currentTimeMillis(); + + try { + // compile dummy method to get compiler initialized outside of the + // config debug override. + HotSpotResolvedJavaMethod dummyMethod = (HotSpotResolvedJavaMethod) JVMCI.getRuntime().getHostJVMCIBackend().getMetaAccess().lookupJavaMethod( + CompileTheWorld.class.getDeclaredMethod("dummy")); + int entryBCI = JVMCICompiler.INVOCATION_ENTRY_BCI; + boolean useProfilingInfo = false; + boolean installAsDefault = false; + CompilationTask task = new CompilationTask(jvmciRuntime, compiler, new HotSpotCompilationRequest(dummyMethod, entryBCI, 0L), useProfilingInfo, installAsDefault, currentOptions); + task.runCompilation(); + } catch (NoSuchMethodException | SecurityException e1) { + printStackTrace(e1); + } + + /* + * Always use a thread pool, even for single threaded mode since it simplifies the use of + * DebugValueThreadFilter to filter on the thread names. + */ + int threadCount = 1; + if (Options.MultiThreaded.getValue(currentOptions)) { + threadCount = Options.Threads.getValue(currentOptions); + if (threadCount == 0) { + threadCount = Runtime.getRuntime().availableProcessors(); + } + } else { + running = true; + } + + OptionValues savedOptions = currentOptions; + currentOptions = new OptionValues(savedOptions, compilationOptions); + threadPool = new ThreadPoolExecutor(threadCount, threadCount, 0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue(), + new CompilerThreadFactory("CompileTheWorld", new DebugConfigAccess() { + @Override + public GraalDebugConfig getDebugConfig() { + return DebugEnvironment.ensureInitialized(currentOptions, compiler.getGraalRuntime().getHostProviders().getSnippetReflection()); + } + })); + + try { + for (int i = 0; i < entries.length; i++) { + final String entry = entries[i]; + + ClassPathEntry cpe; + if (entry.endsWith(".zip") || entry.endsWith(".jar")) { + cpe = new JarClassPathEntry(entry); + } else if (entry.equals(JRT_CLASS_PATH_ENTRY)) { + cpe = new JRTClassPathEntry(entry, Options.LimitModules.getValue(currentOptions)); + } else { + if (!new File(entry).isDirectory()) { + println("CompileTheWorld : Skipped classes in " + entry); + println(); + continue; + } + cpe = new DirClassPathEntry(entry); + } + + if (methodFilters == null || methodFilters.length == 0) { + println("CompileTheWorld : Compiling all classes in " + entry); + } else { + String include = Arrays.asList(methodFilters).stream().map(MethodFilter::toString).collect(Collectors.joining(", ")); + println("CompileTheWorld : Compiling all methods in " + entry + " matching one of the following filters: " + include); + } + if (excludeMethodFilters != null && excludeMethodFilters.length > 0) { + String exclude = Arrays.asList(excludeMethodFilters).stream().map(MethodFilter::toString).collect(Collectors.joining(", ")); + println("CompileTheWorld : Excluding all methods matching one of the following filters: " + exclude); + } + println(); + + ClassLoader loader = cpe.createClassLoader(); + + for (String className : cpe.getClassNames()) { + + // Are we done? + if (classFileCounter >= stopAt) { + break; + } + + classFileCounter++; + + if (className.startsWith("jdk.management.") || className.startsWith("jdk.internal.cmm.*")) { + continue; + } + + try { + // Load and initialize class + Class javaClass = Class.forName(className, true, loader); + + // Pre-load all classes in the constant pool. + try { + HotSpotResolvedObjectType objectType = HotSpotResolvedObjectType.fromObjectClass(javaClass); + ConstantPool constantPool = objectType.getConstantPool(); + for (int cpi = 1; cpi < constantPool.length(); cpi++) { + constantPool.loadReferencedType(cpi, Bytecodes.LDC); + } + } catch (Throwable t) { + // If something went wrong during pre-loading we just ignore it. + if (isClassIncluded(className)) { + println("Preloading failed for (%d) %s: %s", classFileCounter, className, t); + } + continue; + } + + /* + * Only check filters after class loading and resolution to mitigate impact + * on reproducibility. + */ + if (!isClassIncluded(className)) { + continue; + } + + // Are we compiling this class? + MetaAccessProvider metaAccess = JVMCI.getRuntime().getHostJVMCIBackend().getMetaAccess(); + if (classFileCounter >= startAt) { + println("CompileTheWorld (%d) : %s", classFileCounter, className); + + // Compile each constructor/method in the class. + for (Constructor constructor : javaClass.getDeclaredConstructors()) { + HotSpotResolvedJavaMethod javaMethod = (HotSpotResolvedJavaMethod) metaAccess.lookupJavaMethod(constructor); + if (canBeCompiled(javaMethod, constructor.getModifiers())) { + compileMethod(javaMethod); + } + } + for (Method method : javaClass.getDeclaredMethods()) { + HotSpotResolvedJavaMethod javaMethod = (HotSpotResolvedJavaMethod) metaAccess.lookupJavaMethod(method); + if (canBeCompiled(javaMethod, method.getModifiers())) { + compileMethod(javaMethod); + } + } + + // Also compile the class initializer if it exists + HotSpotResolvedJavaMethod clinit = (HotSpotResolvedJavaMethod) metaAccess.lookupJavaType(javaClass).getClassInitializer(); + if (clinit != null && canBeCompiled(clinit, clinit.getModifiers())) { + compileMethod(clinit); + } + } + } catch (Throwable t) { + if (isClassIncluded(className)) { + println("CompileTheWorld (%d) : Skipping %s %s", classFileCounter, className, t.toString()); + printStackTrace(t); + } + } + } + cpe.close(); + } + } finally { + currentOptions = savedOptions; + } + + if (!running) { + startThreads(); + } + int wakeups = 0; + while (threadPool.getCompletedTaskCount() != threadPool.getTaskCount()) { + if (wakeups % 15 == 0) { + TTY.println("CompileTheWorld : Waiting for " + (threadPool.getTaskCount() - threadPool.getCompletedTaskCount()) + " compiles"); + } + try { + threadPool.awaitTermination(1, TimeUnit.SECONDS); + wakeups++; + } catch (InterruptedException e) { + } + } + threadPool = null; + + long elapsedTime = System.currentTimeMillis() - start; + + println(); + if (Options.MultiThreaded.getValue(currentOptions)) { + TTY.println("CompileTheWorld : Done (%d classes, %d methods, %d ms elapsed, %d ms compile time, %d bytes of memory used)", classFileCounter, compiledMethodsCounter.get(), elapsedTime, + compileTime.get(), memoryUsed.get()); + } else { + TTY.println("CompileTheWorld : Done (%d classes, %d methods, %d ms, %d bytes of memory used)", classFileCounter, compiledMethodsCounter.get(), compileTime.get(), memoryUsed.get()); + } + } + + private synchronized void startThreads() { + running = true; + // Wake up any waiting threads + notifyAll(); + } + + private synchronized void waitToRun() { + while (!running) { + try { + wait(); + } catch (InterruptedException e) { + } + } + } + + @SuppressWarnings("try") + private void compileMethod(HotSpotResolvedJavaMethod method) throws InterruptedException, ExecutionException { + if (methodFilters != null && !MethodFilter.matches(methodFilters, method)) { + return; + } + if (excludeMethodFilters != null && MethodFilter.matches(excludeMethodFilters, method)) { + return; + } + Future task = threadPool.submit(new Runnable() { + @Override + public void run() { + waitToRun(); + OptionValues savedOptions = currentOptions; + currentOptions = new OptionValues(savedOptions, compilationOptions); + try { + compileMethod(method, classFileCounter); + } finally { + currentOptions = savedOptions; + } + } + }); + if (threadPool.getCorePoolSize() == 1) { + task.get(); + } + } + + /** + * Compiles a method and gathers some statistics. + */ + private void compileMethod(HotSpotResolvedJavaMethod method, int counter) { + try { + long start = System.currentTimeMillis(); + long allocatedAtStart = MemUseTrackerImpl.getCurrentThreadAllocatedBytes(); + int entryBCI = JVMCICompiler.INVOCATION_ENTRY_BCI; + HotSpotCompilationRequest request = new HotSpotCompilationRequest(method, entryBCI, 0L); + // For more stable CTW execution, disable use of profiling information + boolean useProfilingInfo = false; + boolean installAsDefault = false; + CompilationTask task = new CompilationTask(jvmciRuntime, compiler, request, useProfilingInfo, installAsDefault, currentOptions); + task.runCompilation(); + + // Invalidate the generated code so the code cache doesn't fill up + HotSpotInstalledCode installedCode = task.getInstalledCode(); + if (installedCode != null) { + installedCode.invalidate(); + } + + memoryUsed.getAndAdd(MemUseTrackerImpl.getCurrentThreadAllocatedBytes() - allocatedAtStart); + compileTime.getAndAdd(System.currentTimeMillis() - start); + compiledMethodsCounter.incrementAndGet(); + } catch (Throwable t) { + // Catch everything and print a message + println("CompileTheWorld (%d) : Error compiling method: %s", counter, method.format("%H.%n(%p):%r")); + printStackTrace(t); + } + } + + /** + * Determines if a method should be compiled (Cf. CompilationPolicy::can_be_compiled). + * + * @return true if it can be compiled, false otherwise + */ + private boolean canBeCompiled(HotSpotResolvedJavaMethod javaMethod, int modifiers) { + if (Modifier.isAbstract(modifiers) || Modifier.isNative(modifiers)) { + return false; + } + GraalHotSpotVMConfig c = compiler.getGraalRuntime().getVMConfig(); + if (c.dontCompileHugeMethods && javaMethod.getCodeSize() > c.hugeMethodLimit) { + println(verbose || methodFilters != null, + String.format("CompileTheWorld (%d) : Skipping huge method %s (use -XX:-DontCompileHugeMethods or -XX:HugeMethodLimit=%d to include it)", classFileCounter, + javaMethod.format("%H.%n(%p):%r"), + javaMethod.getCodeSize())); + return false; + } + // Allow use of -XX:CompileCommand=dontinline to exclude problematic methods + if (!javaMethod.canBeInlined()) { + return false; + } + // Skip @Snippets for now + for (Annotation annotation : javaMethod.getAnnotations()) { + if (annotation.annotationType().equals(Snippet.class)) { + return false; + } + } + return true; + } + + static class Options { + // @formatter:off + public static final OptionKey Help = new OptionKey<>(false); + public static final OptionKey Classpath = new OptionKey<>(CompileTheWorld.SUN_BOOT_CLASS_PATH); + public static final OptionKey Verbose = new OptionKey<>(true); + /** + * Ignore Graal classes by default to avoid problems associated with compiling + * snippets and method substitutions. + */ + public static final OptionKey LimitModules = new OptionKey<>("~jdk.internal.vm.compiler"); + public static final OptionKey Iterations = new OptionKey<>(1); + public static final OptionKey MethodFilter = new OptionKey<>(null); + public static final OptionKey ExcludeMethodFilter = new OptionKey<>(null); + public static final OptionKey StartAt = new OptionKey<>(1); + public static final OptionKey StopAt = new OptionKey<>(Integer.MAX_VALUE); + public static final OptionKey Config = new OptionKey<>(null); + public static final OptionKey MultiThreaded = new OptionKey<>(false); + public static final OptionKey Threads = new OptionKey<>(0); + + static final ReflectionOptionDescriptors DESCRIPTORS = new ReflectionOptionDescriptors(Options.class, + "Help", "List options and their help messages and then exit.", + "Classpath", "Class path denoting methods to compile. Default is to compile boot classes.", + "Verbose", "Verbose operation.", + "LimitModules", "Comma separated list of module names to which compilation should be limited. " + + "Module names can be prefixed with \"~\" to exclude the named module.", + "Iterations", "The number of iterations to perform.", + "MethodFilter", "Only compile methods matching this filter.", + "ExcludeMethodFilter", "Exclude methods matching this filter from compilation.", + "StartAt", "First class to consider for compilation.", + "StopAt", "Last class to consider for compilation.", + "Config", "Option value overrides to use during compile the world. For example, " + + "to disable inlining and partial escape analysis specify 'PartialEscapeAnalysis=false Inline=false'. " + + "The format for each option is the same as on the command line just without the '-Dgraal.' prefix.", + "MultiThreaded", "Run using multiple threads for compilation.", + "Threads", "Number of threads to use for multithreaded execution. Defaults to Runtime.getRuntime().availableProcessors()."); + // @formatter:on + } + + public static OptionValues loadOptions(OptionValues initialValues) { + EconomicMap, Object> values = OptionValues.newOptionMap(); + List loader = singletonList(DESCRIPTORS); + OptionsParser.parseOptions(extractEntries(System.getProperties(), "CompileTheWorld.", true), values, loader); + OptionValues options = new OptionValues(initialValues, values); + if (Options.Help.getValue(options)) { + options.printHelp(loader, System.out, "CompileTheWorld."); + System.exit(0); + } + return options; + } + + public static void main(String[] args) throws Throwable { + Services.exportJVMCITo(CompileTheWorld.class); + HotSpotJVMCIRuntime jvmciRuntime = HotSpotJVMCIRuntime.runtime(); + HotSpotGraalCompiler compiler = (HotSpotGraalCompiler) jvmciRuntime.getCompiler(); + HotSpotGraalRuntimeProvider graalRuntime = compiler.getGraalRuntime(); + HotSpotCodeCacheProvider codeCache = graalRuntime.getHostProviders().getCodeCache(); + OptionValues options = loadOptions(graalRuntime.getOptions()); + + int iterations = Options.Iterations.getValue(options); + for (int i = 0; i < iterations; i++) { + codeCache.resetCompilationStatistics(); + TTY.println("CompileTheWorld : iteration " + i); + + CompileTheWorld ctw = new CompileTheWorld(jvmciRuntime, compiler, options); + ctw.compile(); + } + // This is required as non-daemon threads can be started by class initializers + System.exit(0); + } +} diff -r d5572756efd6 -r ab5b504181d8 hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.test/src/org/graalvm/compiler/hotspot/test/CompileTheWorldTest.java --- a/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.test/src/org/graalvm/compiler/hotspot/test/CompileTheWorldTest.java Tue Apr 18 20:10:55 2017 -0700 +++ b/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.test/src/org/graalvm/compiler/hotspot/test/CompileTheWorldTest.java Wed Apr 19 04:10:56 2017 +0000 @@ -24,7 +24,6 @@ import static org.graalvm.compiler.core.GraalCompilerOptions.ExitVMOnException; import org.graalvm.compiler.core.test.GraalCompilerTest; -import org.graalvm.compiler.hotspot.CompileTheWorld; import org.graalvm.compiler.hotspot.HotSpotGraalCompiler; import org.graalvm.compiler.options.OptionKey; import org.graalvm.compiler.options.OptionValues; @@ -44,7 +43,7 @@ boolean originalSetting = ExitVMOnException.getValue(getInitialOptions()); // Compile a couple classes in rt.jar HotSpotJVMCIRuntimeProvider runtime = HotSpotJVMCIRuntime.runtime(); - System.setProperty(CompileTheWorld.LIMITMODS_PROPERTY_NAME, "java.base"); + System.setProperty("CompileTheWorld.LimitModules", "java.base"); OptionValues initialOptions = getInitialOptions(); EconomicMap, Object> compilationOptions = CompileTheWorld.parseOptions("Inline=false"); new CompileTheWorld(runtime, (HotSpotGraalCompiler) runtime.getCompiler(), CompileTheWorld.SUN_BOOT_CLASS_PATH, 1, 5, null, null, false, initialOptions, compilationOptions).compile(); diff -r d5572756efd6 -r ab5b504181d8 hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.test/src/org/graalvm/compiler/hotspot/test/MemoryUsageBenchmark.java --- a/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.test/src/org/graalvm/compiler/hotspot/test/MemoryUsageBenchmark.java Tue Apr 18 20:10:55 2017 -0700 +++ b/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.test/src/org/graalvm/compiler/hotspot/test/MemoryUsageBenchmark.java Wed Apr 19 04:10:56 2017 +0000 @@ -28,10 +28,9 @@ import org.graalvm.compiler.core.test.AllocSpy; import org.graalvm.compiler.debug.DebugEnvironment; import org.graalvm.compiler.hotspot.CompilationTask; -import org.graalvm.compiler.hotspot.CompileTheWorld; -import org.graalvm.compiler.hotspot.CompileTheWorldOptions; import org.graalvm.compiler.hotspot.HotSpotGraalCompiler; import org.graalvm.compiler.nodes.StructuredGraph.AllowAssumptions; +import org.graalvm.compiler.options.OptionValues; import jdk.vm.ci.hotspot.HotSpotCompilationRequest; import jdk.vm.ci.hotspot.HotSpotJVMCIRuntime; @@ -51,7 +50,7 @@ * Memory analysis for a {@link CompileTheWorld} execution can also be performed. For example: * *
- *     mx --vm server vm -XX:-UseJVMCIClassLoader -Dgraal.CompileTheWorldClasspath=$HOME/SPECjvm2008/SPECjvm2008.jar -cp @org.graalvm.compiler.hotspot.test org.graalvm.compiler.hotspot.test.MemoryUsageBenchmark
+ *     mx vm -XX:-UseJVMCIClassLoader -DCompileTheWorld.Classpath=$HOME/SPECjvm2008/SPECjvm2008.jar -cp @org.graalvm.compiler.hotspot.test org.graalvm.compiler.hotspot.test.MemoryUsageBenchmark
  * 
*/ public class MemoryUsageBenchmark extends HotSpotGraalCompilerTest { @@ -181,9 +180,10 @@ public void run() { compileAndTime("simple"); compileAndTime("complex"); - if (CompileTheWorldOptions.CompileTheWorldClasspath.getValue(getInitialOptions()) != CompileTheWorld.SUN_BOOT_CLASS_PATH) { + OptionValues options = CompileTheWorld.loadOptions(getInitialOptions()); + if (CompileTheWorld.Options.Classpath.getValue(options) != CompileTheWorld.SUN_BOOT_CLASS_PATH) { HotSpotJVMCIRuntimeProvider runtime = HotSpotJVMCIRuntime.runtime(); - CompileTheWorld ctw = new CompileTheWorld(runtime, (HotSpotGraalCompiler) runtime.getCompiler(), getInitialOptions()); + CompileTheWorld ctw = new CompileTheWorld(runtime, (HotSpotGraalCompiler) runtime.getCompiler(), options); try { ctw.compile(); } catch (Throwable e) { diff -r d5572756efd6 -r ab5b504181d8 hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.test/src/org/graalvm/compiler/hotspot/test/OptionsInFileTest.java --- /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/OptionsInFileTest.java Wed Apr 19 04:10:56 2017 +0000 @@ -0,0 +1,101 @@ +/* + * Copyright (c) 2013, 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.test; + +import static org.graalvm.compiler.debug.GraalDebugConfig.Options.Dump; +import static org.graalvm.compiler.debug.GraalDebugConfig.Options.MethodFilter; +import static org.graalvm.compiler.debug.GraalDebugConfig.Options.PrintGraph; +import static org.graalvm.compiler.test.SubprocessUtil.formatExecutedCommand; +import static org.graalvm.compiler.test.SubprocessUtil.getVMCommandLine; +import static org.graalvm.compiler.test.SubprocessUtil.withoutDebuggerArguments; + +import java.io.BufferedReader; +import java.io.File; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.InputStreamReader; +import java.io.PrintStream; +import java.util.ArrayList; +import java.util.List; + +import org.graalvm.compiler.core.test.GraalCompilerTest; +import org.junit.Assert; +import org.junit.Test; + +/** + * Tests reading options from a file specified by the {@code graal.options.file}. + */ +public class OptionsInFileTest extends GraalCompilerTest { + @Test + public void test() throws IOException { + List args = withoutDebuggerArguments(getVMCommandLine()); + + String methodFilterValue = "a very unlikely method name"; + String debugFilterValue = "a very unlikely debug scope"; + File optionsFile = File.createTempFile("options", ".properties").getAbsoluteFile(); + try { + Assert.assertFalse(methodFilterValue.equals(MethodFilter.getDefaultValue())); + Assert.assertFalse(debugFilterValue.equals(PrintGraph.getDefaultValue())); + Assert.assertTrue(PrintGraph.getDefaultValue()); + + try (PrintStream out = new PrintStream(new FileOutputStream(optionsFile))) { + out.println(MethodFilter.getName() + "=" + methodFilterValue); + out.println(Dump.getName() + "=" + debugFilterValue); + out.println(PrintGraph.getName() + " = false"); + } + + args.add("-Dgraal.options.file=" + optionsFile); + args.add("-XX:+JVMCIPrintProperties"); + + ProcessBuilder processBuilder = new ProcessBuilder(args); + processBuilder.redirectErrorStream(true); + Process process = processBuilder.start(); + BufferedReader stdout = new BufferedReader(new InputStreamReader(process.getInputStream())); + + String[] expected = { + "graal.MethodFilter := \"a very unlikely method name\"", + "graal.Dump := \"a very unlikely debug scope\"", + "graal.PrintGraph := false"}; + + List outputLines = new ArrayList<>(); + + String line; + while ((line = stdout.readLine()) != null) { + outputLines.add(line); + for (int i = 0; i < expected.length; i++) { + if (expected[i] != null && line.contains(expected[i])) { + expected[i] = null; + } + } + } + String dashes = "-------------------------------------------------------"; + for (int i = 0; i < expected.length; i++) { + if (expected[i] != null) { + Assert.fail(String.format("Did not find '%s' in output of command:%n%s", expected[i], formatExecutedCommand(args, outputLines, dashes, dashes))); + } + } + } finally { + optionsFile.delete(); + } + } +} diff -r d5572756efd6 -r ab5b504181d8 hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/CompileTheWorld.java --- a/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/CompileTheWorld.java Tue Apr 18 20:10:55 2017 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,777 +0,0 @@ -/* - * Copyright (c) 2013, 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.hotspot; - -import static org.graalvm.compiler.core.GraalCompilerOptions.ExitVMOnException; -import static org.graalvm.compiler.core.GraalCompilerOptions.PrintBailout; -import static org.graalvm.compiler.core.GraalCompilerOptions.PrintStackTraceOnException; -import static org.graalvm.compiler.core.common.util.Util.Java8OrEarlier; -import static org.graalvm.compiler.hotspot.CompileTheWorldOptions.CompileTheWorldClasspath; -import static org.graalvm.compiler.hotspot.CompileTheWorldOptions.CompileTheWorldConfig; -import static org.graalvm.compiler.hotspot.CompileTheWorldOptions.CompileTheWorldExcludeMethodFilter; -import static org.graalvm.compiler.hotspot.CompileTheWorldOptions.CompileTheWorldMethodFilter; -import static org.graalvm.compiler.hotspot.CompileTheWorldOptions.CompileTheWorldStartAt; -import static org.graalvm.compiler.hotspot.CompileTheWorldOptions.CompileTheWorldStopAt; -import static org.graalvm.compiler.hotspot.CompileTheWorldOptions.CompileTheWorldVerbose; - -import java.io.Closeable; -import java.io.File; -import java.io.IOException; -import java.lang.annotation.Annotation; -import java.lang.reflect.Constructor; -import java.lang.reflect.Method; -import java.lang.reflect.Modifier; -import java.net.URL; -import java.net.URLClassLoader; -import java.nio.ByteBuffer; -import java.nio.ByteOrder; -import java.nio.channels.FileChannel; -import java.nio.file.FileSystems; -import java.nio.file.FileVisitResult; -import java.nio.file.Files; -import java.nio.file.Path; -import java.nio.file.Paths; -import java.nio.file.SimpleFileVisitor; -import java.nio.file.StandardOpenOption; -import java.nio.file.attribute.BasicFileAttributes; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Enumeration; -import java.util.HashSet; -import java.util.List; -import java.util.ServiceLoader; -import java.util.Set; -import java.util.concurrent.ExecutionException; -import java.util.concurrent.Future; -import java.util.concurrent.LinkedBlockingQueue; -import java.util.concurrent.ThreadPoolExecutor; -import java.util.concurrent.TimeUnit; -import java.util.concurrent.atomic.AtomicLong; -import java.util.jar.JarEntry; -import java.util.jar.JarFile; -import java.util.stream.Collectors; - -import org.graalvm.compiler.api.replacements.Snippet; -import org.graalvm.compiler.bytecode.Bytecodes; -import org.graalvm.compiler.core.CompilerThreadFactory; -import org.graalvm.compiler.core.CompilerThreadFactory.DebugConfigAccess; -import org.graalvm.compiler.core.common.util.Util; -import org.graalvm.compiler.debug.DebugEnvironment; -import org.graalvm.compiler.debug.GraalDebugConfig; -import org.graalvm.compiler.debug.MethodFilter; -import org.graalvm.compiler.debug.TTY; -import org.graalvm.compiler.debug.internal.MemUseTrackerImpl; -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 jdk.vm.ci.hotspot.HotSpotCompilationRequest; -import jdk.vm.ci.hotspot.HotSpotInstalledCode; -import jdk.vm.ci.hotspot.HotSpotJVMCIRuntime; -import jdk.vm.ci.hotspot.HotSpotJVMCIRuntimeProvider; -import jdk.vm.ci.hotspot.HotSpotResolvedJavaMethod; -import jdk.vm.ci.hotspot.HotSpotResolvedObjectType; -import jdk.vm.ci.meta.ConstantPool; -import jdk.vm.ci.meta.MetaAccessProvider; -import jdk.vm.ci.runtime.JVMCI; -import jdk.vm.ci.runtime.JVMCICompiler; -import jdk.vm.ci.services.Services; - -/** - * This class implements compile-the-world functionality with JVMCI. - */ -public final class CompileTheWorld { - - /** - * Magic token to denote that JDK classes are to be compiled. If {@link Util#Java8OrEarlier}, - * then the classes in {@code rt.jar} are compiled. Otherwise the classes in {@code - * /lib/modules} are compiled. - */ - public static final String SUN_BOOT_CLASS_PATH = "sun.boot.class.path"; - - /** - * @param options a space separated set of option value settings with each option setting in a - * {@code -Dgraal.=} format but without the leading {@code -Dgraal.}. - * Ignored if null. - */ - public static EconomicMap, Object> parseOptions(String options) { - if (options != null) { - EconomicMap optionSettings = EconomicMap.create(); - for (String optionSetting : options.split("\\s+|#")) { - OptionsParser.parseOptionSettingTo(optionSetting, optionSettings); - } - EconomicMap, Object> values = OptionValues.newOptionMap(); - ServiceLoader loader = ServiceLoader.load(OptionDescriptors.class, OptionDescriptors.class.getClassLoader()); - OptionsParser.parseOptions(optionSettings, values, loader); - return values; - } - return EconomicMap.create(); - } - - private final HotSpotJVMCIRuntimeProvider jvmciRuntime; - - private final HotSpotGraalCompiler compiler; - - /** - * Class path denoting classes to compile. - * - * @see CompileTheWorldOptions#CompileTheWorldClasspath - */ - private final String inputClassPath; - - /** - * Class index to start compilation at. - * - * @see CompileTheWorldOptions#CompileTheWorldStartAt - */ - private final int startAt; - - /** - * Class index to stop compilation at. - * - * @see CompileTheWorldOptions#CompileTheWorldStopAt - */ - private final int stopAt; - - /** Only compile methods matching one of the filters in this array if the array is non-null. */ - private final MethodFilter[] methodFilters; - - /** Exclude methods matching one of the filters in this array if the array is non-null. */ - private final MethodFilter[] excludeMethodFilters; - - // Counters - private int classFileCounter = 0; - private AtomicLong compiledMethodsCounter = new AtomicLong(); - private AtomicLong compileTime = new AtomicLong(); - private AtomicLong memoryUsed = new AtomicLong(); - - private boolean verbose; - - /** - * Signal that the threads should start compiling in multithreaded mode. - */ - private boolean running; - - private ThreadPoolExecutor threadPool; - - private OptionValues currentOptions; - private final EconomicMap, Object> compilationOptions; - - /** - * Creates a compile-the-world instance. - * - * @param files {@link File#pathSeparator} separated list of Zip/Jar files to compile - * @param startAt index of the class file to start compilation at - * @param stopAt index of the class file to stop compilation at - * @param methodFilters - * @param excludeMethodFilters - */ - public CompileTheWorld(HotSpotJVMCIRuntimeProvider jvmciRuntime, HotSpotGraalCompiler compiler, String files, int startAt, int stopAt, String methodFilters, String excludeMethodFilters, - boolean verbose, OptionValues initialOptions, EconomicMap, Object> compilationOptions) { - this.jvmciRuntime = jvmciRuntime; - this.compiler = compiler; - this.inputClassPath = files; - this.startAt = startAt; - this.stopAt = stopAt; - this.methodFilters = methodFilters == null || methodFilters.isEmpty() ? null : MethodFilter.parse(methodFilters); - this.excludeMethodFilters = excludeMethodFilters == null || excludeMethodFilters.isEmpty() ? null : MethodFilter.parse(excludeMethodFilters); - this.verbose = verbose; - EconomicMap, Object> compilationOptionsCopy = EconomicMap.create(compilationOptions); - this.currentOptions = initialOptions; - - // We don't want the VM to exit when a method fails to compile... - ExitVMOnException.update(compilationOptionsCopy, false); - - // ...but we want to see exceptions. - PrintBailout.update(compilationOptionsCopy, true); - PrintStackTraceOnException.update(compilationOptionsCopy, true); - - // By default only report statistics for the CTW threads themselves - if (!GraalDebugConfig.Options.DebugValueThreadFilter.hasBeenSet(initialOptions)) { - GraalDebugConfig.Options.DebugValueThreadFilter.update(compilationOptionsCopy, "^CompileTheWorld"); - } - this.compilationOptions = EconomicMap.create(compilationOptionsCopy); - } - - public CompileTheWorld(HotSpotJVMCIRuntimeProvider jvmciRuntime, HotSpotGraalCompiler compiler, OptionValues options) { - this(jvmciRuntime, compiler, CompileTheWorldClasspath.getValue(options), - CompileTheWorldStartAt.getValue(options), - CompileTheWorldStopAt.getValue(options), - CompileTheWorldMethodFilter.getValue(options), - CompileTheWorldExcludeMethodFilter.getValue(options), - CompileTheWorldVerbose.getValue(options), - options, - parseOptions(CompileTheWorldConfig.getValue(options))); - } - - /** - * Compiles all methods in all classes in {@link #inputClassPath}. If {@link #inputClassPath} - * equals {@link #SUN_BOOT_CLASS_PATH} the boot class path is used. - */ - public void compile() throws Throwable { - if (SUN_BOOT_CLASS_PATH.equals(inputClassPath)) { - String bcpEntry = null; - if (Java8OrEarlier) { - final String[] entries = System.getProperty(SUN_BOOT_CLASS_PATH).split(File.pathSeparator); - for (int i = 0; i < entries.length && bcpEntry == null; i++) { - String entry = entries[i]; - File entryFile = new File(entry); - // We stop at rt.jar, unless it is the first boot class path entry. - if (entryFile.getName().endsWith("rt.jar") && entryFile.isFile()) { - bcpEntry = entry; - } - } - } else { - bcpEntry = System.getProperty("java.home") + "/lib/modules".replace('/', File.separatorChar); - } - compile(bcpEntry); - } else { - compile(inputClassPath); - } - } - - public void println() { - println(""); - } - - public void println(String format, Object... args) { - println(String.format(format, args)); - } - - public void println(String s) { - println(verbose, s); - } - - public static void println(boolean cond, String s) { - if (cond) { - TTY.println(s); - } - } - - public void printStackTrace(Throwable t) { - if (verbose) { - t.printStackTrace(TTY.out); - } - } - - @SuppressWarnings("unused") - private static void dummy() { - } - - /** - * Abstraction over different types of class path entries. - */ - abstract static class ClassPathEntry implements Closeable { - final String name; - - ClassPathEntry(String name) { - this.name = name; - } - - /** - * Creates a {@link ClassLoader} for loading classes from this entry. - */ - public abstract ClassLoader createClassLoader() throws IOException; - - /** - * Gets the list of classes available under this entry. - */ - public abstract List getClassNames() throws IOException; - - @Override - public String toString() { - return name; - } - - @Override - public void close() throws IOException { - } - } - - /** - * A class path entry that is a normal file system directory. - */ - static class DirClassPathEntry extends ClassPathEntry { - - private final File dir; - - DirClassPathEntry(String name) { - super(name); - dir = new File(name); - assert dir.isDirectory(); - } - - @Override - public ClassLoader createClassLoader() throws IOException { - URL url = dir.toURI().toURL(); - return new URLClassLoader(new URL[]{url}); - } - - @Override - public List getClassNames() throws IOException { - List classNames = new ArrayList<>(); - String root = dir.getPath(); - SimpleFileVisitor visitor = new SimpleFileVisitor() { - @Override - public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException { - if (attrs.isRegularFile()) { - File path = file.toFile(); - if (path.getName().endsWith(".class")) { - String pathString = path.getPath(); - assert pathString.startsWith(root); - String classFile = pathString.substring(root.length() + 1); - String className = classFile.replace(File.separatorChar, '.'); - classNames.add(className.replace('/', '.').substring(0, className.length() - ".class".length())); - } - } - return super.visitFile(file, attrs); - } - }; - Files.walkFileTree(dir.toPath(), visitor); - return classNames; - } - } - - /** - * A class path entry that is a jar or zip file. - */ - static class JarClassPathEntry extends ClassPathEntry { - - private final JarFile jarFile; - - JarClassPathEntry(String name) throws IOException { - super(name); - jarFile = new JarFile(name); - } - - @Override - public ClassLoader createClassLoader() throws IOException { - URL url = new URL("jar", "", "file:" + name + "!/"); - return new URLClassLoader(new URL[]{url}); - } - - @Override - public List getClassNames() throws IOException { - Enumeration e = jarFile.entries(); - List classNames = new ArrayList<>(jarFile.size()); - while (e.hasMoreElements()) { - JarEntry je = e.nextElement(); - if (je.isDirectory() || !je.getName().endsWith(".class")) { - continue; - } - String className = je.getName().substring(0, je.getName().length() - ".class".length()); - classNames.add(className.replace('/', '.')); - } - return classNames; - } - - @Override - public void close() throws IOException { - jarFile.close(); - } - } - - /** - * Name of the property that limits the set of modules processed by CompileTheWorld. - */ - public static final String LIMITMODS_PROPERTY_NAME = "CompileTheWorld.limitmods"; - - /** - * A class path entry that is a jimage file. - */ - static class ImageClassPathEntry extends ClassPathEntry { - - private final File jimage; - - ImageClassPathEntry(String name) { - super(name); - jimage = new File(name); - assert jimage.isFile(); - } - - @Override - public ClassLoader createClassLoader() throws IOException { - URL url = jimage.toURI().toURL(); - return new URLClassLoader(new URL[]{url}); - } - - @Override - public List getClassNames() throws IOException { - String prop = System.getProperty(LIMITMODS_PROPERTY_NAME); - Set limitmods = prop == null ? null : new HashSet<>(Arrays.asList(prop.split(","))); - List classNames = new ArrayList<>(); - String[] entries = readJimageEntries(); - for (String e : entries) { - if (e.endsWith(".class") && !e.endsWith("module-info.class")) { - assert e.charAt(0) == '/' : e; - int endModule = e.indexOf('/', 1); - assert endModule != -1 : e; - if (limitmods != null) { - String module = e.substring(1, endModule); - if (!limitmods.contains(module)) { - continue; - } - } - // Strip the module prefix and convert to dotted form - String className = e.substring(endModule + 1).replace('/', '.'); - // Strip ".class" suffix - className = className.replace('/', '.').substring(0, className.length() - ".class".length()); - classNames.add(className); - } - } - return classNames; - } - - private String[] readJimageEntries() { - try { - // Use reflection so this can be compiled on JDK8 - Path path = FileSystems.getDefault().getPath(name); - Method open = Class.forName("jdk.internal.jimage.BasicImageReader").getDeclaredMethod("open", Path.class); - Object reader = open.invoke(null, path); - Method getEntryNames = reader.getClass().getDeclaredMethod("getEntryNames"); - getEntryNames.setAccessible(true); - String[] entries = (String[]) getEntryNames.invoke(reader); - return entries; - } catch (Exception e) { - TTY.println("Error reading entries from " + name + ": " + e); - return new String[0]; - } - } - } - - /** - * Determines if a given path denotes a jimage file. - * - * @param path file path - * @return {@code true} if the 4 byte integer (in native endianness) at the start of - * {@code path}'s contents is {@code 0xCAFEDADA} - */ - static boolean isJImage(String path) { - try { - FileChannel channel = FileChannel.open(Paths.get(path), StandardOpenOption.READ); - ByteBuffer map = channel.map(FileChannel.MapMode.READ_ONLY, 0, channel.size()); - map.order(ByteOrder.nativeOrder()).asIntBuffer().get(0); - int magic = map.asIntBuffer().get(0); - if (magic == 0xCAFEDADA) { - return true; - } - } catch (IOException e) { - } - return false; - } - - /** - * Compiles all methods in all classes in a given class path. - * - * @param classPath class path denoting classes to compile - * @throws IOException - */ - @SuppressWarnings("try") - private void compile(String classPath) throws IOException { - final String[] entries = classPath.split(File.pathSeparator); - long start = System.currentTimeMillis(); - - try { - // compile dummy method to get compiler initialized outside of the - // config debug override. - HotSpotResolvedJavaMethod dummyMethod = (HotSpotResolvedJavaMethod) JVMCI.getRuntime().getHostJVMCIBackend().getMetaAccess().lookupJavaMethod( - CompileTheWorld.class.getDeclaredMethod("dummy")); - int entryBCI = JVMCICompiler.INVOCATION_ENTRY_BCI; - boolean useProfilingInfo = false; - boolean installAsDefault = false; - CompilationTask task = new CompilationTask(jvmciRuntime, compiler, new HotSpotCompilationRequest(dummyMethod, entryBCI, 0L), useProfilingInfo, installAsDefault, currentOptions); - task.runCompilation(); - } catch (NoSuchMethodException | SecurityException e1) { - printStackTrace(e1); - } - - /* - * Always use a thread pool, even for single threaded mode since it simplifies the use of - * DebugValueThreadFilter to filter on the thread names. - */ - int threadCount = 1; - if (CompileTheWorldOptions.CompileTheWorldMultiThreaded.getValue(currentOptions)) { - threadCount = CompileTheWorldOptions.CompileTheWorldThreads.getValue(currentOptions); - if (threadCount == 0) { - threadCount = Runtime.getRuntime().availableProcessors(); - } - } else { - running = true; - } - - OptionValues savedOptions = currentOptions; - currentOptions = new OptionValues(savedOptions, compilationOptions); - threadPool = new ThreadPoolExecutor(threadCount, threadCount, 0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue(), - new CompilerThreadFactory("CompileTheWorld", new DebugConfigAccess() { - @Override - public GraalDebugConfig getDebugConfig() { - return DebugEnvironment.ensureInitialized(currentOptions, compiler.getGraalRuntime().getHostProviders().getSnippetReflection()); - } - })); - - try { - for (int i = 0; i < entries.length; i++) { - final String entry = entries[i]; - - ClassPathEntry cpe; - if (entry.endsWith(".zip") || entry.endsWith(".jar")) { - cpe = new JarClassPathEntry(entry); - } else if (isJImage(entry)) { - assert !Java8OrEarlier; - cpe = new ImageClassPathEntry(entry); - } else { - if (!new File(entry).isDirectory()) { - println("CompileTheWorld : Skipped classes in " + entry); - println(); - continue; - } - cpe = new DirClassPathEntry(entry); - } - - if (methodFilters == null || methodFilters.length == 0) { - println("CompileTheWorld : Compiling all classes in " + entry); - } else { - String include = Arrays.asList(methodFilters).stream().map(MethodFilter::toString).collect(Collectors.joining(", ")); - println("CompileTheWorld : Compiling all methods in " + entry + " matching one of the following filters: " + include); - } - if (excludeMethodFilters != null && excludeMethodFilters.length > 0) { - String exclude = Arrays.asList(excludeMethodFilters).stream().map(MethodFilter::toString).collect(Collectors.joining(", ")); - println("CompileTheWorld : Excluding all methods matching one of the following filters: " + exclude); - } - println(); - - ClassLoader loader = cpe.createClassLoader(); - - for (String className : cpe.getClassNames()) { - - // Are we done? - if (classFileCounter >= stopAt) { - break; - } - - classFileCounter++; - - if (className.startsWith("jdk.management.") || className.startsWith("jdk.internal.cmm.*")) { - continue; - } - - try { - // Load and initialize class - Class javaClass = Class.forName(className, true, loader); - - // Pre-load all classes in the constant pool. - try { - HotSpotResolvedObjectType objectType = HotSpotResolvedObjectType.fromObjectClass(javaClass); - ConstantPool constantPool = objectType.getConstantPool(); - for (int cpi = 1; cpi < constantPool.length(); cpi++) { - constantPool.loadReferencedType(cpi, Bytecodes.LDC); - } - } catch (Throwable t) { - // If something went wrong during pre-loading we just ignore it. - println("Preloading failed for (%d) %s: %s", classFileCounter, className, t); - } - - /* - * Only check filters after class loading and resolution to mitigate impact - * on reproducibility. - */ - if (methodFilters != null && !MethodFilter.matchesClassName(methodFilters, className)) { - continue; - } - if (excludeMethodFilters != null && MethodFilter.matchesClassName(excludeMethodFilters, className)) { - continue; - } - - // Are we compiling this class? - MetaAccessProvider metaAccess = JVMCI.getRuntime().getHostJVMCIBackend().getMetaAccess(); - if (classFileCounter >= startAt) { - println("CompileTheWorld (%d) : %s", classFileCounter, className); - - // Compile each constructor/method in the class. - for (Constructor constructor : javaClass.getDeclaredConstructors()) { - HotSpotResolvedJavaMethod javaMethod = (HotSpotResolvedJavaMethod) metaAccess.lookupJavaMethod(constructor); - if (canBeCompiled(javaMethod, constructor.getModifiers())) { - compileMethod(javaMethod); - } - } - for (Method method : javaClass.getDeclaredMethods()) { - HotSpotResolvedJavaMethod javaMethod = (HotSpotResolvedJavaMethod) metaAccess.lookupJavaMethod(method); - if (canBeCompiled(javaMethod, method.getModifiers())) { - compileMethod(javaMethod); - } - } - - // Also compile the class initializer if it exists - HotSpotResolvedJavaMethod clinit = (HotSpotResolvedJavaMethod) metaAccess.lookupJavaType(javaClass).getClassInitializer(); - if (clinit != null && canBeCompiled(clinit, clinit.getModifiers())) { - compileMethod(clinit); - } - } - } catch (Throwable t) { - println("CompileTheWorld (%d) : Skipping %s %s", classFileCounter, className, t.toString()); - printStackTrace(t); - } - } - cpe.close(); - } - } finally { - currentOptions = savedOptions; - } - - if (!running) { - startThreads(); - } - int wakeups = 0; - while (threadPool.getCompletedTaskCount() != threadPool.getTaskCount()) { - if (wakeups % 15 == 0) { - TTY.println("CompileTheWorld : Waiting for " + (threadPool.getTaskCount() - threadPool.getCompletedTaskCount()) + " compiles"); - } - try { - threadPool.awaitTermination(1, TimeUnit.SECONDS); - wakeups++; - } catch (InterruptedException e) { - } - } - threadPool = null; - - long elapsedTime = System.currentTimeMillis() - start; - - println(); - if (CompileTheWorldOptions.CompileTheWorldMultiThreaded.getValue(currentOptions)) { - TTY.println("CompileTheWorld : Done (%d classes, %d methods, %d ms elapsed, %d ms compile time, %d bytes of memory used)", classFileCounter, compiledMethodsCounter.get(), elapsedTime, - compileTime.get(), memoryUsed.get()); - } else { - TTY.println("CompileTheWorld : Done (%d classes, %d methods, %d ms, %d bytes of memory used)", classFileCounter, compiledMethodsCounter.get(), compileTime.get(), memoryUsed.get()); - } - } - - private synchronized void startThreads() { - running = true; - // Wake up any waiting threads - notifyAll(); - } - - private synchronized void waitToRun() { - while (!running) { - try { - wait(); - } catch (InterruptedException e) { - } - } - } - - @SuppressWarnings("try") - private void compileMethod(HotSpotResolvedJavaMethod method) throws InterruptedException, ExecutionException { - if (methodFilters != null && !MethodFilter.matches(methodFilters, method)) { - return; - } - if (excludeMethodFilters != null && MethodFilter.matches(excludeMethodFilters, method)) { - return; - } - Future task = threadPool.submit(new Runnable() { - @Override - public void run() { - waitToRun(); - OptionValues savedOptions = currentOptions; - currentOptions = new OptionValues(savedOptions, compilationOptions); - try { - compileMethod(method, classFileCounter); - } finally { - currentOptions = savedOptions; - } - } - }); - if (threadPool.getCorePoolSize() == 1) { - task.get(); - } - } - - /** - * Compiles a method and gathers some statistics. - */ - private void compileMethod(HotSpotResolvedJavaMethod method, int counter) { - try { - long start = System.currentTimeMillis(); - long allocatedAtStart = MemUseTrackerImpl.getCurrentThreadAllocatedBytes(); - int entryBCI = JVMCICompiler.INVOCATION_ENTRY_BCI; - HotSpotCompilationRequest request = new HotSpotCompilationRequest(method, entryBCI, 0L); - // For more stable CTW execution, disable use of profiling information - boolean useProfilingInfo = false; - boolean installAsDefault = false; - CompilationTask task = new CompilationTask(jvmciRuntime, compiler, request, useProfilingInfo, installAsDefault, currentOptions); - task.runCompilation(); - - // Invalidate the generated code so the code cache doesn't fill up - HotSpotInstalledCode installedCode = task.getInstalledCode(); - if (installedCode != null) { - installedCode.invalidate(); - } - - memoryUsed.getAndAdd(MemUseTrackerImpl.getCurrentThreadAllocatedBytes() - allocatedAtStart); - compileTime.getAndAdd(System.currentTimeMillis() - start); - compiledMethodsCounter.incrementAndGet(); - } catch (Throwable t) { - // Catch everything and print a message - println("CompileTheWorld (%d) : Error compiling method: %s", counter, method.format("%H.%n(%p):%r")); - printStackTrace(t); - } - } - - /** - * Determines if a method should be compiled (Cf. CompilationPolicy::can_be_compiled). - * - * @return true if it can be compiled, false otherwise - */ - private boolean canBeCompiled(HotSpotResolvedJavaMethod javaMethod, int modifiers) { - if (Modifier.isAbstract(modifiers) || Modifier.isNative(modifiers)) { - return false; - } - GraalHotSpotVMConfig c = compiler.getGraalRuntime().getVMConfig(); - if (c.dontCompileHugeMethods && javaMethod.getCodeSize() > c.hugeMethodLimit) { - println(verbose || methodFilters != null, - String.format("CompileTheWorld (%d) : Skipping huge method %s (use -XX:-DontCompileHugeMethods or -XX:HugeMethodLimit=%d to include it)", classFileCounter, - javaMethod.format("%H.%n(%p):%r"), - javaMethod.getCodeSize())); - return false; - } - // Allow use of -XX:CompileCommand=dontinline to exclude problematic methods - if (!javaMethod.canBeInlined()) { - return false; - } - // Skip @Snippets for now - for (Annotation annotation : javaMethod.getAnnotations()) { - if (annotation.annotationType().equals(Snippet.class)) { - return false; - } - } - return true; - } - - public static void main(String[] args) throws Throwable { - Services.exportJVMCITo(CompileTheWorld.class); - HotSpotGraalCompiler compiler = (HotSpotGraalCompiler) HotSpotJVMCIRuntime.runtime().getCompiler(); - compiler.compileTheWorld(); - } -} diff -r d5572756efd6 -r ab5b504181d8 hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/CompileTheWorldOptions.java --- a/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/CompileTheWorldOptions.java Tue Apr 18 20:10:55 2017 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,61 +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.hotspot; - -import org.graalvm.compiler.options.Option; -import org.graalvm.compiler.options.OptionType; -import org.graalvm.compiler.options.OptionKey; - -/** - * Options related to {@link CompileTheWorld}. - * - * Note: This must be a top level class to work around for - * Eclipse bug 477597. - */ -public class CompileTheWorldOptions { - // @formatter:off - @Option(help = "Class path denoting methods to compile", type = OptionType.Debug) - public static final OptionKey CompileTheWorldClasspath = new OptionKey<>(CompileTheWorld.SUN_BOOT_CLASS_PATH); - @Option(help = "Verbose CompileTheWorld operation", type = OptionType.Debug) - public static final OptionKey CompileTheWorldVerbose = new OptionKey<>(true); - @Option(help = "The number of CompileTheWorld iterations to perform", type = OptionType.Debug) - public static final OptionKey CompileTheWorldIterations = new OptionKey<>(1); - @Option(help = "Only compile methods matching this filter", type = OptionType.Debug) - public static final OptionKey CompileTheWorldMethodFilter = new OptionKey<>(null); - @Option(help = "Exclude methods matching this filter from compilation", type = OptionType.Debug) - public static final OptionKey CompileTheWorldExcludeMethodFilter = new OptionKey<>(null); - @Option(help = "First class to consider when using -XX:+CompileTheWorld", type = OptionType.Debug) - public static final OptionKey CompileTheWorldStartAt = new OptionKey<>(1); - @Option(help = "Last class to consider when using -XX:+CompileTheWorld", type = OptionType.Debug) - public static final OptionKey CompileTheWorldStopAt = new OptionKey<>(Integer.MAX_VALUE); - @Option(help = "Option value overrides to use during compile the world. For example, " + - "to disable inlining and partial escape analysis specify 'PartialEscapeAnalysis=false Inline=false'. " + - "The format for each option is the same as on the command line just without the '-Dgraal.' prefix.", type = OptionType.Debug) - public static final OptionKey CompileTheWorldConfig = new OptionKey<>(null); - - @Option(help = "Run CTW using as many threads as there are processors on the system", type = OptionType.Debug) - public static final OptionKey CompileTheWorldMultiThreaded = new OptionKey<>(false); - @Option(help = "Number of threads to use for multithreaded CTW. Defaults to Runtime.getRuntime().availableProcessors()", type = OptionType.Debug) - public static final OptionKey CompileTheWorldThreads = new OptionKey<>(0); - // @formatter:on -} diff -r d5572756efd6 -r ab5b504181d8 hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/HotSpotGraalCompiler.java --- a/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/HotSpotGraalCompiler.java Tue Apr 18 20:10:55 2017 -0700 +++ b/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/HotSpotGraalCompiler.java Wed Apr 19 04:10:56 2017 +0000 @@ -39,7 +39,6 @@ import org.graalvm.compiler.debug.DebugConfigScope; import org.graalvm.compiler.debug.DebugEnvironment; import org.graalvm.compiler.debug.GraalDebugConfig; -import org.graalvm.compiler.debug.TTY; import org.graalvm.compiler.debug.TopLevelDebugConfig; import org.graalvm.compiler.debug.internal.method.MethodMetricsRootScopeInfo; import org.graalvm.compiler.hotspot.CompilationCounters.Options; @@ -63,7 +62,6 @@ import jdk.vm.ci.code.CompilationRequest; import jdk.vm.ci.code.CompilationRequestResult; -import jdk.vm.ci.hotspot.HotSpotCodeCacheProvider; import jdk.vm.ci.hotspot.HotSpotCompilationRequest; import jdk.vm.ci.hotspot.HotSpotCompilationRequestResult; import jdk.vm.ci.hotspot.HotSpotJVMCIRuntimeProvider; @@ -135,19 +133,6 @@ } } - public void compileTheWorld() throws Throwable { - HotSpotCodeCacheProvider codeCache = (HotSpotCodeCacheProvider) jvmciRuntime.getHostJVMCIBackend().getCodeCache(); - int iterations = CompileTheWorldOptions.CompileTheWorldIterations.getValue(graalRuntime.getOptions()); - for (int i = 0; i < iterations; i++) { - codeCache.resetCompilationStatistics(); - TTY.println("CompileTheWorld : iteration " + i); - this.graalRuntime.getVMConfig(); - CompileTheWorld ctw = new CompileTheWorld(jvmciRuntime, this, graalRuntime.getOptions()); - ctw.compile(); - } - System.exit(0); - } - public CompilationResult compile(ResolvedJavaMethod method, int entryBCI, boolean useProfilingInfo, CompilationIdentifier compilationId, OptionValues options) { HotSpotBackend backend = graalRuntime.getHostBackend(); HotSpotProviders providers = backend.getProviders(); diff -r d5572756efd6 -r ab5b504181d8 hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/HotSpotGraalOptionValues.java --- a/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/HotSpotGraalOptionValues.java Tue Apr 18 20:10:55 2017 -0700 +++ b/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/HotSpotGraalOptionValues.java Wed Apr 19 04:10:56 2017 +0000 @@ -39,7 +39,6 @@ import org.graalvm.compiler.options.OptionsParser; import org.graalvm.compiler.serviceprovider.ServiceProvider; import org.graalvm.util.EconomicMap; -import org.graalvm.util.MapCursor; import jdk.vm.ci.common.InitTimer; @@ -117,9 +116,8 @@ Properties props = new Properties(); props.load(fr); EconomicMap optionSettings = EconomicMap.create(); - MapCursor cursor = optionSettings.getEntries(); - while (cursor.advance()) { - optionSettings.put(cursor.getKey(), cursor.getValue()); + for (Map.Entry e : props.entrySet()) { + optionSettings.put((String) e.getKey(), (String) e.getValue()); } try { OptionsParser.parseOptions(optionSettings, values, loader); diff -r d5572756efd6 -r ab5b504181d8 hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/HotSpotHostBackend.java --- a/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/HotSpotHostBackend.java Tue Apr 18 20:10:55 2017 -0700 +++ b/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/HotSpotHostBackend.java Wed Apr 19 04:10:56 2017 +0000 @@ -22,9 +22,11 @@ */ package org.graalvm.compiler.hotspot; +import static jdk.vm.ci.code.CodeUtil.K; import static jdk.vm.ci.code.CodeUtil.getCallingConvention; import static jdk.vm.ci.common.InitTimer.timer; +import org.graalvm.compiler.core.common.NumUtil; import org.graalvm.compiler.core.common.spi.ForeignCallDescriptor; import org.graalvm.compiler.hotspot.meta.HotSpotHostForeignCallsProvider; import org.graalvm.compiler.hotspot.meta.HotSpotLoweringProvider; @@ -109,7 +111,7 @@ // is greater than a page. int pageSize = config.vmPageSize; - int bangEnd = config.stackShadowPages * pageSize; + int bangEnd = NumUtil.roundUp(config.stackShadowPages * 4 * K, pageSize); // This is how far the previous frame's stack banging extended. int bangEndSafe = bangEnd; diff -r d5572756efd6 -r ab5b504181d8 hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/NodeCostDumpUtil.java --- /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/NodeCostDumpUtil.java Wed Apr 19 04:10:56 2017 +0000 @@ -0,0 +1,240 @@ +/* + * 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; + +import java.io.File; +import java.io.IOException; +import java.lang.reflect.Field; +import java.net.URI; +import java.net.URL; +import java.net.URLClassLoader; +import java.nio.file.FileSystem; +import java.nio.file.FileSystems; +import java.nio.file.FileVisitResult; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.SimpleFileVisitor; +import java.nio.file.attribute.BasicFileAttributes; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.HashSet; +import java.util.List; +import java.util.Set; +import java.util.regex.Pattern; +import java.util.regex.PatternSyntaxException; +import java.util.stream.Collectors; + +import org.graalvm.compiler.debug.CSVUtil; +import org.graalvm.compiler.debug.GraalError; +import org.graalvm.compiler.graph.Node; +import org.graalvm.compiler.graph.NodeClass; +import org.graalvm.compiler.graph.spi.Canonicalizable; +import org.graalvm.compiler.nodes.memory.MemoryCheckpoint; +import org.graalvm.compiler.nodes.spi.Virtualizable; + +public class NodeCostDumpUtil { + + private static final String prefix1 = "com.oracle."; + private static final String prefix2 = "org.graalvm."; + private static final String FMT = CSVUtil.buildFormatString("%s", "%s", "%s", "%s", "%s", "%s", "%s", "%s"); + + private static String getArgumentRegex(String arg) { + if (arg.length() == 0) { + return null; + } + try { + Pattern.compile(arg); + return arg; + } catch (PatternSyntaxException e) { + // silently ignore + System.err.println("Invalid regex given, defaulting to \".*\" regex.."); + return null; + } + } + + public static void main(String[] args) { + if (args.length != 1) { + System.err.println("NodeCostDumpUtil expects exactly one argument, the node name regex to match against."); + System.exit(-1); + } + final String pattern = getArgumentRegex(args[0]); + String version = System.getProperty("java.specification.version"); + if (version.compareTo("1.9") >= 0) { + System.err.printf("NodeCostDumpUtil does not support JDK versions greater than 1.8, current version is %s.\n", version); + System.exit(-1); + } + String[] jvmciCP = System.getProperty("jvmci.class.path.append").split(File.pathSeparator); + String[] primarySuiteCP = System.getProperty("primary.suite.cp").split(File.pathSeparator); + ClassLoader applicationClassLoader = Thread.currentThread().getContextClassLoader(); + HashSet> classes = new HashSet<>(); + try { + Set uniquePaths = new HashSet<>(Arrays.asList(primarySuiteCP)); + uniquePaths.addAll(Arrays.asList(jvmciCP)); + for (String path : uniquePaths) { + if (new File(path).exists()) { + if (path.endsWith(".jar")) { + try (FileSystem jarFileSystem = FileSystems.newFileSystem(URI.create("jar:file:" + path), Collections.emptyMap())) { + initAllClasses(jarFileSystem.getPath("/"), applicationClassLoader, classes); + } + } else { + initAllClasses(FileSystems.getDefault().getPath(path), applicationClassLoader, classes); + } + } + } + } catch (IOException ex) { + GraalError.shouldNotReachHere(); + } + System.err.printf("Loaded %d classes...\n", classes.size()); + List> nodeClasses = new ArrayList<>(); + for (Class loaded : classes) { + if (Node.class.isAssignableFrom(loaded) && !loaded.isArray()) { + nodeClasses.add(loaded); + } + } + System.err.printf("Loaded %s node classes...\n", nodeClasses.size()); + List> nc = new ArrayList<>(); + for (Class nodeClass : nodeClasses) { + Field f; + try { + f = nodeClass.getField("TYPE"); + f.setAccessible(true); + Object val = f.get(null); + NodeClass nodeType = (NodeClass) val; + nc.add(nodeType); + } catch (Throwable t) { + // Silently ignore problems here + } + } + System.err.printf("Read TYPE field from %s node classes...\n", nc.size()); + nc = nc.stream().filter(x -> x != null).collect(Collectors.toList()); + nc.sort((x, y) -> { + String a = x.getJavaClass().getName(); + String b = y.getJavaClass().getName(); + return a.compareTo(b); + }); + CSVUtil.Escape.println(System.out, FMT, "NodeName", "Size", "Overrides Size Method", "Cycles", "Overrides Cycles Method", "Canonicalizable", "MemoryCheckPoint", "Virtualizable"); + for (NodeClass nodeclass : nc) { + String packageStrippedName = null; + try { + packageStrippedName = nodeclass.getJavaClass().getCanonicalName().replace(prefix1, "").replace(prefix2, ""); + } catch (Throwable t) { + // do nothing + continue; + } + if (pattern != null && !packageStrippedName.matches(pattern)) { + continue; + } + boolean overridesSizeMethod = false; + boolean overridesCyclesMethod = false; + Class c = nodeclass.getJavaClass(); + try { + c.getDeclaredMethod("estimatedNodeSize"); + overridesSizeMethod = true; + } catch (Throwable t) { + // do nothing + } + try { + c.getDeclaredMethod("estimatedNodeCycles"); + overridesCyclesMethod = true; + } catch (Throwable t) { + // do nothing + } + CSVUtil.Escape.println(System.out, FMT, packageStrippedName, nodeclass.size(), overridesSizeMethod, nodeclass.cycles(), overridesCyclesMethod, canonicalizable(c), memoryCheckPoint(c), + virtualizable(c)); + } + } + + private static boolean canonicalizable(Class c) { + return Canonicalizable.class.isAssignableFrom(c); + } + + private static boolean virtualizable(Class c) { + return Virtualizable.class.isAssignableFrom(c); + } + + private static boolean memoryCheckPoint(Class c) { + return MemoryCheckpoint.class.isAssignableFrom(c); + } + + private static void initAllClasses(final Path root, ClassLoader classLoader, HashSet> classes) { + try { + Files.walkFileTree(root, new SimpleFileVisitor() { + @Override + public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException { + String className = root.relativize(file).toString(); + ClassLoader c = classLoader; + if (className.endsWith(".class")) { + String prefix = prefixed(className); + if (prefix != null) { + String stripped = stripClassName(className); + c = new URLClassLoader(new URL[]{new File(constructURLPart(stripped, className, prefix)).toURI().toURL()}, classLoader); + className = constructClazzPart(stripped, prefix); + } else { + String clazzPart = className.replace('/', '.'); + className = clazzPart.substring(0, clazzPart.length() - ".class".length()); + } + try { + Class systemClass = Class.forName(className, false, c); + if (systemClass.getEnclosingClass() != null) { + try { + classes.add(systemClass.getEnclosingClass()); + } catch (Throwable t) { + // do nothing + } + } + classes.add(systemClass); + } catch (Throwable ignored) { + } + } + return FileVisitResult.CONTINUE; + } + }); + } catch (IOException ex) { + GraalError.shouldNotReachHere(); + } + } + + private static String prefixed(String className) { + if (className.contains(prefix1) && className.indexOf(prefix1) > 0) { + return prefix1; + } else if (className.contains(prefix2) && className.indexOf(prefix2) > 0) { + return prefix2; + } + return null; + } + + private static String stripClassName(String className) { + return className.replace('/', '.'); + } + + private static String constructClazzPart(String stripped, String prefix) { + String clazzPart = stripped.substring(stripped.lastIndexOf(prefix), stripped.length()); + return clazzPart.substring(0, clazzPart.length() - ".class".length()); + } + + private static String constructURLPart(String stripped, String className, String prefix) { + return className.substring(0, stripped.lastIndexOf(prefix)); + } + +} diff -r d5572756efd6 -r ab5b504181d8 hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/meta/HotSpotGraphBuilderPlugins.java --- a/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/meta/HotSpotGraphBuilderPlugins.java Tue Apr 18 20:10:55 2017 -0700 +++ b/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/meta/HotSpotGraphBuilderPlugins.java Wed Apr 19 04:10:56 2017 +0000 @@ -252,7 +252,7 @@ @Override public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver receiver, ValueNode object) { ValueNode javaClass = receiver.get(); - LogicNode condition = b.recursiveAppend(InstanceOfDynamicNode.create(b.getAssumptions(), b.getConstantReflection(), javaClass, object, true)); + LogicNode condition = b.append(InstanceOfDynamicNode.create(b.getAssumptions(), b.getConstantReflection(), javaClass, object, true)); if (condition.isTautology()) { b.addPush(JavaKind.Object, object); } else { diff -r d5572756efd6 -r ab5b504181d8 hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/meta/HotSpotProviders.java --- a/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/meta/HotSpotProviders.java Tue Apr 18 20:10:55 2017 -0700 +++ b/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/meta/HotSpotProviders.java Wed Apr 19 04:10:56 2017 +0000 @@ -27,7 +27,6 @@ import org.graalvm.compiler.hotspot.word.HotSpotWordTypes; import org.graalvm.compiler.nodes.graphbuilderconf.GraphBuilderConfiguration.Plugins; import org.graalvm.compiler.nodes.spi.LoweringProvider; -import org.graalvm.compiler.nodes.spi.NodeCostProvider; import org.graalvm.compiler.nodes.spi.Replacements; import org.graalvm.compiler.phases.tiers.SuitesProvider; import org.graalvm.compiler.phases.util.Providers; @@ -49,10 +48,10 @@ private final Plugins graphBuilderPlugins; public HotSpotProviders(MetaAccessProvider metaAccess, HotSpotCodeCacheProvider codeCache, ConstantReflectionProvider constantReflection, ConstantFieldProvider constantField, - HotSpotForeignCallsProvider foreignCalls, LoweringProvider lowerer, Replacements replacements, NodeCostProvider nodeCostProvider, SuitesProvider suites, + HotSpotForeignCallsProvider foreignCalls, LoweringProvider lowerer, Replacements replacements, SuitesProvider suites, HotSpotRegistersProvider registers, SnippetReflectionProvider snippetReflection, HotSpotWordTypes wordTypes, Plugins graphBuilderPlugins) { - super(metaAccess, codeCache, constantReflection, constantField, foreignCalls, lowerer, replacements, new HotSpotStampProvider(), nodeCostProvider); + super(metaAccess, codeCache, constantReflection, constantField, foreignCalls, lowerer, replacements, new HotSpotStampProvider()); this.suites = suites; this.registers = registers; this.snippetReflection = snippetReflection; diff -r d5572756efd6 -r ab5b504181d8 hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/meta/HotSpotWordOperationPlugin.java --- a/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/meta/HotSpotWordOperationPlugin.java Tue Apr 18 20:10:55 2017 -0700 +++ b/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/meta/HotSpotWordOperationPlugin.java Wed Apr 19 04:10:56 2017 +0000 @@ -117,7 +117,7 @@ ValueNode pointer = args[0]; assert pointer.stamp() instanceof MetaspacePointerStamp; - LogicNode isNull = b.add(IsNullNode.create(pointer)); + LogicNode isNull = b.addWithInputs(IsNullNode.create(pointer)); b.addPush(returnKind, ConditionalNode.create(isNull, b.add(forBoolean(true)), b.add(forBoolean(false)))); break; diff -r d5572756efd6 -r ab5b504181d8 hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/nodes/ComputeObjectAddressNode.java --- a/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/nodes/ComputeObjectAddressNode.java Tue Apr 18 20:10:55 2017 -0700 +++ b/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/nodes/ComputeObjectAddressNode.java Wed Apr 19 04:10:56 2017 +0000 @@ -22,12 +22,12 @@ */ package org.graalvm.compiler.hotspot.nodes; -import static org.graalvm.compiler.nodeinfo.NodeCycles.CYCLES_3; -import static org.graalvm.compiler.nodeinfo.NodeSize.SIZE_2; +import static org.graalvm.compiler.nodeinfo.NodeCycles.CYCLES_1; import org.graalvm.compiler.core.common.type.StampFactory; import org.graalvm.compiler.graph.NodeClass; import org.graalvm.compiler.nodeinfo.NodeInfo; +import org.graalvm.compiler.nodeinfo.NodeSize; import org.graalvm.compiler.nodes.FixedWithNextNode; import org.graalvm.compiler.nodes.ValueNode; import org.graalvm.compiler.nodes.debug.ControlFlowAnchored; @@ -40,7 +40,7 @@ * A high-level intrinsic for getting an address inside of an object. During lowering it will be * moved next to any uses to avoid creating a derived pointer that is live across a safepoint. */ -@NodeInfo(cycles = CYCLES_3, size = SIZE_2) +@NodeInfo(cycles = CYCLES_1, size = NodeSize.SIZE_1) public final class ComputeObjectAddressNode extends FixedWithNextNode implements Lowerable, ControlFlowAnchored { public static final NodeClass TYPE = NodeClass.create(ComputeObjectAddressNode.class); diff -r d5572756efd6 -r ab5b504181d8 hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/nodes/DeoptimizeCallerNode.java --- a/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/nodes/DeoptimizeCallerNode.java Tue Apr 18 20:10:55 2017 -0700 +++ b/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/nodes/DeoptimizeCallerNode.java Wed Apr 19 04:10:56 2017 +0000 @@ -22,8 +22,8 @@ */ package org.graalvm.compiler.hotspot.nodes; -import static org.graalvm.compiler.nodeinfo.NodeCycles.CYCLES_1; -import static org.graalvm.compiler.nodeinfo.NodeSize.SIZE_3; +import static org.graalvm.compiler.nodeinfo.NodeCycles.CYCLES_8; +import static org.graalvm.compiler.nodeinfo.NodeSize.SIZE_8; import org.graalvm.compiler.core.common.type.StampFactory; import org.graalvm.compiler.graph.NodeClass; @@ -39,7 +39,7 @@ /** * Removes the current frame and tail calls the uncommon trap routine. */ -@NodeInfo(shortName = "DeoptCaller", nameTemplate = "DeoptCaller {p#reason/s}", cycles = CYCLES_1, size = SIZE_3) +@NodeInfo(shortName = "DeoptCaller", nameTemplate = "DeoptCaller {p#reason/s}", cycles = CYCLES_8, size = SIZE_8) public final class DeoptimizeCallerNode extends ControlSinkNode implements LIRLowerable { public static final NodeClass TYPE = NodeClass.create(DeoptimizeCallerNode.class); diff -r d5572756efd6 -r ab5b504181d8 hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/nodes/G1ArrayRangePostWriteBarrier.java --- a/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/nodes/G1ArrayRangePostWriteBarrier.java Tue Apr 18 20:10:55 2017 -0700 +++ b/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/nodes/G1ArrayRangePostWriteBarrier.java Wed Apr 19 04:10:56 2017 +0000 @@ -22,14 +22,14 @@ */ package org.graalvm.compiler.hotspot.nodes; -import static org.graalvm.compiler.nodeinfo.NodeCycles.CYCLES_100; -import static org.graalvm.compiler.nodeinfo.NodeSize.SIZE_100; +import static org.graalvm.compiler.nodeinfo.NodeCycles.CYCLES_64; +import static org.graalvm.compiler.nodeinfo.NodeSize.SIZE_64; import org.graalvm.compiler.graph.NodeClass; import org.graalvm.compiler.nodeinfo.NodeInfo; import org.graalvm.compiler.nodes.ValueNode; -@NodeInfo(cycles = CYCLES_100, size = SIZE_100) +@NodeInfo(cycles = CYCLES_64, size = SIZE_64) public class G1ArrayRangePostWriteBarrier extends ArrayRangeWriteBarrier { public static final NodeClass TYPE = NodeClass.create(G1ArrayRangePostWriteBarrier.class); diff -r d5572756efd6 -r ab5b504181d8 hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/nodes/G1ArrayRangePreWriteBarrier.java --- a/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/nodes/G1ArrayRangePreWriteBarrier.java Tue Apr 18 20:10:55 2017 -0700 +++ b/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/nodes/G1ArrayRangePreWriteBarrier.java Wed Apr 19 04:10:56 2017 +0000 @@ -22,14 +22,14 @@ */ package org.graalvm.compiler.hotspot.nodes; -import static org.graalvm.compiler.nodeinfo.NodeCycles.CYCLES_100; -import static org.graalvm.compiler.nodeinfo.NodeSize.SIZE_100; +import static org.graalvm.compiler.nodeinfo.NodeCycles.CYCLES_64; +import static org.graalvm.compiler.nodeinfo.NodeSize.SIZE_64; import org.graalvm.compiler.graph.NodeClass; import org.graalvm.compiler.nodeinfo.NodeInfo; import org.graalvm.compiler.nodes.ValueNode; -@NodeInfo(cycles = CYCLES_100, size = SIZE_100) +@NodeInfo(cycles = CYCLES_64, size = SIZE_64) public final class G1ArrayRangePreWriteBarrier extends ArrayRangeWriteBarrier { public static final NodeClass TYPE = NodeClass.create(G1ArrayRangePreWriteBarrier.class); diff -r d5572756efd6 -r ab5b504181d8 hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/nodes/G1PostWriteBarrier.java --- a/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/nodes/G1PostWriteBarrier.java Tue Apr 18 20:10:55 2017 -0700 +++ b/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/nodes/G1PostWriteBarrier.java Wed Apr 19 04:10:56 2017 +0000 @@ -22,15 +22,15 @@ */ package org.graalvm.compiler.hotspot.nodes; -import static org.graalvm.compiler.nodeinfo.NodeCycles.CYCLES_50; -import static org.graalvm.compiler.nodeinfo.NodeSize.SIZE_50; +import static org.graalvm.compiler.nodeinfo.NodeCycles.CYCLES_64; +import static org.graalvm.compiler.nodeinfo.NodeSize.SIZE_64; import org.graalvm.compiler.graph.NodeClass; import org.graalvm.compiler.nodeinfo.NodeInfo; import org.graalvm.compiler.nodes.ValueNode; import org.graalvm.compiler.nodes.memory.address.AddressNode; -@NodeInfo(cycles = CYCLES_50, size = SIZE_50) +@NodeInfo(cycles = CYCLES_64, size = SIZE_64) public class G1PostWriteBarrier extends ObjectWriteBarrier { public static final NodeClass TYPE = NodeClass.create(G1PostWriteBarrier.class); diff -r d5572756efd6 -r ab5b504181d8 hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/nodes/G1PreWriteBarrier.java --- a/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/nodes/G1PreWriteBarrier.java Tue Apr 18 20:10:55 2017 -0700 +++ b/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/nodes/G1PreWriteBarrier.java Wed Apr 19 04:10:56 2017 +0000 @@ -22,8 +22,8 @@ */ package org.graalvm.compiler.hotspot.nodes; -import static org.graalvm.compiler.nodeinfo.NodeCycles.CYCLES_50; -import static org.graalvm.compiler.nodeinfo.NodeSize.SIZE_50; +import static org.graalvm.compiler.nodeinfo.NodeCycles.CYCLES_64; +import static org.graalvm.compiler.nodeinfo.NodeSize.SIZE_64; import org.graalvm.compiler.graph.NodeClass; import org.graalvm.compiler.nodeinfo.InputType; @@ -33,7 +33,7 @@ import org.graalvm.compiler.nodes.ValueNode; import org.graalvm.compiler.nodes.memory.address.AddressNode; -@NodeInfo(cycles = CYCLES_50, size = SIZE_50) +@NodeInfo(cycles = CYCLES_64, size = SIZE_64) public final class G1PreWriteBarrier extends ObjectWriteBarrier implements DeoptimizingNode.DeoptBefore { public static final NodeClass TYPE = NodeClass.create(G1PreWriteBarrier.class); diff -r d5572756efd6 -r ab5b504181d8 hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/nodes/G1ReferentFieldReadBarrier.java --- a/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/nodes/G1ReferentFieldReadBarrier.java Tue Apr 18 20:10:55 2017 -0700 +++ b/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/nodes/G1ReferentFieldReadBarrier.java Wed Apr 19 04:10:56 2017 +0000 @@ -22,8 +22,8 @@ */ package org.graalvm.compiler.hotspot.nodes; -import static org.graalvm.compiler.nodeinfo.NodeCycles.CYCLES_50; -import static org.graalvm.compiler.nodeinfo.NodeSize.SIZE_50; +import static org.graalvm.compiler.nodeinfo.NodeCycles.CYCLES_64; +import static org.graalvm.compiler.nodeinfo.NodeSize.SIZE_64; import org.graalvm.compiler.graph.NodeClass; import org.graalvm.compiler.nodeinfo.NodeInfo; @@ -36,7 +36,7 @@ * {@code UnsafeLoadNode}). The return value of the read is passed to the snippet implementing the * read barrier and consequently is added to the SATB queue if the concurrent marker is enabled. */ -@NodeInfo(cycles = CYCLES_50, size = SIZE_50) +@NodeInfo(cycles = CYCLES_64, size = SIZE_64) public final class G1ReferentFieldReadBarrier extends ObjectWriteBarrier { public static final NodeClass TYPE = NodeClass.create(G1ReferentFieldReadBarrier.class); diff -r d5572756efd6 -r ab5b504181d8 hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/nodes/HotSpotNodeCostProvider.java --- a/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/nodes/HotSpotNodeCostProvider.java Tue Apr 18 20:10:55 2017 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,71 +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.nodes; - -import static org.graalvm.compiler.nodeinfo.NodeCycles.CYCLES_20; -import static org.graalvm.compiler.nodeinfo.NodeCycles.CYCLES_30; -import static org.graalvm.compiler.nodeinfo.NodeSize.SIZE_20; -import static org.graalvm.compiler.nodeinfo.NodeSize.SIZE_30; - -import org.graalvm.compiler.graph.Node; -import org.graalvm.compiler.hotspot.replacements.ObjectCloneNode; -import org.graalvm.compiler.nodeinfo.NodeCycles; -import org.graalvm.compiler.nodeinfo.NodeSize; -import org.graalvm.compiler.nodes.spi.DefaultNodeCostProvider; -import org.graalvm.compiler.nodes.type.StampTool; - -import jdk.vm.ci.meta.ResolvedJavaType; - -public abstract class HotSpotNodeCostProvider extends DefaultNodeCostProvider { - - @Override - public NodeSize size(Node n) { - if (n instanceof ObjectCloneNode) { - ResolvedJavaType type = StampTool.typeOrNull(((ObjectCloneNode) n).getObject()); - if (type != null) { - if (type.isArray()) { - return SIZE_30; - } else { - return SIZE_20; - } - } - } - return super.size(n); - } - - @Override - public NodeCycles cycles(Node n) { - if (n instanceof ObjectCloneNode) { - ResolvedJavaType type = StampTool.typeOrNull(((ObjectCloneNode) n).getObject()); - if (type != null) { - if (type.isArray()) { - return CYCLES_30; - } else { - return CYCLES_20; - } - } - } - return super.cycles(n); - } - -} diff -r d5572756efd6 -r ab5b504181d8 hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/nodes/JumpToExceptionHandlerInCallerNode.java --- a/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/nodes/JumpToExceptionHandlerInCallerNode.java Tue Apr 18 20:10:55 2017 -0700 +++ b/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/nodes/JumpToExceptionHandlerInCallerNode.java Wed Apr 19 04:10:56 2017 +0000 @@ -22,7 +22,7 @@ */ package org.graalvm.compiler.hotspot.nodes; -import static org.graalvm.compiler.nodeinfo.NodeCycles.CYCLES_15; +import static org.graalvm.compiler.nodeinfo.NodeCycles.CYCLES_8; import static org.graalvm.compiler.nodeinfo.NodeSize.SIZE_8; import org.graalvm.compiler.core.common.type.StampFactory; @@ -40,7 +40,7 @@ * Sets up the {@linkplain HotSpotBackend#EXCEPTION_HANDLER_IN_CALLER arguments} expected by an * exception handler in the caller's frame, removes the current frame and jumps to said handler. */ -@NodeInfo(cycles = CYCLES_15, size = SIZE_8) +@NodeInfo(cycles = CYCLES_8, size = SIZE_8) public final class JumpToExceptionHandlerInCallerNode extends ControlSinkNode implements LIRLowerable { public static final NodeClass TYPE = NodeClass.create(JumpToExceptionHandlerInCallerNode.class); diff -r d5572756efd6 -r ab5b504181d8 hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/nodes/JumpToExceptionHandlerNode.java --- a/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/nodes/JumpToExceptionHandlerNode.java Tue Apr 18 20:10:55 2017 -0700 +++ b/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/nodes/JumpToExceptionHandlerNode.java Wed Apr 19 04:10:56 2017 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 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 diff -r d5572756efd6 -r ab5b504181d8 hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/nodes/SerialArrayRangeWriteBarrier.java --- a/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/nodes/SerialArrayRangeWriteBarrier.java Tue Apr 18 20:10:55 2017 -0700 +++ b/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/nodes/SerialArrayRangeWriteBarrier.java Wed Apr 19 04:10:56 2017 +0000 @@ -22,14 +22,14 @@ */ package org.graalvm.compiler.hotspot.nodes; -import static org.graalvm.compiler.nodeinfo.NodeCycles.CYCLES_15; -import static org.graalvm.compiler.nodeinfo.NodeSize.SIZE_20; +import static org.graalvm.compiler.nodeinfo.NodeCycles.CYCLES_8; +import static org.graalvm.compiler.nodeinfo.NodeSize.SIZE_8; import org.graalvm.compiler.graph.NodeClass; import org.graalvm.compiler.nodeinfo.NodeInfo; import org.graalvm.compiler.nodes.ValueNode; -@NodeInfo(cycles = CYCLES_15, size = SIZE_20) +@NodeInfo(cycles = CYCLES_8, size = SIZE_8) public final class SerialArrayRangeWriteBarrier extends ArrayRangeWriteBarrier { public static final NodeClass TYPE = NodeClass.create(SerialArrayRangeWriteBarrier.class); diff -r d5572756efd6 -r ab5b504181d8 hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/nodes/SerialWriteBarrier.java --- a/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/nodes/SerialWriteBarrier.java Tue Apr 18 20:10:55 2017 -0700 +++ b/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/nodes/SerialWriteBarrier.java Wed Apr 19 04:10:56 2017 +0000 @@ -23,13 +23,13 @@ package org.graalvm.compiler.hotspot.nodes; import static org.graalvm.compiler.nodeinfo.NodeCycles.CYCLES_8; -import static org.graalvm.compiler.nodeinfo.NodeSize.SIZE_3; +import static org.graalvm.compiler.nodeinfo.NodeSize.SIZE_4; import org.graalvm.compiler.graph.NodeClass; import org.graalvm.compiler.nodeinfo.NodeInfo; import org.graalvm.compiler.nodes.memory.address.AddressNode; -@NodeInfo(cycles = CYCLES_8, size = SIZE_3) +@NodeInfo(cycles = CYCLES_8, size = SIZE_4) public class SerialWriteBarrier extends ObjectWriteBarrier { public static final NodeClass TYPE = NodeClass.create(SerialWriteBarrier.class); diff -r d5572756efd6 -r ab5b504181d8 hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/nodes/aot/EncodedSymbolNode.java --- a/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/nodes/aot/EncodedSymbolNode.java Tue Apr 18 20:10:55 2017 -0700 +++ b/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/nodes/aot/EncodedSymbolNode.java Wed Apr 19 04:10:56 2017 +0000 @@ -22,6 +22,9 @@ */ package org.graalvm.compiler.hotspot.nodes.aot; +import static org.graalvm.compiler.nodeinfo.NodeCycles.CYCLES_IGNORED; +import static org.graalvm.compiler.nodeinfo.NodeSize.SIZE_IGNORED; + import org.graalvm.compiler.core.common.type.Stamp; import org.graalvm.compiler.core.common.type.StampFactory; import org.graalvm.compiler.graph.Node; @@ -38,7 +41,7 @@ import jdk.vm.ci.meta.Constant; -@NodeInfo +@NodeInfo(cycles = CYCLES_IGNORED, size = SIZE_IGNORED) public final class EncodedSymbolNode extends FloatingNode implements Canonicalizable { public static final NodeClass TYPE = NodeClass.create(EncodedSymbolNode.class); diff -r d5572756efd6 -r ab5b504181d8 hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/nodes/aot/InitializeKlassNode.java --- a/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/nodes/aot/InitializeKlassNode.java Tue Apr 18 20:10:55 2017 -0700 +++ b/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/nodes/aot/InitializeKlassNode.java Wed Apr 19 04:10:56 2017 +0000 @@ -22,8 +22,8 @@ */ package org.graalvm.compiler.hotspot.nodes.aot; -import static org.graalvm.compiler.nodeinfo.NodeCycles.CYCLES_3; -import static org.graalvm.compiler.nodeinfo.NodeSize.SIZE_20; +import static org.graalvm.compiler.nodeinfo.NodeCycles.CYCLES_4; +import static org.graalvm.compiler.nodeinfo.NodeSize.SIZE_16; import org.graalvm.compiler.graph.NodeClass; import org.graalvm.compiler.nodeinfo.NodeInfo; @@ -32,7 +32,7 @@ import org.graalvm.compiler.nodes.spi.Lowerable; import org.graalvm.compiler.nodes.spi.LoweringTool; -@NodeInfo(cycles = CYCLES_3, size = SIZE_20) +@NodeInfo(cycles = CYCLES_4, size = SIZE_16) public class InitializeKlassNode extends DeoptimizingFixedWithNextNode implements Lowerable { public static final NodeClass TYPE = NodeClass.create(InitializeKlassNode.class); diff -r d5572756efd6 -r ab5b504181d8 hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/nodes/aot/InitializeKlassStubCall.java --- a/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/nodes/aot/InitializeKlassStubCall.java Tue Apr 18 20:10:55 2017 -0700 +++ b/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/nodes/aot/InitializeKlassStubCall.java Wed Apr 19 04:10:56 2017 +0000 @@ -23,7 +23,7 @@ package org.graalvm.compiler.hotspot.nodes.aot; import static org.graalvm.compiler.nodeinfo.NodeCycles.CYCLES_UNKNOWN; -import static org.graalvm.compiler.nodeinfo.NodeSize.SIZE_20; +import static org.graalvm.compiler.nodeinfo.NodeSize.SIZE_16; import org.graalvm.compiler.core.common.LocationIdentity; import org.graalvm.compiler.graph.Node; @@ -51,7 +51,7 @@ /** * A call to the VM via a regular stub. */ -@NodeInfo(allowedUsageTypes = {InputType.Memory}, cycles = CYCLES_UNKNOWN, size = SIZE_20) +@NodeInfo(allowedUsageTypes = {InputType.Memory}, cycles = CYCLES_UNKNOWN, size = SIZE_16) public class InitializeKlassStubCall extends AbstractMemoryCheckpoint implements LIRLowerable, Canonicalizable, DeoptimizingNode.DeoptBefore, MemoryCheckpoint.Single { public static final NodeClass TYPE = NodeClass.create(InitializeKlassStubCall.class); diff -r d5572756efd6 -r ab5b504181d8 hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/nodes/aot/LoadConstantIndirectlyFixedNode.java --- a/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/nodes/aot/LoadConstantIndirectlyFixedNode.java Tue Apr 18 20:10:55 2017 -0700 +++ b/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/nodes/aot/LoadConstantIndirectlyFixedNode.java Wed Apr 19 04:10:56 2017 +0000 @@ -22,8 +22,8 @@ */ package org.graalvm.compiler.hotspot.nodes.aot; -import static org.graalvm.compiler.nodeinfo.NodeCycles.CYCLES_3; -import static org.graalvm.compiler.nodeinfo.NodeSize.SIZE_3; +import static org.graalvm.compiler.nodeinfo.NodeCycles.CYCLES_4; +import static org.graalvm.compiler.nodeinfo.NodeSize.SIZE_1; import org.graalvm.compiler.core.common.PermanentBailoutException; import org.graalvm.compiler.graph.Node; @@ -46,7 +46,7 @@ import jdk.vm.ci.meta.Constant; import jdk.vm.ci.meta.Value; -@NodeInfo(cycles = CYCLES_3, size = SIZE_3) +@NodeInfo(cycles = CYCLES_4, size = SIZE_1) public class LoadConstantIndirectlyFixedNode extends FixedWithNextNode implements Canonicalizable, LIRLowerable { public static final NodeClass TYPE = NodeClass.create(LoadConstantIndirectlyFixedNode.class); diff -r d5572756efd6 -r ab5b504181d8 hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/nodes/aot/LoadConstantIndirectlyNode.java --- a/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/nodes/aot/LoadConstantIndirectlyNode.java Tue Apr 18 20:10:55 2017 -0700 +++ b/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/nodes/aot/LoadConstantIndirectlyNode.java Wed Apr 19 04:10:56 2017 +0000 @@ -22,8 +22,8 @@ */ package org.graalvm.compiler.hotspot.nodes.aot; -import static org.graalvm.compiler.nodeinfo.NodeCycles.CYCLES_3; -import static org.graalvm.compiler.nodeinfo.NodeSize.SIZE_3; +import static org.graalvm.compiler.nodeinfo.NodeCycles.CYCLES_4; +import static org.graalvm.compiler.nodeinfo.NodeSize.SIZE_1; import org.graalvm.compiler.core.common.PermanentBailoutException; import org.graalvm.compiler.graph.Node; @@ -45,7 +45,7 @@ import jdk.vm.ci.meta.Constant; import jdk.vm.ci.meta.Value; -@NodeInfo(cycles = CYCLES_3, size = SIZE_3) +@NodeInfo(cycles = CYCLES_4, size = SIZE_1) public class LoadConstantIndirectlyNode extends FloatingNode implements Canonicalizable, LIRLowerable { public static final NodeClass TYPE = NodeClass.create(LoadConstantIndirectlyNode.class); diff -r d5572756efd6 -r ab5b504181d8 hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/nodes/aot/LoadMethodCountersIndirectlyNode.java --- a/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/nodes/aot/LoadMethodCountersIndirectlyNode.java Tue Apr 18 20:10:55 2017 -0700 +++ b/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/nodes/aot/LoadMethodCountersIndirectlyNode.java Wed Apr 19 04:10:56 2017 +0000 @@ -22,8 +22,8 @@ */ package org.graalvm.compiler.hotspot.nodes.aot; -import static org.graalvm.compiler.nodeinfo.NodeCycles.CYCLES_3; -import static org.graalvm.compiler.nodeinfo.NodeSize.SIZE_3; +import static org.graalvm.compiler.nodeinfo.NodeCycles.CYCLES_4; +import static org.graalvm.compiler.nodeinfo.NodeSize.SIZE_4; import org.graalvm.compiler.core.common.PermanentBailoutException; import org.graalvm.compiler.graph.Node; @@ -46,7 +46,7 @@ import jdk.vm.ci.meta.Constant; import jdk.vm.ci.meta.Value; -@NodeInfo(cycles = CYCLES_3, size = SIZE_3) +@NodeInfo(cycles = CYCLES_4, size = SIZE_4) public class LoadMethodCountersIndirectlyNode extends FloatingNode implements Canonicalizable, LIRLowerable { public static final NodeClass TYPE = NodeClass.create(LoadMethodCountersIndirectlyNode.class); diff -r d5572756efd6 -r ab5b504181d8 hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/nodes/aot/LoadMethodCountersNode.java --- a/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/nodes/aot/LoadMethodCountersNode.java Tue Apr 18 20:10:55 2017 -0700 +++ b/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/nodes/aot/LoadMethodCountersNode.java Wed Apr 19 04:10:56 2017 +0000 @@ -22,10 +22,8 @@ */ package org.graalvm.compiler.hotspot.nodes.aot; -import jdk.vm.ci.meta.ResolvedJavaMethod; - -import static org.graalvm.compiler.nodeinfo.NodeCycles.CYCLES_3; -import static org.graalvm.compiler.nodeinfo.NodeSize.SIZE_3; +import static org.graalvm.compiler.nodeinfo.NodeCycles.CYCLES_4; +import static org.graalvm.compiler.nodeinfo.NodeSize.SIZE_4; import org.graalvm.compiler.debug.GraalError; import org.graalvm.compiler.graph.NodeClass; @@ -37,7 +35,9 @@ import org.graalvm.compiler.nodes.spi.LIRLowerable; import org.graalvm.compiler.nodes.spi.NodeLIRBuilderTool; -@NodeInfo(cycles = CYCLES_3, size = SIZE_3) +import jdk.vm.ci.meta.ResolvedJavaMethod; + +@NodeInfo(cycles = CYCLES_4, size = SIZE_4) public class LoadMethodCountersNode extends FloatingNode implements LIRLowerable { public static final NodeClass TYPE = NodeClass.create(LoadMethodCountersNode.class); diff -r d5572756efd6 -r ab5b504181d8 hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/nodes/aot/ResolveConstantNode.java --- a/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/nodes/aot/ResolveConstantNode.java Tue Apr 18 20:10:55 2017 -0700 +++ b/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/nodes/aot/ResolveConstantNode.java Wed Apr 19 04:10:56 2017 +0000 @@ -22,8 +22,8 @@ */ package org.graalvm.compiler.hotspot.nodes.aot; -import static org.graalvm.compiler.nodeinfo.NodeCycles.CYCLES_3; -import static org.graalvm.compiler.nodeinfo.NodeSize.SIZE_20; +import static org.graalvm.compiler.nodeinfo.NodeCycles.CYCLES_4; +import static org.graalvm.compiler.nodeinfo.NodeSize.SIZE_16; import org.graalvm.compiler.graph.NodeClass; import org.graalvm.compiler.hotspot.meta.HotSpotConstantLoadAction; @@ -33,7 +33,7 @@ import org.graalvm.compiler.nodes.spi.Lowerable; import org.graalvm.compiler.nodes.spi.LoweringTool; -@NodeInfo(cycles = CYCLES_3, size = SIZE_20) +@NodeInfo(cycles = CYCLES_4, size = SIZE_16) public class ResolveConstantNode extends FloatingNode implements Lowerable { public static final NodeClass TYPE = NodeClass.create(ResolveConstantNode.class); diff -r d5572756efd6 -r ab5b504181d8 hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/nodes/aot/ResolveConstantStubCall.java --- a/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/nodes/aot/ResolveConstantStubCall.java Tue Apr 18 20:10:55 2017 -0700 +++ b/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/nodes/aot/ResolveConstantStubCall.java Wed Apr 19 04:10:56 2017 +0000 @@ -23,7 +23,7 @@ package org.graalvm.compiler.hotspot.nodes.aot; import static org.graalvm.compiler.nodeinfo.NodeCycles.CYCLES_UNKNOWN; -import static org.graalvm.compiler.nodeinfo.NodeSize.SIZE_20; +import static org.graalvm.compiler.nodeinfo.NodeSize.SIZE_16; import org.graalvm.compiler.core.common.PermanentBailoutException; import org.graalvm.compiler.graph.Node; @@ -49,7 +49,7 @@ /** * A call to the VM via a regular stub. */ -@NodeInfo(cycles = CYCLES_UNKNOWN, size = SIZE_20) +@NodeInfo(cycles = CYCLES_UNKNOWN, size = SIZE_16) public class ResolveConstantStubCall extends DeoptimizingStubCall implements Canonicalizable, LIRLowerable { public static final NodeClass TYPE = NodeClass.create(ResolveConstantStubCall.class); diff -r d5572756efd6 -r ab5b504181d8 hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/nodes/aot/ResolveMethodAndLoadCountersNode.java --- a/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/nodes/aot/ResolveMethodAndLoadCountersNode.java Tue Apr 18 20:10:55 2017 -0700 +++ b/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/nodes/aot/ResolveMethodAndLoadCountersNode.java Wed Apr 19 04:10:56 2017 +0000 @@ -22,10 +22,8 @@ */ package org.graalvm.compiler.hotspot.nodes.aot; -import jdk.vm.ci.meta.ResolvedJavaMethod; - -import static org.graalvm.compiler.nodeinfo.NodeCycles.CYCLES_3; -import static org.graalvm.compiler.nodeinfo.NodeSize.SIZE_20; +import static org.graalvm.compiler.nodeinfo.NodeCycles.CYCLES_4; +import static org.graalvm.compiler.nodeinfo.NodeSize.SIZE_16; import org.graalvm.compiler.graph.NodeClass; import org.graalvm.compiler.hotspot.nodes.type.MethodCountersPointerStamp; @@ -35,7 +33,9 @@ import org.graalvm.compiler.nodes.spi.Lowerable; import org.graalvm.compiler.nodes.spi.LoweringTool; -@NodeInfo(cycles = CYCLES_3, size = SIZE_20) +import jdk.vm.ci.meta.ResolvedJavaMethod; + +@NodeInfo(cycles = CYCLES_4, size = SIZE_16) public class ResolveMethodAndLoadCountersNode extends FloatingNode implements Lowerable { public static final NodeClass TYPE = NodeClass.create(ResolveMethodAndLoadCountersNode.class); diff -r d5572756efd6 -r ab5b504181d8 hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/nodes/aot/ResolveMethodAndLoadCountersStubCall.java --- a/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/nodes/aot/ResolveMethodAndLoadCountersStubCall.java Tue Apr 18 20:10:55 2017 -0700 +++ b/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/nodes/aot/ResolveMethodAndLoadCountersStubCall.java Wed Apr 19 04:10:56 2017 +0000 @@ -22,11 +22,8 @@ */ package org.graalvm.compiler.hotspot.nodes.aot; -import jdk.vm.ci.meta.Constant; -import jdk.vm.ci.meta.Value; - import static org.graalvm.compiler.nodeinfo.NodeCycles.CYCLES_UNKNOWN; -import static org.graalvm.compiler.nodeinfo.NodeSize.SIZE_20; +import static org.graalvm.compiler.nodeinfo.NodeSize.SIZE_16; import org.graalvm.compiler.graph.Node; import org.graalvm.compiler.graph.NodeClass; @@ -45,10 +42,13 @@ import org.graalvm.compiler.nodes.spi.NodeLIRBuilderTool; import org.graalvm.compiler.nodes.util.GraphUtil; +import jdk.vm.ci.meta.Constant; +import jdk.vm.ci.meta.Value; + /** * A call to the VM via a regular stub. */ -@NodeInfo(cycles = CYCLES_UNKNOWN, size = SIZE_20) +@NodeInfo(cycles = CYCLES_UNKNOWN, size = SIZE_16) public class ResolveMethodAndLoadCountersStubCall extends DeoptimizingStubCall implements Canonicalizable, LIRLowerable { public static final NodeClass TYPE = NodeClass.create(ResolveMethodAndLoadCountersStubCall.class); diff -r d5572756efd6 -r ab5b504181d8 hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/nodes/profiling/ProfileNode.java --- a/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/nodes/profiling/ProfileNode.java Tue Apr 18 20:10:55 2017 -0700 +++ b/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/nodes/profiling/ProfileNode.java Wed Apr 19 04:10:56 2017 +0000 @@ -22,6 +22,9 @@ */ package org.graalvm.compiler.hotspot.nodes.profiling; +import static org.graalvm.compiler.nodeinfo.NodeCycles.CYCLES_IGNORED; +import static org.graalvm.compiler.nodeinfo.NodeSize.SIZE_IGNORED; + import org.graalvm.compiler.core.common.type.StampFactory; import org.graalvm.compiler.graph.NodeClass; import org.graalvm.compiler.graph.iterators.NodeIterable; @@ -37,7 +40,7 @@ import jdk.vm.ci.meta.ResolvedJavaMethod; -@NodeInfo +@NodeInfo(cycles = CYCLES_IGNORED, cyclesRationale = "profiling should be ignored", size = SIZE_IGNORED, sizeRationale = "profiling should be ignored") public class ProfileNode extends DeoptimizingFixedWithNextNode implements Lowerable { public static class Options { @Option(help = "Control probabilistic profiling on AMD64", type = OptionType.Expert)// diff -r d5572756efd6 -r ab5b504181d8 hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/nodes/profiling/ProfileWithNotificationNode.java --- a/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/nodes/profiling/ProfileWithNotificationNode.java Tue Apr 18 20:10:55 2017 -0700 +++ b/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/nodes/profiling/ProfileWithNotificationNode.java Wed Apr 19 04:10:56 2017 +0000 @@ -22,15 +22,12 @@ */ package org.graalvm.compiler.hotspot.nodes.profiling; -import jdk.vm.ci.meta.ResolvedJavaMethod; - -import static org.graalvm.compiler.nodeinfo.NodeCycles.CYCLES_10; -import static org.graalvm.compiler.nodeinfo.NodeSize.SIZE_50; - import org.graalvm.compiler.graph.NodeClass; import org.graalvm.compiler.nodeinfo.NodeInfo; -@NodeInfo(cycles = CYCLES_10, size = SIZE_50) +import jdk.vm.ci.meta.ResolvedJavaMethod; + +@NodeInfo public class ProfileWithNotificationNode extends ProfileNode { public static final NodeClass TYPE = NodeClass.create(ProfileWithNotificationNode.class); diff -r d5572756efd6 -r ab5b504181d8 hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/replacements/ClassGetHubNode.java --- a/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/replacements/ClassGetHubNode.java Tue Apr 18 20:10:55 2017 -0700 +++ b/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/replacements/ClassGetHubNode.java Wed Apr 19 04:10:56 2017 +0000 @@ -22,7 +22,7 @@ */ package org.graalvm.compiler.hotspot.replacements; -import static org.graalvm.compiler.nodeinfo.NodeCycles.CYCLES_4; +import static org.graalvm.compiler.nodeinfo.NodeCycles.CYCLES_1; import static org.graalvm.compiler.nodeinfo.NodeSize.SIZE_1; import jdk.vm.ci.meta.JavaKind; @@ -63,7 +63,7 @@ * handled by * {@link ReadNode#canonicalizeRead(ValueNode, AddressNode, LocationIdentity, CanonicalizerTool)}. */ -@NodeInfo(cycles = CYCLES_4, size = SIZE_1) +@NodeInfo(cycles = CYCLES_1, size = SIZE_1) public final class ClassGetHubNode extends FloatingNode implements Lowerable, Canonicalizable, ConvertNode { public static final NodeClass TYPE = NodeClass.create(ClassGetHubNode.class); @Input protected ValueNode clazz; @@ -80,7 +80,7 @@ @SuppressWarnings("unused") public static boolean intrinsify(GraphBuilderContext b, ResolvedJavaMethod method, ValueNode clazz) { ValueNode clazzValue = create(clazz, b.getMetaAccess(), b.getConstantReflection(), false); - b.push(JavaKind.Object, b.recursiveAppend(clazzValue)); + b.push(JavaKind.Object, b.append(clazzValue)); return true; } diff -r d5572756efd6 -r ab5b504181d8 hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/replacements/HubGetClassNode.java --- a/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/replacements/HubGetClassNode.java Tue Apr 18 20:10:55 2017 -0700 +++ b/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/replacements/HubGetClassNode.java Wed Apr 19 04:10:56 2017 +0000 @@ -22,7 +22,7 @@ */ package org.graalvm.compiler.hotspot.replacements; -import static org.graalvm.compiler.nodeinfo.NodeCycles.CYCLES_4; +import static org.graalvm.compiler.nodeinfo.NodeCycles.CYCLES_1; import static org.graalvm.compiler.nodeinfo.NodeSize.SIZE_1; import org.graalvm.compiler.core.common.GraalOptions; @@ -51,7 +51,7 @@ * Read {@code Klass::_java_mirror} and incorporate non-null type information into stamp. This is * also used by {@link ClassGetHubNode} to eliminate chains of {@code klass._java_mirror._klass}. */ -@NodeInfo(cycles = CYCLES_4, size = SIZE_1) +@NodeInfo(cycles = CYCLES_1, size = SIZE_1) public final class HubGetClassNode extends FloatingNode implements Lowerable, Canonicalizable, ConvertNode { public static final NodeClass TYPE = NodeClass.create(HubGetClassNode.class); @Input protected ValueNode hub; diff -r d5572756efd6 -r ab5b504181d8 hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/replacements/KlassLayoutHelperNode.java --- a/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/replacements/KlassLayoutHelperNode.java Tue Apr 18 20:10:55 2017 -0700 +++ b/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/replacements/KlassLayoutHelperNode.java Wed Apr 19 04:10:56 2017 +0000 @@ -22,7 +22,7 @@ */ package org.graalvm.compiler.hotspot.replacements; -import static org.graalvm.compiler.nodeinfo.NodeCycles.CYCLES_4; +import static org.graalvm.compiler.nodeinfo.NodeCycles.CYCLES_1; import static org.graalvm.compiler.nodeinfo.NodeSize.SIZE_1; import jdk.vm.ci.meta.ConstantReflectionProvider; @@ -54,7 +54,7 @@ * Read {@code Klass::_layout_helper} and incorporate any useful stamp information based on any type * information in {@code klass}. */ -@NodeInfo(cycles = CYCLES_4, size = SIZE_1) +@NodeInfo(cycles = CYCLES_1, size = SIZE_1) public final class KlassLayoutHelperNode extends FloatingNode implements Canonicalizable, Lowerable { public static final NodeClass TYPE = NodeClass.create(KlassLayoutHelperNode.class); @@ -75,7 +75,7 @@ @SuppressWarnings("unused") public static boolean intrinsify(GraphBuilderContext b, ResolvedJavaMethod method, @InjectedNodeParameter GraalHotSpotVMConfig config, ValueNode klass) { ValueNode valueNode = create(config, klass, b.getConstantReflection(), b.getMetaAccess()); - b.push(JavaKind.Int, b.recursiveAppend(valueNode)); + b.push(JavaKind.Int, b.append(valueNode)); return true; } diff -r d5572756efd6 -r ab5b504181d8 hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/replacements/ReflectionGetCallerClassNode.java --- a/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/replacements/ReflectionGetCallerClassNode.java Tue Apr 18 20:10:55 2017 -0700 +++ b/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/replacements/ReflectionGetCallerClassNode.java Wed Apr 19 04:10:56 2017 +0000 @@ -22,9 +22,6 @@ */ package org.graalvm.compiler.hotspot.replacements; -import static org.graalvm.compiler.nodeinfo.NodeCycles.CYCLES_UNKNOWN; -import static org.graalvm.compiler.nodeinfo.NodeSize.SIZE_20; - import org.graalvm.compiler.core.common.type.StampPair; import org.graalvm.compiler.debug.GraalError; import org.graalvm.compiler.graph.Node; @@ -47,7 +44,7 @@ import jdk.vm.ci.meta.MetaAccessProvider; import jdk.vm.ci.meta.ResolvedJavaMethod; -@NodeInfo(cycles = CYCLES_UNKNOWN, cyclesRationale = "This node can be lowered to a call", size = SIZE_20) +@NodeInfo public final class ReflectionGetCallerClassNode extends MacroStateSplitNode implements Canonicalizable, Lowerable { public static final NodeClass TYPE = NodeClass.create(ReflectionGetCallerClassNode.class); diff -r d5572756efd6 -r ab5b504181d8 hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/replacements/arraycopy/UnsafeArrayCopyNode.java --- a/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/replacements/arraycopy/UnsafeArrayCopyNode.java Tue Apr 18 20:10:55 2017 -0700 +++ b/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/replacements/arraycopy/UnsafeArrayCopyNode.java Wed Apr 19 04:10:56 2017 +0000 @@ -23,8 +23,8 @@ package org.graalvm.compiler.hotspot.replacements.arraycopy; import static org.graalvm.compiler.core.common.LocationIdentity.any; -import static org.graalvm.compiler.nodeinfo.NodeCycles.CYCLES_200; -import static org.graalvm.compiler.nodeinfo.NodeSize.SIZE_200; +import static org.graalvm.compiler.nodeinfo.NodeCycles.CYCLES_256; +import static org.graalvm.compiler.nodeinfo.NodeSize.SIZE_64; import org.graalvm.compiler.core.common.LocationIdentity; import org.graalvm.compiler.core.common.type.StampFactory; @@ -43,7 +43,7 @@ import jdk.vm.ci.meta.JavaKind; -@NodeInfo(allowedUsageTypes = {InputType.Memory}, cycles = CYCLES_200, size = SIZE_200) +@NodeInfo(allowedUsageTypes = {InputType.Memory}, cycles = CYCLES_256, size = SIZE_64) public final class UnsafeArrayCopyNode extends ArrayRangeWriteNode implements Lowerable, MemoryCheckpoint.Single, MemoryAccess { public static final NodeClass TYPE = NodeClass.create(UnsafeArrayCopyNode.class); diff -r d5572756efd6 -r ab5b504181d8 hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.java/src/org/graalvm/compiler/java/BciBlockMapping.java --- a/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.java/src/org/graalvm/compiler/java/BciBlockMapping.java Tue Apr 18 20:10:55 2017 -0700 +++ b/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.java/src/org/graalvm/compiler/java/BciBlockMapping.java Wed Apr 19 04:10:56 2017 +0000 @@ -437,8 +437,6 @@ private static final int LOOP_HEADER_INITIAL_CAPACITY = 4; private int blocksNotYetAssignedId; - public int returnCount; - private int returnBci; /** * Creates a new BlockMap instance from {@code code}. @@ -452,10 +450,6 @@ return this.blocks; } - public int getReturnCount() { - return this.returnCount; - } - /** * Builds the block map and conservative CFG and numbers blocks. */ @@ -533,9 +527,7 @@ case DRETURN: // fall through case ARETURN: // fall through case RETURN: { - returnCount++; current = null; - returnBci = bci; break; } case ATHROW: { @@ -832,7 +824,7 @@ // Purge null entries for unreached blocks and sort blocks such that loop bodies are always // consecutively in the array. - int blockCount = maxBlocks - blocksNotYetAssignedId + 2; + int blockCount = maxBlocks - blocksNotYetAssignedId + 1; BciBlock[] newBlocks = new BciBlock[blockCount]; int next = 0; for (int i = 0; i < blocks.length; ++i) { @@ -845,13 +837,7 @@ } } } - - // Add return block. - BciBlock returnBlock = new BciBlock(); - returnBlock.startBci = returnBci; - returnBlock.endBci = returnBci; - returnBlock.setId(newBlocks.length - 2); - newBlocks[newBlocks.length - 2] = returnBlock; + assert next == newBlocks.length - 1; // Add unwind block. ExceptionDispatchBlock unwindBlock = new ExceptionDispatchBlock(); @@ -1066,10 +1052,6 @@ return startBlock; } - public BciBlock getReturnBlock() { - return blocks[blocks.length - 2]; - } - public ExceptionDispatchBlock getUnwindBlock() { return (ExceptionDispatchBlock) blocks[blocks.length - 1]; } diff -r d5572756efd6 -r ab5b504181d8 hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.java/src/org/graalvm/compiler/java/BytecodeParser.java --- a/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.java/src/org/graalvm/compiler/java/BytecodeParser.java Tue Apr 18 20:10:55 2017 -0700 +++ b/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.java/src/org/graalvm/compiler/java/BytecodeParser.java Wed Apr 19 04:10:56 2017 +0000 @@ -251,6 +251,8 @@ import static org.graalvm.compiler.java.BytecodeParserOptions.TraceInlineDuringParsing; import static org.graalvm.compiler.java.BytecodeParserOptions.TraceParserPlugins; import static org.graalvm.compiler.java.BytecodeParserOptions.UseGuardedIntrinsics; +import static org.graalvm.compiler.nodes.extended.BranchProbabilityNode.FAST_PATH_PROBABILITY; +import static org.graalvm.compiler.nodes.extended.BranchProbabilityNode.SLOW_PATH_PROBABILITY; import static org.graalvm.compiler.nodes.graphbuilderconf.IntrinsicContext.CompilationContext.INLINE_DURING_PARSING; import static org.graalvm.compiler.nodes.type.StampTool.isPointerNonNull; @@ -399,6 +401,7 @@ import org.graalvm.compiler.nodes.util.GraphUtil; import org.graalvm.compiler.options.OptionValues; import org.graalvm.compiler.phases.OptimisticOptimizations; +import org.graalvm.compiler.phases.util.ValueMergeUtil; import org.graalvm.util.EconomicMap; import org.graalvm.util.Equivalence; @@ -578,6 +581,16 @@ } } + protected static class ReturnToCallerData { + protected final ValueNode returnValue; + protected final FixedWithNextNode beforeReturnNode; + + protected ReturnToCallerData(ValueNode returnValue, FixedWithNextNode beforeReturnNode) { + this.returnValue = returnValue; + this.beforeReturnNode = beforeReturnNode; + } + } + private final GraphBuilderPhase.Instance graphBuilderInstance; protected final StructuredGraph graph; protected final OptionValues options; @@ -593,8 +606,7 @@ private ValueNode methodSynchronizedObject; - private ValueNode returnValue; - private FixedWithNextNode beforeReturnNode; + private List returnDataList; private ValueNode unwindValue; private FixedWithNextNode beforeUnwindNode; @@ -641,14 +653,6 @@ return graphBuilderInstance; } - public ValueNode getReturnValue() { - return returnValue; - } - - public FixedWithNextNode getBeforeReturnNode() { - return this.beforeReturnNode; - } - public ValueNode getUnwindValue() { return unwindValue; } @@ -1114,15 +1118,15 @@ } protected LogicNode genObjectEquals(ValueNode x, ValueNode y) { - return ObjectEqualsNode.create(x, y, constantReflection); + return ObjectEqualsNode.create(constantReflection, metaAccess, options, x, y); } protected LogicNode genIntegerEquals(ValueNode x, ValueNode y) { - return IntegerEqualsNode.create(x, y); + return IntegerEqualsNode.create(constantReflection, metaAccess, options, null, x, y); } protected LogicNode genIntegerLessThan(ValueNode x, ValueNode y) { - return IntegerLessThanNode.create(x, y); + return IntegerLessThanNode.create(constantReflection, metaAccess, options, null, x, y); } protected ValueNode genUnique(ValueNode x) { @@ -1200,7 +1204,7 @@ BytecodeExceptionNode exception = graph.add(new BytecodeExceptionNode(metaAccess, NullPointerException.class)); AbstractBeginNode falseSucc = graph.add(new BeginNode()); ValueNode nonNullReceiver = graph.addOrUnique(PiNode.create(receiver, objectNonNull(), falseSucc)); - append(new IfNode(graph.addOrUniqueWithInputs(IsNullNode.create(receiver)), exception, falseSucc, 0.01)); + append(new IfNode(graph.addOrUniqueWithInputs(IsNullNode.create(receiver)), exception, falseSucc, SLOW_PATH_PROBABILITY)); lastInstr = falseSucc; exception.setStateAfter(createFrameState(bci(), exception)); @@ -1212,7 +1216,7 @@ protected void emitExplicitBoundsCheck(ValueNode index, ValueNode length) { AbstractBeginNode trueSucc = graph.add(new BeginNode()); BytecodeExceptionNode exception = graph.add(new BytecodeExceptionNode(metaAccess, ArrayIndexOutOfBoundsException.class, index)); - append(new IfNode(genUnique(IntegerBelowNode.create(index, length)), trueSucc, exception, 0.99)); + append(new IfNode(genUnique(IntegerBelowNode.create(constantReflection, metaAccess, options, null, index, length)), trueSucc, exception, FAST_PATH_PROBABILITY)); lastInstr = trueSucc; exception.setStateAfter(createFrameState(bci(), exception)); @@ -1608,7 +1612,7 @@ LoadHubNode hub = graph.unique(new LoadHubNode(stampProvider, nonNullReceiver)); LoadMethodNode actual = append(new LoadMethodNode(methodStamp, targetMethod, receiverType, method.getDeclaringClass(), hub)); ConstantNode expected = graph.unique(ConstantNode.forConstant(methodStamp, targetMethod.getEncoding(), getMetaAccess())); - LogicNode compare = graph.addOrUniqueWithInputs(CompareNode.createCompareNode(Condition.EQ, actual, expected, constantReflection)); + LogicNode compare = graph.addOrUniqueWithInputs(CompareNode.createCompareNode(constantReflection, metaAccess, options, null, Condition.EQ, actual, expected)); JavaTypeProfile profile = null; if (profilingInfo != null && this.optimisticOpts.useTypeCheckHints(getOptions())) { @@ -1632,7 +1636,7 @@ AbstractBeginNode intrinsicBranch = graph.add(new BeginNode()); AbstractBeginNode nonIntrinsicBranch = graph.add(new BeginNode()); - append(new IfNode(compare, intrinsicBranch, nonIntrinsicBranch, 0.01)); + append(new IfNode(compare, intrinsicBranch, nonIntrinsicBranch, FAST_PATH_PROBABILITY)); lastInstr = intrinsicBranch; return new IntrinsicGuard(currentLastInstr, intrinsicReceiver, mark, nonIntrinsicBranch, profile); } else { @@ -1959,13 +1963,30 @@ startFrameState.initializeFromArgumentsArray(args); parser.build(this.lastInstr, startFrameState); - FixedWithNextNode calleeBeforeReturnNode = parser.getBeforeReturnNode(); - this.lastInstr = calleeBeforeReturnNode; - JavaKind calleeReturnKind = targetMethod.getSignature().getReturnKind(); - if (calleeBeforeReturnNode != null) { - ValueNode calleeReturnValue = parser.getReturnValue(); + if (parser.returnDataList == null) { + /* Callee does not return. */ + lastInstr = null; + } else { + ValueNode calleeReturnValue; + MergeNode returnMergeNode = null; + if (parser.returnDataList.size() == 1) { + /* Callee has a single return, we can continue parsing at that point. */ + ReturnToCallerData singleReturnData = parser.returnDataList.get(0); + lastInstr = singleReturnData.beforeReturnNode; + calleeReturnValue = singleReturnData.returnValue; + } else { + assert parser.returnDataList.size() > 1; + /* Callee has multiple returns, we need to insert a control flow merge. */ + returnMergeNode = graph.add(new MergeNode()); + calleeReturnValue = ValueMergeUtil.mergeValueProducers(returnMergeNode, parser.returnDataList, returnData -> returnData.beforeReturnNode, returnData -> returnData.returnValue); + } + if (calleeReturnValue != null) { - frameState.push(calleeReturnKind.getStackKind(), calleeReturnValue); + frameState.push(targetMethod.getSignature().getReturnKind().getStackKind(), calleeReturnValue); + } + if (returnMergeNode != null) { + returnMergeNode.setStateAfter(createFrameState(stream.nextBCI(), returnMergeNode)); + lastInstr = finishInstruction(returnMergeNode, frameState); } } @@ -2028,27 +2049,18 @@ } } } + + frameState.setRethrowException(false); + frameState.clearStack(); + beforeReturn(returnVal, returnKind); if (parent == null) { - frameState.setRethrowException(false); - frameState.clearStack(); - beforeReturn(returnVal, returnKind); append(new ReturnNode(returnVal)); } else { - if (blockMap.getReturnCount() == 1 || !controlFlowSplit) { - // There is only a single return. - beforeReturn(returnVal, returnKind); - this.returnValue = returnVal; - this.beforeReturnNode = this.lastInstr; - this.lastInstr = null; - } else { - frameState.setRethrowException(false); - frameState.clearStack(); - if (returnVal != null) { - frameState.push(returnKind, returnVal); - } - assert blockMap.getReturnCount() > 1; - appendGoto(blockMap.getReturnBlock()); + if (returnDataList == null) { + returnDataList = new ArrayList<>(); } + returnDataList.add(new ReturnToCallerData(returnVal, lastInstr)); + lastInstr = null; } } @@ -2122,7 +2134,7 @@ JsrScope scope = currentBlock.getJsrScope(); int retAddress = scope.nextReturnAddress(); ConstantNode returnBciNode = getJsrConstant(retAddress); - LogicNode guard = IntegerEqualsNode.create(local, returnBciNode); + LogicNode guard = IntegerEqualsNode.create(constantReflection, metaAccess, options, null, local, returnBciNode); guard = graph.addOrUniqueWithInputs(guard); append(new FixedGuardNode(guard, JavaSubroutineMismatch, InvalidateReprofile)); if (!successor.getJsrScope().equals(scope.pop())) { @@ -2182,18 +2194,6 @@ if (v.graph() != null) { return v; } - T added = graph.addOrUnique(v); - if (added == v) { - updateLastInstruction(v); - } - return added; - } - - @Override - public T recursiveAppend(T v) { - if (v.graph() != null) { - return v; - } T added = graph.addOrUniqueWithInputs(v); if (added == v) { updateLastInstruction(v); @@ -2429,9 +2429,7 @@ setMergeStateAfter(block, firstInstruction); } - if (block == blockMap.getReturnBlock()) { - handleReturnBlock(); - } else if (block == blockMap.getUnwindBlock()) { + if (block == blockMap.getUnwindBlock()) { handleUnwindBlock((ExceptionDispatchBlock) block); } else if (block instanceof ExceptionDispatchBlock) { createExceptionDispatch((ExceptionDispatchBlock) block); @@ -2454,15 +2452,6 @@ } } - private void handleReturnBlock() { - JavaKind returnKind = method.getSignature().getReturnKind().getStackKind(); - ValueNode x = returnKind == JavaKind.Void ? null : frameState.pop(returnKind); - assert frameState.stackSize() == 0; - beforeReturn(x, returnKind); - this.returnValue = x; - this.beforeReturnNode = this.lastInstr; - } - private void setMergeStateAfter(BciBlock block, FixedWithNextNode firstInstruction) { AbstractMergeNode abstractMergeNode = (AbstractMergeNode) firstInstruction; if (abstractMergeNode.stateAfter() == null) { @@ -3144,7 +3133,7 @@ default: throw shouldNotReachHere(); } - frameState.push(kind, recursiveAppend(v)); + frameState.push(kind, append(v)); } private void genIntegerDivOp(JavaKind kind, int opcode) { @@ -3191,7 +3180,7 @@ default: throw shouldNotReachHere(); } - frameState.push(kind, recursiveAppend(v)); + frameState.push(kind, append(v)); } private void genLogicOp(JavaKind kind, int opcode) { @@ -3214,7 +3203,7 @@ default: throw shouldNotReachHere(); } - frameState.push(kind, recursiveAppend(v)); + frameState.push(kind, append(v)); } private void genCompareOp(JavaKind kind, boolean isUnorderedLess) { @@ -3233,7 +3222,7 @@ if (from != from.getStackKind()) { input = append(genNarrow(input, from.getBitCount())); } - frameState.push(to, recursiveAppend(genSignExtend(input, to.getBitCount()))); + frameState.push(to, append(genSignExtend(input, to.getBitCount()))); } private void genZeroExtend(JavaKind from, JavaKind to) { @@ -3254,7 +3243,7 @@ int delta = getStream().readIncrement(); ValueNode x = frameState.loadLocal(index, JavaKind.Int); ValueNode y = appendConstant(JavaConstant.forInt(delta)); - frameState.storeLocal(index, JavaKind.Int, recursiveAppend(genIntegerAdd(x, y))); + frameState.storeLocal(index, JavaKind.Int, append(genIntegerAdd(x, y))); } private void genIfZero(Condition cond) { diff -r d5572756efd6 -r ab5b504181d8 hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir/src/org/graalvm/compiler/lir/RedundantMoveElimination.java --- a/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir/src/org/graalvm/compiler/lir/RedundantMoveElimination.java Tue Apr 18 20:10:55 2017 -0700 +++ b/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir/src/org/graalvm/compiler/lir/RedundantMoveElimination.java Wed Apr 19 04:10:56 2017 +0000 @@ -376,7 +376,7 @@ @SuppressWarnings("try") private int updateState(final int[] state, LIRInstruction op, int initValueNum) { - try (final Indent indent = Debug.logAndIndent("update state for op %s, initial value num = %d", op, initValueNum)) { + try (Indent indent = Debug.logAndIndent("update state for op %s, initial value num = %d", op, initValueNum)) { if (isEligibleMove(op)) { /* * Handle the special case of a move instruction diff -r d5572756efd6 -r ab5b504181d8 hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir/src/org/graalvm/compiler/lir/alloc/lsra/LinearScan.java --- a/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir/src/org/graalvm/compiler/lir/alloc/lsra/LinearScan.java Tue Apr 18 20:10:55 2017 -0700 +++ b/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir/src/org/graalvm/compiler/lir/alloc/lsra/LinearScan.java Wed Apr 19 04:10:56 2017 +0000 @@ -750,11 +750,7 @@ } } } - Debug.dump(Debug.BASIC_LEVEL, new LinearScanIntervalDumper(Arrays.copyOf(intervals, intervalsSize)), label); - } - - public void printLir(String label, @SuppressWarnings("unused") boolean hirValid) { - Debug.dump(Debug.INFO_LEVEL, ir, label); + Debug.dump(Debug.VERBOSE_LEVEL, new LinearScanIntervalDumper(Arrays.copyOf(intervals, intervalsSize)), label); } boolean verify() { diff -r d5572756efd6 -r ab5b504181d8 hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir/src/org/graalvm/compiler/lir/alloc/lsra/LinearScanAllocationPhase.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir/src/org/graalvm/compiler/lir/alloc/lsra/LinearScanAllocationPhase.java Wed Apr 19 04:10:56 2017 +0000 @@ -0,0 +1,62 @@ +/* + * 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.lir.alloc.lsra; + +import org.graalvm.compiler.debug.Debug; +import org.graalvm.compiler.debug.Debug.Scope; +import org.graalvm.compiler.lir.gen.LIRGenerationResult; +import static org.graalvm.compiler.lir.phases.AllocationPhase.AllocationContext; +import org.graalvm.compiler.lir.phases.LIRPhase; + +import jdk.vm.ci.code.TargetDescription; + +abstract class LinearScanAllocationPhase { + + final CharSequence getName() { + return LIRPhase.createName(getClass()); + } + + @Override + public final String toString() { + return getName().toString(); + } + + public final void apply(TargetDescription target, LIRGenerationResult lirGenRes, AllocationContext context) { + apply(target, lirGenRes, context, true); + } + + @SuppressWarnings("try") + public final void apply(TargetDescription target, LIRGenerationResult lirGenRes, AllocationContext context, boolean dumpLIR) { + try (Scope s = Debug.scope(getName(), this)) { + run(target, lirGenRes, context); + if (dumpLIR && Debug.isDumpEnabled(Debug.VERBOSE_LEVEL)) { + Debug.dump(Debug.VERBOSE_LEVEL, lirGenRes.getLIR(), "After %s", getName()); + } + } catch (Throwable e) { + throw Debug.handle(e); + } + } + + protected abstract void run(TargetDescription target, LIRGenerationResult lirGenRes, AllocationContext context); + +} diff -r d5572756efd6 -r ab5b504181d8 hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir/src/org/graalvm/compiler/lir/alloc/lsra/LinearScanAssignLocationsPhase.java --- a/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir/src/org/graalvm/compiler/lir/alloc/lsra/LinearScanAssignLocationsPhase.java Tue Apr 18 20:10:55 2017 -0700 +++ b/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir/src/org/graalvm/compiler/lir/alloc/lsra/LinearScanAssignLocationsPhase.java Wed Apr 19 04:10:56 2017 +0000 @@ -46,7 +46,7 @@ import org.graalvm.compiler.lir.StandardOp.ValueMoveOp; import org.graalvm.compiler.lir.Variable; import org.graalvm.compiler.lir.gen.LIRGenerationResult; -import org.graalvm.compiler.lir.phases.AllocationPhase; +import org.graalvm.compiler.lir.phases.AllocationPhase.AllocationContext; import jdk.vm.ci.code.TargetDescription; import jdk.vm.ci.meta.AllocatableValue; @@ -55,7 +55,7 @@ /** * Phase 7: Assign register numbers back to LIR. */ -public class LinearScanAssignLocationsPhase extends AllocationPhase { +public class LinearScanAssignLocationsPhase extends LinearScanAllocationPhase { protected final LinearScan allocator; diff -r d5572756efd6 -r ab5b504181d8 hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir/src/org/graalvm/compiler/lir/alloc/lsra/LinearScanEliminateSpillMovePhase.java --- a/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir/src/org/graalvm/compiler/lir/alloc/lsra/LinearScanEliminateSpillMovePhase.java Tue Apr 18 20:10:55 2017 -0700 +++ b/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir/src/org/graalvm/compiler/lir/alloc/lsra/LinearScanEliminateSpillMovePhase.java Wed Apr 19 04:10:56 2017 +0000 @@ -41,7 +41,7 @@ import org.graalvm.compiler.lir.alloc.lsra.Interval.SpillState; import org.graalvm.compiler.lir.alloc.lsra.LinearScan.IntervalPredicate; import org.graalvm.compiler.lir.gen.LIRGenerationResult; -import org.graalvm.compiler.lir.phases.AllocationPhase; +import org.graalvm.compiler.lir.phases.AllocationPhase.AllocationContext; import org.graalvm.compiler.options.NestedBooleanOptionKey; import org.graalvm.compiler.options.Option; import org.graalvm.compiler.options.OptionKey; @@ -50,7 +50,7 @@ import jdk.vm.ci.code.TargetDescription; import jdk.vm.ci.meta.AllocatableValue; -public class LinearScanEliminateSpillMovePhase extends AllocationPhase { +public class LinearScanEliminateSpillMovePhase extends LinearScanAllocationPhase { public static class Options { // @formatter:off diff -r d5572756efd6 -r ab5b504181d8 hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir/src/org/graalvm/compiler/lir/alloc/lsra/LinearScanLifetimeAnalysisPhase.java --- a/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir/src/org/graalvm/compiler/lir/alloc/lsra/LinearScanLifetimeAnalysisPhase.java Tue Apr 18 20:10:55 2017 -0700 +++ b/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir/src/org/graalvm/compiler/lir/alloc/lsra/LinearScanLifetimeAnalysisPhase.java Wed Apr 19 04:10:56 2017 +0000 @@ -36,8 +36,8 @@ import java.util.BitSet; import java.util.EnumSet; +import org.graalvm.compiler.core.common.LIRKind; import org.graalvm.compiler.core.common.PermanentBailoutException; -import org.graalvm.compiler.core.common.LIRKind; import org.graalvm.compiler.core.common.alloc.ComputeBlockOrder; import org.graalvm.compiler.core.common.cfg.AbstractBlockBase; import org.graalvm.compiler.core.common.util.BitMap2D; @@ -56,7 +56,7 @@ import org.graalvm.compiler.lir.alloc.lsra.Interval.SpillState; import org.graalvm.compiler.lir.alloc.lsra.LinearScan.BlockData; import org.graalvm.compiler.lir.gen.LIRGenerationResult; -import org.graalvm.compiler.lir.phases.AllocationPhase; +import org.graalvm.compiler.lir.phases.AllocationPhase.AllocationContext; import org.graalvm.util.EconomicSet; import org.graalvm.util.Equivalence; @@ -70,7 +70,7 @@ import jdk.vm.ci.meta.Value; import jdk.vm.ci.meta.ValueKind; -public class LinearScanLifetimeAnalysisPhase extends AllocationPhase { +public class LinearScanLifetimeAnalysisPhase extends LinearScanAllocationPhase { protected final LinearScan allocator; @@ -84,7 +84,7 @@ @Override protected void run(TargetDescription target, LIRGenerationResult lirGenRes, AllocationContext context) { numberInstructions(); - allocator.printLir("Before register allocation", true); + Debug.dump(Debug.VERBOSE_LEVEL, lirGenRes.getLIR(), "Before register allocation"); computeLocalLiveSets(); computeGlobalLiveSets(); buildIntervals(DetailedAsserts.getValue(allocator.getOptions())); diff -r d5572756efd6 -r ab5b504181d8 hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir/src/org/graalvm/compiler/lir/alloc/lsra/LinearScanOptimizeSpillPositionPhase.java --- a/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir/src/org/graalvm/compiler/lir/alloc/lsra/LinearScanOptimizeSpillPositionPhase.java Tue Apr 18 20:10:55 2017 -0700 +++ b/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir/src/org/graalvm/compiler/lir/alloc/lsra/LinearScanOptimizeSpillPositionPhase.java Wed Apr 19 04:10:56 2017 +0000 @@ -27,6 +27,7 @@ import static org.graalvm.compiler.lir.LIRValueUtil.isStackSlotValue; import java.util.Iterator; + import org.graalvm.compiler.core.common.cfg.AbstractBlockBase; import org.graalvm.compiler.debug.Debug; import org.graalvm.compiler.debug.DebugCounter; @@ -36,12 +37,12 @@ import org.graalvm.compiler.lir.LIRInstruction.OperandMode; import org.graalvm.compiler.lir.alloc.lsra.Interval.SpillState; import org.graalvm.compiler.lir.gen.LIRGenerationResult; -import org.graalvm.compiler.lir.phases.AllocationPhase; +import org.graalvm.compiler.lir.phases.AllocationPhase.AllocationContext; import jdk.vm.ci.code.TargetDescription; import jdk.vm.ci.meta.AllocatableValue; -public final class LinearScanOptimizeSpillPositionPhase extends AllocationPhase { +public final class LinearScanOptimizeSpillPositionPhase extends LinearScanAllocationPhase { private static final DebugCounter betterSpillPos = Debug.counter("BetterSpillPosition"); private static final DebugCounter betterSpillPosWithLowerProbability = Debug.counter("BetterSpillPositionWithLowerProbability"); diff -r d5572756efd6 -r ab5b504181d8 hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir/src/org/graalvm/compiler/lir/alloc/lsra/LinearScanRegisterAllocationPhase.java --- a/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir/src/org/graalvm/compiler/lir/alloc/lsra/LinearScanRegisterAllocationPhase.java Tue Apr 18 20:10:55 2017 -0700 +++ b/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir/src/org/graalvm/compiler/lir/alloc/lsra/LinearScanRegisterAllocationPhase.java Wed Apr 19 04:10:56 2017 +0000 @@ -25,12 +25,12 @@ import org.graalvm.compiler.debug.Debug; import org.graalvm.compiler.debug.Indent; import org.graalvm.compiler.lir.gen.LIRGenerationResult; -import org.graalvm.compiler.lir.phases.AllocationPhase; +import org.graalvm.compiler.lir.phases.AllocationPhase.AllocationContext; import org.graalvm.util.Pair; import jdk.vm.ci.code.TargetDescription; -public final class LinearScanRegisterAllocationPhase extends AllocationPhase { +public final class LinearScanRegisterAllocationPhase extends LinearScanAllocationPhase { private final LinearScan allocator; diff -r d5572756efd6 -r ab5b504181d8 hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir/src/org/graalvm/compiler/lir/alloc/lsra/LinearScanResolveDataFlowPhase.java --- a/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir/src/org/graalvm/compiler/lir/alloc/lsra/LinearScanResolveDataFlowPhase.java Tue Apr 18 20:10:55 2017 -0700 +++ b/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir/src/org/graalvm/compiler/lir/alloc/lsra/LinearScanResolveDataFlowPhase.java Wed Apr 19 04:10:56 2017 +0000 @@ -31,7 +31,7 @@ import org.graalvm.compiler.lir.LIRInstruction; import org.graalvm.compiler.lir.StandardOp; import org.graalvm.compiler.lir.gen.LIRGenerationResult; -import org.graalvm.compiler.lir.phases.AllocationPhase; +import org.graalvm.compiler.lir.phases.AllocationPhase.AllocationContext; import jdk.vm.ci.code.TargetDescription; @@ -40,7 +40,7 @@ * * Insert moves at edges between blocks if intervals have been split. */ -public class LinearScanResolveDataFlowPhase extends AllocationPhase { +public class LinearScanResolveDataFlowPhase extends LinearScanAllocationPhase { protected final LinearScan allocator; diff -r d5572756efd6 -r ab5b504181d8 hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir/src/org/graalvm/compiler/lir/alloc/trace/TraceAllocationPhase.java --- a/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir/src/org/graalvm/compiler/lir/alloc/trace/TraceAllocationPhase.java Tue Apr 18 20:10:55 2017 -0700 +++ b/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir/src/org/graalvm/compiler/lir/alloc/trace/TraceAllocationPhase.java Wed Apr 19 04:10:56 2017 +0000 @@ -112,13 +112,13 @@ public final void apply(TargetDescription target, LIRGenerationResult lirGenRes, Trace trace, C context, boolean dumpTrace) { try (Scope s = Debug.scope(getName(), this)) { try (DebugCloseable a = timer.start(); DebugCloseable c = memUseTracker.start()) { - if (dumpTrace && Debug.isDumpEnabled(TraceBuilderPhase.TRACE_DUMP_LEVEL + 1)) { - Debug.dump(TraceBuilderPhase.TRACE_DUMP_LEVEL + 1, trace, "%s before (Trace%s: %s)", getName(), trace.getId(), trace); + if (dumpTrace && Debug.isDumpEnabled(Debug.DETAILED_LEVEL)) { + Debug.dump(Debug.DETAILED_LEVEL, trace, "Before %s (Trace%s: %s)", getName(), trace.getId(), trace); } run(target, lirGenRes, trace, context); allocatedTraces.increment(); - if (dumpTrace && Debug.isDumpEnabled(TraceBuilderPhase.TRACE_DUMP_LEVEL)) { - Debug.dump(TraceBuilderPhase.TRACE_DUMP_LEVEL, trace, "%s (Trace%s: %s)", getName(), trace.getId(), trace); + if (dumpTrace && Debug.isDumpEnabled(Debug.VERBOSE_LEVEL)) { + Debug.dump(Debug.VERBOSE_LEVEL, trace, "After %s (Trace%s: %s)", getName(), trace.getId(), trace); } } } catch (Throwable e) { diff -r d5572756efd6 -r ab5b504181d8 hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir/src/org/graalvm/compiler/lir/alloc/trace/TraceBuilderPhase.java --- a/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir/src/org/graalvm/compiler/lir/alloc/trace/TraceBuilderPhase.java Tue Apr 18 20:10:55 2017 -0700 +++ b/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir/src/org/graalvm/compiler/lir/alloc/trace/TraceBuilderPhase.java Wed Apr 19 04:10:56 2017 +0000 @@ -64,9 +64,6 @@ // @formatter:on } - private static final int TRACE_LOG_LEVEL = Debug.BASIC_LEVEL; - public static final int TRACE_DUMP_LEVEL = Debug.VERBOSE_LEVEL; - @Override protected void run(TargetDescription target, LIRGenerationResult lirGenRes, AllocationContext context) { AbstractBlockBase[] linearScanOrder = lirGenRes.getLIR().linearScanOrder(); @@ -76,15 +73,15 @@ final TraceBuilderResult traceBuilderResult = getTraceBuilderResult(lir, startBlock, linearScanOrder); - if (Debug.isLogEnabled(TRACE_LOG_LEVEL)) { + if (Debug.isLogEnabled(Debug.BASIC_LEVEL)) { ArrayList traces = traceBuilderResult.getTraces(); for (int i = 0; i < traces.size(); i++) { Trace trace = traces.get(i); - Debug.log(TRACE_LOG_LEVEL, "Trace %5d: %s%s", i, trace, isTrivialTrace(lirGenRes.getLIR(), trace) ? " (trivial)" : ""); + Debug.log(Debug.BASIC_LEVEL, "Trace %5d: %s%s", i, trace, isTrivialTrace(lirGenRes.getLIR(), trace) ? " (trivial)" : ""); } } TraceStatisticsPrinter.printTraceStatistics(traceBuilderResult, lirGenRes.getCompilationUnitName()); - Debug.dump(TRACE_DUMP_LEVEL, traceBuilderResult, "After TraceBuilding"); + Debug.dump(Debug.VERBOSE_LEVEL, traceBuilderResult, "TraceBuilderResult"); context.contextAdd(traceBuilderResult); } @@ -93,7 +90,7 @@ OptionValues options = lir.getOptions(); TraceBuilder selectedTraceBuilder = Options.TraceBuilding.getValue(options); - Debug.log(TRACE_LOG_LEVEL, "Building Traces using %s", selectedTraceBuilder); + Debug.log(Debug.BASIC_LEVEL, "Building Traces using %s", selectedTraceBuilder); switch (Options.TraceBuilding.getValue(options)) { case SingleBlock: return SingleBlockTraceBuilder.computeTraces(startBlock, linearScanOrder, pred); diff -r d5572756efd6 -r ab5b504181d8 hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir/src/org/graalvm/compiler/lir/alloc/trace/TraceGlobalMoveResolutionPhase.java --- a/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir/src/org/graalvm/compiler/lir/alloc/trace/TraceGlobalMoveResolutionPhase.java Tue Apr 18 20:10:55 2017 -0700 +++ b/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir/src/org/graalvm/compiler/lir/alloc/trace/TraceGlobalMoveResolutionPhase.java Wed Apr 19 04:10:56 2017 +0000 @@ -45,7 +45,6 @@ import org.graalvm.compiler.lir.alloc.trace.TraceAllocationPhase.TraceAllocationContext; import org.graalvm.compiler.lir.gen.LIRGenerationResult; import org.graalvm.compiler.lir.gen.LIRGeneratorTool.MoveFactory; -import org.graalvm.compiler.lir.phases.LIRPhase; import org.graalvm.compiler.lir.ssa.SSAUtil; import jdk.vm.ci.code.Architecture; @@ -54,7 +53,10 @@ import jdk.vm.ci.meta.AllocatableValue; import jdk.vm.ci.meta.Value; -public final class TraceGlobalMoveResolutionPhase extends LIRPhase { +public final class TraceGlobalMoveResolutionPhase { + + private TraceGlobalMoveResolutionPhase() { + } /** * Abstract move resolver interface for testing. @@ -63,8 +65,8 @@ public abstract void addMapping(Value src, AllocatableValue dst, Value fromStack); } - @Override - protected void run(TargetDescription target, LIRGenerationResult lirGenRes, TraceAllocationContext context) { + public static void resolve(TargetDescription target, LIRGenerationResult lirGenRes, TraceAllocationContext context) { + Debug.dump(Debug.VERBOSE_LEVEL, lirGenRes.getLIR(), "Before TraceGlobalMoveResultion"); MoveFactory spillMoveFactory = context.spillMoveFactory; resolveGlobalDataFlow(context.resultTraces, lirGenRes, spillMoveFactory, target.arch, context.livenessInfo); } @@ -191,4 +193,5 @@ moveResolver.addMapping(from, to, fromStack); } } + } diff -r d5572756efd6 -r ab5b504181d8 hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir/src/org/graalvm/compiler/lir/alloc/trace/TraceRegisterAllocationPhase.java --- a/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir/src/org/graalvm/compiler/lir/alloc/trace/TraceRegisterAllocationPhase.java Tue Apr 18 20:10:55 2017 -0700 +++ b/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir/src/org/graalvm/compiler/lir/alloc/trace/TraceRegisterAllocationPhase.java Wed Apr 19 04:10:56 2017 +0000 @@ -31,7 +31,6 @@ import org.graalvm.compiler.debug.DebugCounter; import org.graalvm.compiler.debug.Indent; import org.graalvm.compiler.lir.LIR; -import org.graalvm.compiler.lir.LIRInstruction; import org.graalvm.compiler.lir.alloc.trace.TraceAllocationPhase.TraceAllocationContext; import org.graalvm.compiler.lir.gen.LIRGenerationResult; import org.graalvm.compiler.lir.gen.LIRGeneratorTool.MoveFactory; @@ -64,8 +63,6 @@ // @formatter:on } - private static final TraceGlobalMoveResolutionPhase TRACE_GLOBAL_MOVE_RESOLUTION_PHASE = new TraceGlobalMoveResolutionPhase(); - private static final DebugCounter tracesCounter = Debug.counter("TraceRA[traces]"); public static final DebugCounter globalStackSlots = Debug.counter("TraceRA[GlobalStackSlots]"); @@ -89,7 +86,6 @@ final TraceRegisterAllocationPolicy plan = DefaultTraceRegisterAllocationPolicy.allocationPolicy(target, lirGenRes, spillMoveFactory, registerAllocationConfig, cachedStackSlots, resultTraces, neverSpillConstant, livenessInfo, lir.getOptions()); - Debug.dump(Debug.INFO_LEVEL, lir, "Before TraceRegisterAllocation"); try (Scope s0 = Debug.scope("AllocateTraces", resultTraces, livenessInfo)) { for (Trace trace : resultTraces.getTraces()) { tracesCounter.increment(); @@ -101,12 +97,8 @@ } catch (Throwable e) { throw Debug.handle(e); } - if (Debug.isDumpEnabled(Debug.INFO_LEVEL)) { - unnumberInstructions(lir); - Debug.dump(Debug.INFO_LEVEL, lir, "After trace allocation"); - } - TRACE_GLOBAL_MOVE_RESOLUTION_PHASE.apply(target, lirGenRes, traceContext); + TraceGlobalMoveResolutionPhase.resolve(target, lirGenRes, traceContext); deconstructSSAForm(lir); } @@ -124,11 +116,4 @@ } } - private static void unnumberInstructions(LIR lir) { - for (AbstractBlockBase block : lir.getControlFlowGraph().getBlocks()) { - for (LIRInstruction op : lir.getLIRforBlock(block)) { - op.setId(-1); - } - } - } } diff -r d5572756efd6 -r ab5b504181d8 hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir/src/org/graalvm/compiler/lir/alloc/trace/lsra/TraceLinearScanAllocationPhase.java --- a/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir/src/org/graalvm/compiler/lir/alloc/trace/lsra/TraceLinearScanAllocationPhase.java Tue Apr 18 20:10:55 2017 -0700 +++ b/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir/src/org/graalvm/compiler/lir/alloc/trace/lsra/TraceLinearScanAllocationPhase.java Wed Apr 19 04:10:56 2017 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 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 @@ -23,19 +23,41 @@ package org.graalvm.compiler.lir.alloc.trace.lsra; import org.graalvm.compiler.core.common.alloc.RegisterAllocationConfig; +import org.graalvm.compiler.core.common.alloc.Trace; import org.graalvm.compiler.core.common.alloc.TraceBuilderResult; -import org.graalvm.compiler.lir.alloc.trace.TraceAllocationPhase; +import org.graalvm.compiler.debug.Debug; import org.graalvm.compiler.lir.alloc.trace.lsra.TraceLinearScanPhase.TraceLinearScan; +import org.graalvm.compiler.lir.gen.LIRGenerationResult; import org.graalvm.compiler.lir.gen.LIRGeneratorTool.MoveFactory; +import org.graalvm.compiler.lir.phases.LIRPhase; + +import jdk.vm.ci.code.TargetDescription; -abstract class TraceLinearScanAllocationPhase extends TraceAllocationPhase { +abstract class TraceLinearScanAllocationPhase { + + final CharSequence getName() { + return LIRPhase.createName(getClass()); + } - static final class TraceLinearScanAllocationContext extends TraceAllocationPhase.TraceAllocationContext { - public final TraceLinearScan allocator; + @Override + public final String toString() { + return getName().toString(); + } - TraceLinearScanAllocationContext(MoveFactory spillMoveFactory, RegisterAllocationConfig registerAllocationConfig, TraceBuilderResult traceBuilderResult, TraceLinearScan allocator) { - super(spillMoveFactory, registerAllocationConfig, traceBuilderResult, allocator.getGlobalLivenessInfo()); - this.allocator = allocator; + final void apply(TargetDescription target, LIRGenerationResult lirGenRes, Trace trace, MoveFactory spillMoveFactory, RegisterAllocationConfig registerAllocationConfig, + TraceBuilderResult traceBuilderResult, TraceLinearScan allocator) { + apply(target, lirGenRes, trace, spillMoveFactory, registerAllocationConfig, traceBuilderResult, allocator, true); + } + + final void apply(TargetDescription target, LIRGenerationResult lirGenRes, Trace trace, MoveFactory spillMoveFactory, RegisterAllocationConfig registerAllocationConfig, + TraceBuilderResult traceBuilderResult, TraceLinearScan allocator, boolean dumpLIR) { + run(target, lirGenRes, trace, spillMoveFactory, registerAllocationConfig, traceBuilderResult, allocator); + if (dumpLIR && Debug.isDumpEnabled(Debug.DETAILED_LEVEL)) { + Debug.dump(Debug.DETAILED_LEVEL, trace, "After %s (Trace%s)", getName(), trace.getId()); } } + + abstract void run(TargetDescription target, LIRGenerationResult lirGenRes, Trace trace, MoveFactory spillMoveFactory, RegisterAllocationConfig registerAllocationConfig, + TraceBuilderResult traceBuilderResult, TraceLinearScan allocator); + } diff -r d5572756efd6 -r ab5b504181d8 hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir/src/org/graalvm/compiler/lir/alloc/trace/lsra/TraceLinearScanAssignLocationsPhase.java --- a/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir/src/org/graalvm/compiler/lir/alloc/trace/lsra/TraceLinearScanAssignLocationsPhase.java Tue Apr 18 20:10:55 2017 -0700 +++ b/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir/src/org/graalvm/compiler/lir/alloc/trace/lsra/TraceLinearScanAssignLocationsPhase.java Wed Apr 19 04:10:56 2017 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 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 @@ -33,7 +33,9 @@ import java.util.Collections; import java.util.EnumSet; +import org.graalvm.compiler.core.common.alloc.RegisterAllocationConfig; import org.graalvm.compiler.core.common.alloc.Trace; +import org.graalvm.compiler.core.common.alloc.TraceBuilderResult; import org.graalvm.compiler.core.common.cfg.AbstractBlockBase; import org.graalvm.compiler.debug.Debug; import org.graalvm.compiler.debug.GraalError; @@ -69,9 +71,8 @@ final class TraceLinearScanAssignLocationsPhase extends TraceLinearScanAllocationPhase { @Override - protected void run(TargetDescription target, LIRGenerationResult lirGenRes, Trace trace, TraceLinearScanAllocationContext context) { - TraceLinearScan allocator = context.allocator; - MoveFactory spillMoveFactory = context.spillMoveFactory; + protected void run(TargetDescription target, LIRGenerationResult lirGenRes, Trace trace, MoveFactory spillMoveFactory, RegisterAllocationConfig registerAllocationConfig, + TraceBuilderResult traceBuilderResult, TraceLinearScan allocator) { new Assigner(allocator, spillMoveFactory).assign(); } diff -r d5572756efd6 -r ab5b504181d8 hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir/src/org/graalvm/compiler/lir/alloc/trace/lsra/TraceLinearScanEliminateSpillMovePhase.java --- a/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir/src/org/graalvm/compiler/lir/alloc/trace/lsra/TraceLinearScanEliminateSpillMovePhase.java Tue Apr 18 20:10:55 2017 -0700 +++ b/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir/src/org/graalvm/compiler/lir/alloc/trace/lsra/TraceLinearScanEliminateSpillMovePhase.java Wed Apr 19 04:10:56 2017 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 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 @@ -29,6 +29,7 @@ import java.util.ArrayList; +import org.graalvm.compiler.core.common.alloc.RegisterAllocationConfig; import org.graalvm.compiler.core.common.alloc.Trace; import org.graalvm.compiler.core.common.alloc.TraceBuilderResult; import org.graalvm.compiler.core.common.cfg.AbstractBlockBase; @@ -44,6 +45,7 @@ import org.graalvm.compiler.lir.alloc.trace.lsra.TraceLinearScanPhase.IntervalPredicate; import org.graalvm.compiler.lir.alloc.trace.lsra.TraceLinearScanPhase.TraceLinearScan; import org.graalvm.compiler.lir.gen.LIRGenerationResult; +import org.graalvm.compiler.lir.gen.LIRGeneratorTool.MoveFactory; import jdk.vm.ci.code.TargetDescription; import jdk.vm.ci.meta.AllocatableValue; @@ -59,9 +61,8 @@ }; @Override - protected void run(TargetDescription target, LIRGenerationResult lirGenRes, Trace trace, TraceLinearScanAllocationContext context) { - TraceBuilderResult traceBuilderResult = context.resultTraces; - TraceLinearScan allocator = context.allocator; + 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); } diff -r d5572756efd6 -r ab5b504181d8 hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir/src/org/graalvm/compiler/lir/alloc/trace/lsra/TraceLinearScanLifetimeAnalysisPhase.java --- a/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir/src/org/graalvm/compiler/lir/alloc/trace/lsra/TraceLinearScanLifetimeAnalysisPhase.java Tue Apr 18 20:10:55 2017 -0700 +++ b/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir/src/org/graalvm/compiler/lir/alloc/trace/lsra/TraceLinearScanLifetimeAnalysisPhase.java Wed Apr 19 04:10:56 2017 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 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 @@ -39,6 +39,7 @@ import java.util.EnumSet; import org.graalvm.compiler.core.common.LIRKind; +import org.graalvm.compiler.core.common.alloc.RegisterAllocationConfig; import org.graalvm.compiler.core.common.alloc.Trace; import org.graalvm.compiler.core.common.alloc.TraceBuilderResult; import org.graalvm.compiler.core.common.cfg.AbstractBlockBase; @@ -78,14 +79,12 @@ public final class TraceLinearScanLifetimeAnalysisPhase extends TraceLinearScanAllocationPhase { @Override - protected void run(TargetDescription target, LIRGenerationResult lirGenRes, Trace trace, TraceLinearScanAllocationContext context) { - TraceBuilderResult traceBuilderResult = context.resultTraces; - TraceLinearScan allocator = context.allocator; + protected void run(TargetDescription target, LIRGenerationResult lirGenRes, Trace trace, MoveFactory spillMoveFactory, RegisterAllocationConfig registerAllocationConfig, + TraceBuilderResult traceBuilderResult, TraceLinearScan allocator) { new Analyser(allocator, traceBuilderResult).analyze(); } public static final class Analyser { - private static final int DUMP_DURING_ANALYSIS_LEVEL = 4; private final TraceLinearScan allocator; private final TraceBuilderResult traceBuilderResult; private int numInstructions; @@ -534,7 +533,7 @@ AbstractBlockBase pred = blockId == 0 ? null : blocks[blockId - 1]; handleBlockBegin(block, pred); } - if (Debug.isDumpEnabled(DUMP_DURING_ANALYSIS_LEVEL)) { + if (Debug.isDumpEnabled(Debug.VERY_DETAILED_LEVEL)) { allocator.printIntervals("After Block " + block); } } // end of block iteration diff -r d5572756efd6 -r ab5b504181d8 hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir/src/org/graalvm/compiler/lir/alloc/trace/lsra/TraceLinearScanPhase.java --- a/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir/src/org/graalvm/compiler/lir/alloc/trace/lsra/TraceLinearScanPhase.java Tue Apr 18 20:10:55 2017 -0700 +++ b/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir/src/org/graalvm/compiler/lir/alloc/trace/lsra/TraceLinearScanPhase.java Wed Apr 19 04:10:56 2017 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2009, 2016, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2009, 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 @@ -56,11 +56,9 @@ import org.graalvm.compiler.lir.alloc.trace.GlobalLivenessInfo; import org.graalvm.compiler.lir.alloc.trace.TraceAllocationPhase; import org.graalvm.compiler.lir.alloc.trace.TraceAllocationPhase.TraceAllocationContext; -import org.graalvm.compiler.lir.alloc.trace.TraceBuilderPhase; import org.graalvm.compiler.lir.alloc.trace.TraceRegisterAllocationPhase; import org.graalvm.compiler.lir.alloc.trace.TraceUtil; import org.graalvm.compiler.lir.alloc.trace.lsra.TraceInterval.RegisterPriority; -import org.graalvm.compiler.lir.alloc.trace.lsra.TraceLinearScanAllocationPhase.TraceLinearScanAllocationContext; import org.graalvm.compiler.lir.debug.IntervalDumper; import org.graalvm.compiler.lir.debug.IntervalDumper.IntervalVisitor; import org.graalvm.compiler.lir.framemap.FrameMapBuilder; @@ -588,37 +586,35 @@ @SuppressWarnings("try") protected void allocate(TargetDescription target, LIRGenerationResult lirGenRes, TraceAllocationContext traceContext) { + MoveFactory spillMoveFactory = traceContext.spillMoveFactory; + RegisterAllocationConfig registerAllocationConfig = traceContext.registerAllocationConfig; /* * This is the point to enable debug logging for the whole register allocation. */ try (Indent indent = Debug.logAndIndent("LinearScan allocate")) { - TraceLinearScanAllocationContext context = new TraceLinearScanAllocationContext(traceContext.spillMoveFactory, traceContext.registerAllocationConfig, traceBuilderResult, this); - - TRACE_LINEAR_SCAN_LIFETIME_ANALYSIS_PHASE.apply(target, lirGenRes, trace, context, false); + TRACE_LINEAR_SCAN_LIFETIME_ANALYSIS_PHASE.apply(target, lirGenRes, trace, spillMoveFactory, registerAllocationConfig, traceBuilderResult, this, false); try (Scope s = Debug.scope("AfterLifetimeAnalysis", this)) { - printLir("Before register allocation", true); + printLir("After instruction numbering"); printIntervals("Before register allocation"); sortIntervalsBeforeAllocation(); sortFixedIntervalsBeforeAllocation(); - TRACE_LINEAR_SCAN_REGISTER_ALLOCATION_PHASE.apply(target, lirGenRes, trace, context, false); + TRACE_LINEAR_SCAN_REGISTER_ALLOCATION_PHASE.apply(target, lirGenRes, trace, spillMoveFactory, registerAllocationConfig, traceBuilderResult, this, false); printIntervals("After register allocation"); // resolve intra-trace data-flow - TRACE_LINEAR_SCAN_RESOLVE_DATA_FLOW_PHASE.apply(target, lirGenRes, trace, context, false); - Debug.dump(TraceBuilderPhase.TRACE_DUMP_LEVEL, sortedBlocks(), "%s", TRACE_LINEAR_SCAN_RESOLVE_DATA_FLOW_PHASE.getName()); + TRACE_LINEAR_SCAN_RESOLVE_DATA_FLOW_PHASE.apply(target, lirGenRes, trace, spillMoveFactory, registerAllocationConfig, traceBuilderResult, this); // eliminate spill moves OptionValues options = getOptions(); if (Options.LIROptTraceRAEliminateSpillMoves.getValue(options)) { - TRACE_LINEAR_SCAN_ELIMINATE_SPILL_MOVE_PHASE.apply(target, lirGenRes, trace, context, false); - Debug.dump(TraceBuilderPhase.TRACE_DUMP_LEVEL, sortedBlocks(), "%s", TRACE_LINEAR_SCAN_ELIMINATE_SPILL_MOVE_PHASE.getName()); + TRACE_LINEAR_SCAN_ELIMINATE_SPILL_MOVE_PHASE.apply(target, lirGenRes, trace, spillMoveFactory, registerAllocationConfig, traceBuilderResult, this); } - TRACE_LINEAR_SCAN_ASSIGN_LOCATIONS_PHASE.apply(target, lirGenRes, trace, context, false); + TRACE_LINEAR_SCAN_ASSIGN_LOCATIONS_PHASE.apply(target, lirGenRes, trace, spillMoveFactory, registerAllocationConfig, traceBuilderResult, this, false); if (DetailedAsserts.getValue(options)) { verifyIntervals(); @@ -629,9 +625,9 @@ } } - public void printLir(String label, @SuppressWarnings("unused") boolean hirValid) { - if (Debug.isDumpEnabled(TraceBuilderPhase.TRACE_DUMP_LEVEL)) { - Debug.dump(TraceBuilderPhase.TRACE_DUMP_LEVEL, sortedBlocks(), label); + public void printLir(String label) { + if (Debug.isDumpEnabled(Debug.DETAILED_LEVEL)) { + Debug.dump(Debug.DETAILED_LEVEL, sortedBlocks(), "%s (Trace%d)", label, trace.getId()); } } @@ -1051,7 +1047,7 @@ @SuppressWarnings("try") public void printIntervals(String label) { - if (Debug.isDumpEnabled(TraceBuilderPhase.TRACE_DUMP_LEVEL)) { + if (Debug.isDumpEnabled(Debug.DETAILED_LEVEL)) { if (Debug.isLogEnabled()) { try (Indent indent = Debug.logAndIndent("intervals %s", label)) { for (FixedInterval interval : fixedIntervals) { @@ -1073,7 +1069,7 @@ } } } - Debug.dump(Debug.INFO_LEVEL, this, label); + Debug.dump(Debug.DETAILED_LEVEL, this, "%s (Trace%d)", label, trace.getId()); } } diff -r d5572756efd6 -r ab5b504181d8 hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir/src/org/graalvm/compiler/lir/alloc/trace/lsra/TraceLinearScanRegisterAllocationPhase.java --- a/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir/src/org/graalvm/compiler/lir/alloc/trace/lsra/TraceLinearScanRegisterAllocationPhase.java Tue Apr 18 20:10:55 2017 -0700 +++ b/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir/src/org/graalvm/compiler/lir/alloc/trace/lsra/TraceLinearScanRegisterAllocationPhase.java Wed Apr 19 04:10:56 2017 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 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 @@ -22,19 +22,22 @@ */ package org.graalvm.compiler.lir.alloc.trace.lsra; +import org.graalvm.compiler.core.common.alloc.RegisterAllocationConfig; import org.graalvm.compiler.core.common.alloc.Trace; +import org.graalvm.compiler.core.common.alloc.TraceBuilderResult; import org.graalvm.compiler.debug.Debug; import org.graalvm.compiler.debug.Indent; import org.graalvm.compiler.lir.alloc.trace.lsra.TraceLinearScanPhase.TraceLinearScan; import org.graalvm.compiler.lir.gen.LIRGenerationResult; +import org.graalvm.compiler.lir.gen.LIRGeneratorTool.MoveFactory; import jdk.vm.ci.code.TargetDescription; final class TraceLinearScanRegisterAllocationPhase extends TraceLinearScanAllocationPhase { @Override - protected void run(TargetDescription target, LIRGenerationResult lirGenRes, Trace trace, TraceLinearScanAllocationContext context) { - TraceLinearScan allocator = context.allocator; + protected void run(TargetDescription target, LIRGenerationResult lirGenRes, Trace trace, MoveFactory spillMoveFactory, RegisterAllocationConfig registerAllocationConfig, + TraceBuilderResult traceBuilderResult, TraceLinearScan allocator) { allocateRegisters(allocator); } diff -r d5572756efd6 -r ab5b504181d8 hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir/src/org/graalvm/compiler/lir/alloc/trace/lsra/TraceLinearScanResolveDataFlowPhase.java --- a/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir/src/org/graalvm/compiler/lir/alloc/trace/lsra/TraceLinearScanResolveDataFlowPhase.java Tue Apr 18 20:10:55 2017 -0700 +++ b/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir/src/org/graalvm/compiler/lir/alloc/trace/lsra/TraceLinearScanResolveDataFlowPhase.java Wed Apr 19 04:10:56 2017 +0000 @@ -31,6 +31,7 @@ import java.util.ArrayList; +import org.graalvm.compiler.core.common.alloc.RegisterAllocationConfig; import org.graalvm.compiler.core.common.alloc.Trace; import org.graalvm.compiler.core.common.alloc.TraceBuilderResult; import org.graalvm.compiler.core.common.cfg.AbstractBlockBase; @@ -45,6 +46,7 @@ import org.graalvm.compiler.lir.alloc.trace.GlobalLivenessInfo; import org.graalvm.compiler.lir.alloc.trace.lsra.TraceLinearScanPhase.TraceLinearScan; import org.graalvm.compiler.lir.gen.LIRGenerationResult; +import org.graalvm.compiler.lir.gen.LIRGeneratorTool.MoveFactory; import org.graalvm.compiler.lir.ssa.SSAUtil; import jdk.vm.ci.code.TargetDescription; @@ -58,9 +60,8 @@ final class TraceLinearScanResolveDataFlowPhase extends TraceLinearScanAllocationPhase { @Override - protected void run(TargetDescription target, LIRGenerationResult lirGenRes, Trace trace, TraceLinearScanAllocationContext context) { - TraceBuilderResult traceBuilderResult = context.resultTraces; - TraceLinearScan allocator = context.allocator; + protected void run(TargetDescription target, LIRGenerationResult lirGenRes, Trace trace, MoveFactory spillMoveFactory, RegisterAllocationConfig registerAllocationConfig, + TraceBuilderResult traceBuilderResult, TraceLinearScan allocator) { new Resolver(allocator, traceBuilderResult).resolveDataFlow(trace, allocator.sortedBlocks()); } diff -r d5572756efd6 -r ab5b504181d8 hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir/src/org/graalvm/compiler/lir/phases/LIRPhase.java --- a/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir/src/org/graalvm/compiler/lir/phases/LIRPhase.java Tue Apr 18 20:10:55 2017 -0700 +++ b/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir/src/org/graalvm/compiler/lir/phases/LIRPhase.java Wed Apr 19 04:10:56 2017 +0000 @@ -113,8 +113,8 @@ try (Scope s = Debug.scope(getName(), this)) { try (DebugCloseable a = timer.start(); DebugCloseable c = memUseTracker.start()) { run(target, lirGenRes, context); - if (dumpLIR && Debug.isDumpEnabled(Debug.BASIC_LEVEL)) { - Debug.dump(Debug.BASIC_LEVEL, lirGenRes.getLIR(), "%s", getName()); + if (dumpLIR && Debug.isEnabled()) { + dumpAfter(lirGenRes); } } } catch (Throwable e) { @@ -122,6 +122,15 @@ } } + private void dumpAfter(LIRGenerationResult lirGenRes) { + boolean isStage = this instanceof LIRPhaseSuite; + if (!isStage) { + if (Debug.isDumpEnabled(Debug.INFO_LEVEL)) { + Debug.dump(Debug.INFO_LEVEL, lirGenRes.getLIR(), "After %s", getName()); + } + } + } + protected abstract void run(TargetDescription target, LIRGenerationResult lirGenRes, C context); public static CharSequence createName(Class clazz) { diff -r d5572756efd6 -r ab5b504181d8 hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir/src/org/graalvm/compiler/lir/stackslotalloc/LSStackSlotAllocator.java --- a/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir/src/org/graalvm/compiler/lir/stackslotalloc/LSStackSlotAllocator.java Tue Apr 18 20:10:55 2017 -0700 +++ b/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir/src/org/graalvm/compiler/lir/stackslotalloc/LSStackSlotAllocator.java Wed Apr 19 04:10:56 2017 +0000 @@ -103,6 +103,7 @@ } private static final class Allocator { + private final LIR lir; private final FrameMapBuilderTool frameMapBuilder; private final StackInterval[] stackSlotMap; @@ -131,7 +132,7 @@ @SuppressWarnings("try") private void allocate() { - Debug.dump(Debug.INFO_LEVEL, lir, "After StackSlot numbering"); + Debug.dump(Debug.VERBOSE_LEVEL, lir, "After StackSlot numbering"); long currentFrameSize = StackSlotAllocatorUtil.allocatedFramesize.isEnabled() ? frameMapBuilder.getFrameMap().currentFrameSize() : 0; EconomicSet usePos; @@ -145,14 +146,14 @@ assert verifyIntervals(); } } - if (Debug.isDumpEnabled(Debug.INFO_LEVEL)) { + if (Debug.isDumpEnabled(Debug.VERBOSE_LEVEL)) { dumpIntervals("Before stack slot allocation"); } // step 4: allocate stack slots try (DebugCloseable t = AllocateSlotsTimer.start()) { allocateStackSlots(); } - if (Debug.isDumpEnabled(Debug.INFO_LEVEL)) { + if (Debug.isDumpEnabled(Debug.VERBOSE_LEVEL)) { dumpIntervals("After stack slot allocation"); } @@ -160,7 +161,6 @@ try (DebugCloseable t = AssignSlotsTimer.start()) { assignStackSlots(usePos); } - Debug.dump(Debug.INFO_LEVEL, lir, "After StackSlot assignment"); if (StackSlotAllocatorUtil.allocatedFramesize.isEnabled()) { StackSlotAllocatorUtil.allocatedFramesize.add(frameMapBuilder.getFrameMap().currentFrameSize() - currentFrameSize); } @@ -434,7 +434,7 @@ } private void dumpIntervals(String label) { - Debug.dump(Debug.INFO_LEVEL, new StackIntervalDumper(Arrays.copyOf(stackSlotMap, stackSlotMap.length)), label); + Debug.dump(Debug.VERBOSE_LEVEL, new StackIntervalDumper(Arrays.copyOf(stackSlotMap, stackSlotMap.length)), label); } } diff -r d5572756efd6 -r ab5b504181d8 hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.loop/src/org/graalvm/compiler/loop/LoopEx.java --- a/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.loop/src/org/graalvm/compiler/loop/LoopEx.java Tue Apr 18 20:10:55 2017 -0700 +++ b/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.loop/src/org/graalvm/compiler/loop/LoopEx.java Wed Apr 19 04:10:56 2017 +0000 @@ -69,8 +69,9 @@ import org.graalvm.compiler.nodes.debug.ControlFlowAnchored; import org.graalvm.compiler.nodes.extended.ValueAnchorNode; import org.graalvm.compiler.nodes.util.GraphUtil; +import org.graalvm.util.EconomicMap; +import org.graalvm.util.EconomicSet; import org.graalvm.util.Equivalence; -import org.graalvm.util.EconomicMap; import jdk.vm.ci.code.BytecodeFrame; @@ -296,7 +297,7 @@ } public void nodesInLoopBranch(NodeBitMap branchNodes, AbstractBeginNode branch) { - Collection blocks = new LinkedList<>(); + EconomicSet blocks = EconomicSet.create(); Collection exits = new LinkedList<>(); Queue work = new LinkedList<>(); ControlFlowGraph cfg = loopsData().getCFG(); @@ -304,9 +305,9 @@ while (!work.isEmpty()) { Block b = work.remove(); if (loop().getExits().contains(b)) { + assert !exits.contains(b.getBeginNode()); exits.add((LoopExitNode) b.getBeginNode()); - } else { - blocks.add(b.getBeginNode()); + } else if (blocks.add(b.getBeginNode())) { Block d = b.getDominatedSibling(); while (d != null) { if (loop.getBlocks().contains(d)) { diff -r d5572756efd6 -r ab5b504181d8 hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodeinfo/src/org/graalvm/compiler/nodeinfo/NodeCycles.java --- a/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodeinfo/src/org/graalvm/compiler/nodeinfo/NodeCycles.java Tue Apr 18 20:10:55 2017 -0700 +++ b/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodeinfo/src/org/graalvm/compiler/nodeinfo/NodeCycles.java Wed Apr 19 04:10:56 2017 +0000 @@ -52,28 +52,58 @@ CYCLES_0(0), CYCLES_1(1), CYCLES_2(2), - CYCLES_3(3), CYCLES_4(4), - CYCLES_5(5), - CYCLES_6(6), CYCLES_8(8), - CYCLES_10(10), - CYCLES_15(15), - CYCLES_20(20), - CYCLES_30(30), - CYCLES_40(40), - CYCLES_50(50), - CYCLES_80(80), - CYCLES_100(100), - CYCLES_200(200), - CYCLES_500(500); + CYCLES_16(16), + CYCLES_32(32), + CYCLES_64(64), + CYCLES_128(128), + CYCLES_256(256), + CYCLES_512(512), + CYCLES_1024(1024); - public final int estimatedCPUCycles; + public final int value; - NodeCycles(int estimatedCPUCycles) { - this.estimatedCPUCycles = estimatedCPUCycles; + NodeCycles(int value) { + this.value = value; } public static final int IGNORE_CYCLES_CONTRACT_FACTOR = 0xFFFF; + public static NodeCycles compute(NodeCycles base, int opCount) { + assert opCount >= 0; + if (opCount == 0) { + return CYCLES_0; + } + assert base.ordinal() > CYCLES_0.ordinal(); + int log2 = log2(base.value * opCount); + NodeCycles[] values = values(); + for (int i = base.ordinal(); i < values.length; i++) { + if (log2(values[i].value) == log2) { + return values[i]; + } + } + return CYCLES_1024; + } + + public static NodeCycles compute(int rawValue) { + assert rawValue >= 0; + if (rawValue == 0) { + return CYCLES_0; + } + NodeCycles[] values = values(); + for (int i = CYCLES_0.ordinal(); i < values.length - 1; i++) { + if (values[i].value >= rawValue && rawValue <= values[i + 1].value) { + int r1 = values[i].value; + int r2 = values[i + 1].value; + int diff = r2 - r1; + return rawValue - r1 > diff / 2 ? values[i + 1] : values[i]; + } + } + return CYCLES_1024; + } + + private static int log2(int val) { + return (Integer.SIZE - 1) - Integer.numberOfLeadingZeros(val); + } } diff -r d5572756efd6 -r ab5b504181d8 hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodeinfo/src/org/graalvm/compiler/nodeinfo/NodeSize.java --- a/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodeinfo/src/org/graalvm/compiler/nodeinfo/NodeSize.java Tue Apr 18 20:10:55 2017 -0700 +++ b/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodeinfo/src/org/graalvm/compiler/nodeinfo/NodeSize.java Wed Apr 19 04:10:56 2017 +0000 @@ -47,31 +47,65 @@ */ SIZE_IGNORED(0), /** - * Nodes that do not require any code to be generated in order to be "executed", e.g. a phi + * Nodes that do not require any code to be generated in order to be "executed", e.g. a pinode * node. */ SIZE_0(0), SIZE_1(1), SIZE_2(2), - SIZE_3(3), SIZE_4(4), - SIZE_6(6), SIZE_8(8), - SIZE_10(10), - SIZE_15(15), - SIZE_20(20), - SIZE_30(30), - SIZE_40(40), - SIZE_50(50), - SIZE_80(80), - SIZE_100(100), - SIZE_200(200); + SIZE_16(16), + SIZE_32(32), + SIZE_64(64), + SIZE_128(128), + SIZE_256(256), + SIZE_512(512), + SIZE_1024(1024); - public final int estimatedCodeSize; + public final int value; - NodeSize(int estimatedCodeSize) { - this.estimatedCodeSize = estimatedCodeSize; + NodeSize(int value) { + this.value = value; } public static final int IGNORE_SIZE_CONTRACT_FACTOR = 0xFFFF; + + public static NodeSize compute(NodeSize base, int opCount) { + assert opCount >= 0; + if (opCount == 0) { + return SIZE_0; + } + assert base.ordinal() > SIZE_0.ordinal(); + int log2 = log2(base.value * opCount); + NodeSize[] values = values(); + for (int i = base.ordinal(); i < values.length; i++) { + if (log2(values[i].value) == log2) { + return values[i]; + } + } + return SIZE_1024; + } + + public static NodeSize compute(int rawValue) { + assert rawValue >= 0; + if (rawValue == 0) { + return SIZE_0; + } + assert rawValue > 0; + NodeSize[] values = values(); + for (int i = SIZE_0.ordinal(); i < values.length - 1; i++) { + if (values[i].value >= rawValue && rawValue <= values[i + 1].value) { + int r1 = values[i].value; + int r2 = values[i + 1].value; + int diff = r2 - r1; + return rawValue - r1 > diff / 2 ? values[i + 1] : values[i]; + } + } + return SIZE_1024; + } + + private static int log2(int val) { + return (Integer.SIZE - 1) - Integer.numberOfLeadingZeros(val); + } } diff -r d5572756efd6 -r ab5b504181d8 hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/BreakpointNode.java --- a/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/BreakpointNode.java Tue Apr 18 20:10:55 2017 -0700 +++ b/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/BreakpointNode.java Wed Apr 19 04:10:56 2017 +0000 @@ -22,6 +22,9 @@ */ package org.graalvm.compiler.nodes; +import static org.graalvm.compiler.nodeinfo.NodeCycles.CYCLES_IGNORED; +import static org.graalvm.compiler.nodeinfo.NodeSize.SIZE_IGNORED; + import org.graalvm.compiler.core.common.type.StampFactory; import org.graalvm.compiler.graph.NodeClass; import org.graalvm.compiler.graph.NodeInputList; @@ -47,7 +50,7 @@ * Note that the signature is arbitrary. It's sole purpose is to capture values you may want to * inspect in the native debugger when the breakpoint is hit. */ -@NodeInfo +@NodeInfo(cycles = CYCLES_IGNORED, size = SIZE_IGNORED) public final class BreakpointNode extends FixedWithNextNode implements LIRLowerable { public static final NodeClass TYPE = NodeClass.create(BreakpointNode.class); diff -r d5572756efd6 -r ab5b504181d8 hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/FrameState.java --- a/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/FrameState.java Tue Apr 18 20:10:55 2017 -0700 +++ b/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/FrameState.java Wed Apr 19 04:10:56 2017 +0000 @@ -22,12 +22,14 @@ */ package org.graalvm.compiler.nodes; +import static jdk.vm.ci.code.BytecodeFrame.getPlaceholderBciName; +import static jdk.vm.ci.code.BytecodeFrame.isPlaceholderBci; import static org.graalvm.compiler.nodeinfo.InputType.Association; import static org.graalvm.compiler.nodeinfo.InputType.State; import static org.graalvm.compiler.nodeinfo.NodeCycles.CYCLES_0; +import static org.graalvm.compiler.nodeinfo.NodeCycles.CYCLES_IGNORED; import static org.graalvm.compiler.nodeinfo.NodeSize.SIZE_1; -import static jdk.vm.ci.code.BytecodeFrame.getPlaceholderBciName; -import static jdk.vm.ci.code.BytecodeFrame.isPlaceholderBci; +import static org.graalvm.compiler.nodeinfo.NodeSize.SIZE_IGNORED; import java.util.ArrayList; import java.util.Collections; @@ -78,7 +80,7 @@ */ public static final ValueNode TWO_SLOT_MARKER = new TwoSlotMarker(); - @NodeInfo + @NodeInfo(cycles = CYCLES_IGNORED, size = SIZE_IGNORED) private static final class TwoSlotMarker extends ValueNode { public static final NodeClass TYPE = NodeClass.create(TwoSlotMarker.class); diff -r d5572756efd6 -r ab5b504181d8 hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/GraphDecoder.java --- a/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/GraphDecoder.java Tue Apr 18 20:10:55 2017 -0700 +++ b/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/GraphDecoder.java Wed Apr 19 04:10:56 2017 +0000 @@ -573,7 +573,7 @@ return resultScope; } - private InvokeData readInvokeData(MethodScope methodScope, int invokeOrderId, Invoke invoke) { + protected InvokeData readInvokeData(MethodScope methodScope, int invokeOrderId, Invoke invoke) { ResolvedJavaType contextType = (ResolvedJavaType) readObject(methodScope); int callTargetOrderId = readOrderId(methodScope); int stateAfterOrderId = readOrderId(methodScope); diff -r d5572756efd6 -r ab5b504181d8 hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/GraphEncoder.java --- a/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/GraphEncoder.java Tue Apr 18 20:10:55 2017 -0700 +++ b/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/GraphEncoder.java Wed Apr 19 04:10:56 2017 +0000 @@ -427,8 +427,8 @@ GraphComparison.verifyGraphsEqual(originalGraph, decodedGraph); } catch (Throwable ex) { try (Debug.Scope scope = Debug.scope("GraphEncoder")) { - Debug.forceDump(originalGraph, "Original Graph"); - Debug.forceDump(decodedGraph, "Decoded Graph"); + Debug.dump(Debug.VERBOSE_LEVEL, originalGraph, "Original Graph"); + Debug.dump(Debug.VERBOSE_LEVEL, decodedGraph, "Decoded Graph"); } throw ex; } diff -r d5572756efd6 -r ab5b504181d8 hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/InvokeNode.java --- a/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/InvokeNode.java Tue Apr 18 20:10:55 2017 -0700 +++ b/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/InvokeNode.java Wed Apr 19 04:10:56 2017 +0000 @@ -25,7 +25,13 @@ import static org.graalvm.compiler.nodeinfo.InputType.Extension; import static org.graalvm.compiler.nodeinfo.InputType.Memory; import static org.graalvm.compiler.nodeinfo.InputType.State; +import static org.graalvm.compiler.nodeinfo.NodeCycles.CYCLES_2; +import static org.graalvm.compiler.nodeinfo.NodeCycles.CYCLES_64; +import static org.graalvm.compiler.nodeinfo.NodeCycles.CYCLES_8; import static org.graalvm.compiler.nodeinfo.NodeCycles.CYCLES_UNKNOWN; +import static org.graalvm.compiler.nodeinfo.NodeSize.SIZE_2; +import static org.graalvm.compiler.nodeinfo.NodeSize.SIZE_64; +import static org.graalvm.compiler.nodeinfo.NodeSize.SIZE_8; import static org.graalvm.compiler.nodeinfo.NodeSize.SIZE_UNKNOWN; import java.util.Map; @@ -35,7 +41,9 @@ import org.graalvm.compiler.graph.Node; import org.graalvm.compiler.graph.NodeClass; import org.graalvm.compiler.nodeinfo.InputType; +import org.graalvm.compiler.nodeinfo.NodeCycles; import org.graalvm.compiler.nodeinfo.NodeInfo; +import org.graalvm.compiler.nodeinfo.NodeSize; import org.graalvm.compiler.nodeinfo.Verbosity; import org.graalvm.compiler.nodes.extended.ForeignCallNode; import org.graalvm.compiler.nodes.java.MethodCallTargetNode; @@ -227,4 +235,34 @@ public ValueNode classInit() { return classInit; } + + @Override + public NodeCycles estimatedNodeCycles() { + switch (callTarget().invokeKind()) { + case Interface: + return CYCLES_64; + case Special: + case Static: + return CYCLES_2; + case Virtual: + return CYCLES_8; + default: + return CYCLES_UNKNOWN; + } + } + + @Override + public NodeSize estimatedNodeSize() { + switch (callTarget().invokeKind()) { + case Interface: + return SIZE_64; + case Special: + case Static: + return SIZE_2; + case Virtual: + return SIZE_8; + default: + return SIZE_UNKNOWN; + } + } } diff -r d5572756efd6 -r ab5b504181d8 hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/LoopEndNode.java --- a/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/LoopEndNode.java Tue Apr 18 20:10:55 2017 -0700 +++ b/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/LoopEndNode.java Wed Apr 19 04:10:56 2017 +0000 @@ -24,13 +24,16 @@ import static org.graalvm.compiler.nodeinfo.InputType.Association; import static org.graalvm.compiler.nodeinfo.NodeCycles.CYCLES_1; +import static org.graalvm.compiler.nodeinfo.NodeCycles.CYCLES_2; import static org.graalvm.compiler.nodeinfo.NodeSize.SIZE_1; import java.util.Collections; import org.graalvm.compiler.graph.Node; import org.graalvm.compiler.graph.NodeClass; +import org.graalvm.compiler.nodeinfo.NodeCycles; import org.graalvm.compiler.nodeinfo.NodeInfo; +import org.graalvm.compiler.nodeinfo.NodeSize; import org.graalvm.compiler.nodes.spi.NodeLIRBuilderTool; /** @@ -135,4 +138,21 @@ public Iterable cfgSuccessors() { return Collections.emptyList(); } + + @Override + public NodeCycles estimatedNodeCycles() { + if (canSafepoint()) { + // jmp+read + return CYCLES_2; + } + return super.estimatedNodeCycles(); + } + + @Override + public NodeSize estimatedNodeSize() { + if (canSafepoint()) { + return NodeSize.SIZE_2; + } + return super.estimatedNodeSize(); + } } diff -r d5572756efd6 -r ab5b504181d8 hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/PauseNode.java --- a/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/PauseNode.java Tue Apr 18 20:10:55 2017 -0700 +++ b/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/PauseNode.java Wed Apr 19 04:10:56 2017 +0000 @@ -22,16 +22,20 @@ */ package org.graalvm.compiler.nodes; +import static org.graalvm.compiler.nodeinfo.NodeCycles.CYCLES_IGNORED; + import org.graalvm.compiler.core.common.type.StampFactory; import org.graalvm.compiler.graph.NodeClass; -import org.graalvm.compiler.nodeinfo.NodeCycles; import org.graalvm.compiler.nodeinfo.NodeInfo; import org.graalvm.compiler.nodeinfo.NodeSize; import org.graalvm.compiler.nodes.spi.LIRLowerable; import org.graalvm.compiler.nodes.spi.NodeLIRBuilderTool; /** A node that results in a platform dependent pause instruction being emitted. */ -@NodeInfo(cycles = NodeCycles.CYCLES_500, size = NodeSize.SIZE_1) +// @formatter:off +@NodeInfo(cycles = CYCLES_IGNORED, + size = NodeSize.SIZE_1) +// @formatter:on public final class PauseNode extends FixedWithNextNode implements LIRLowerable { public static final NodeClass TYPE = NodeClass.create(PauseNode.class); diff -r d5572756efd6 -r ab5b504181d8 hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/PiNode.java --- a/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/PiNode.java Tue Apr 18 20:10:55 2017 -0700 +++ b/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/PiNode.java Wed Apr 19 04:10:56 2017 +0000 @@ -128,7 +128,7 @@ if (value == null) { value = new PiNode(object, stamp, anchor); } - b.push(JavaKind.Object, b.recursiveAppend(value)); + b.push(JavaKind.Object, b.append(value)); return true; } @@ -139,7 +139,7 @@ if (value == null) { value = new PiNode(object, stamp); } - b.push(JavaKind.Object, b.recursiveAppend(value)); + b.push(JavaKind.Object, b.append(value)); return true; } diff -r d5572756efd6 -r ab5b504181d8 hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/ReturnNode.java --- a/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/ReturnNode.java Tue Apr 18 20:10:55 2017 -0700 +++ b/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/ReturnNode.java Wed Apr 19 04:10:56 2017 +0000 @@ -23,8 +23,8 @@ package org.graalvm.compiler.nodes; import static org.graalvm.compiler.nodeinfo.InputType.Extension; -import static org.graalvm.compiler.nodeinfo.NodeCycles.CYCLES_UNKNOWN; -import static org.graalvm.compiler.nodeinfo.NodeSize.SIZE_UNKNOWN; +import static org.graalvm.compiler.nodeinfo.NodeCycles.CYCLES_2; +import static org.graalvm.compiler.nodeinfo.NodeSize.SIZE_2; import org.graalvm.compiler.core.common.type.StampFactory; import org.graalvm.compiler.graph.IterableNodeType; @@ -37,7 +37,7 @@ import jdk.vm.ci.code.TargetDescription; import jdk.vm.ci.meta.JavaKind; -@NodeInfo(cycles = CYCLES_UNKNOWN, size = SIZE_UNKNOWN) +@NodeInfo(cycles = CYCLES_2, size = SIZE_2, cyclesRationale = "Restore frame + ret", sizeRationale = "Restore frame + ret") public final class ReturnNode extends ControlSinkNode implements LIRLowerable, IterableNodeType { public static final NodeClass TYPE = NodeClass.create(ReturnNode.class); diff -r d5572756efd6 -r ab5b504181d8 hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/SafepointNode.java --- a/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/SafepointNode.java Tue Apr 18 20:10:55 2017 -0700 +++ b/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/SafepointNode.java Wed Apr 19 04:10:56 2017 +0000 @@ -22,8 +22,8 @@ */ package org.graalvm.compiler.nodes; -import static org.graalvm.compiler.nodeinfo.NodeCycles.CYCLES_UNKNOWN; -import static org.graalvm.compiler.nodeinfo.NodeSize.SIZE_6; +import static org.graalvm.compiler.nodeinfo.NodeCycles.CYCLES_2; +import static org.graalvm.compiler.nodeinfo.NodeSize.SIZE_1; import org.graalvm.compiler.core.common.type.StampFactory; import org.graalvm.compiler.graph.NodeClass; @@ -37,9 +37,9 @@ * Marks a position in the graph where a safepoint should be emitted. */ // @formatter:off -@NodeInfo(cycles = CYCLES_UNKNOWN, - cyclesRationale = "We don't know how long a safepoint would take if it is executed", - size = SIZE_6) +@NodeInfo(cycles = CYCLES_2, + cyclesRationale = "read", + size = SIZE_1) // @formatter:on public final class SafepointNode extends DeoptimizingFixedWithNextNode implements Lowerable, LIRLowerable { diff -r d5572756efd6 -r ab5b504181d8 hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/SimplifyingGraphDecoder.java --- a/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/SimplifyingGraphDecoder.java Tue Apr 18 20:10:55 2017 -0700 +++ b/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/SimplifyingGraphDecoder.java Wed Apr 19 04:10:56 2017 +0000 @@ -111,10 +111,10 @@ } @Override - public boolean supportSubwordCompare(int bits) { - // to be safe, just report false here + public Integer smallestCompareWidth() { + // to be safe, just report null here // there will be more opportunities for this optimization later - return false; + return null; } } diff -r d5572756efd6 -r ab5b504181d8 hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/UnwindNode.java --- a/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/UnwindNode.java Tue Apr 18 20:10:55 2017 -0700 +++ b/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/UnwindNode.java Wed Apr 19 04:10:56 2017 +0000 @@ -23,7 +23,7 @@ package org.graalvm.compiler.nodes; import static org.graalvm.compiler.nodeinfo.NodeCycles.CYCLES_8; -import static org.graalvm.compiler.nodeinfo.NodeSize.SIZE_4; +import static org.graalvm.compiler.nodeinfo.NodeSize.SIZE_8; import org.graalvm.compiler.core.common.type.StampFactory; import org.graalvm.compiler.graph.NodeClass; @@ -38,7 +38,7 @@ /** * Unwinds the current frame to an exception handler in the caller frame. */ -@NodeInfo(cycles = CYCLES_8, size = SIZE_4) +@NodeInfo(cycles = CYCLES_8, size = SIZE_8, cyclesRationale = "stub call", sizeRationale = "stub call") public final class UnwindNode extends ControlSinkNode implements Lowerable, LIRLowerable { public static final NodeClass TYPE = NodeClass.create(UnwindNode.class); diff -r d5572756efd6 -r ab5b504181d8 hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/calc/AbsNode.java --- a/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/calc/AbsNode.java Tue Apr 18 20:10:55 2017 -0700 +++ b/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/calc/AbsNode.java Wed Apr 19 04:10:56 2017 +0000 @@ -22,7 +22,7 @@ */ package org.graalvm.compiler.nodes.calc; -import static org.graalvm.compiler.nodeinfo.NodeCycles.CYCLES_3; +import static org.graalvm.compiler.nodeinfo.NodeCycles.CYCLES_2; import static org.graalvm.compiler.nodeinfo.NodeSize.SIZE_1; import org.graalvm.compiler.core.common.type.ArithmeticOpTable; @@ -38,7 +38,7 @@ /** * Absolute value. */ -@NodeInfo(cycles = CYCLES_3, size = SIZE_1) +@NodeInfo(cycles = CYCLES_2, size = SIZE_1) public final class AbsNode extends UnaryArithmeticNode implements ArithmeticLIRLowerable, NarrowableArithmeticNode { public static final NodeClass TYPE = NodeClass.create(AbsNode.class); diff -r d5572756efd6 -r ab5b504181d8 hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/calc/CompareNode.java --- a/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/calc/CompareNode.java Tue Apr 18 20:10:55 2017 -0700 +++ b/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/calc/CompareNode.java Wed Apr 19 04:10:56 2017 +0000 @@ -25,6 +25,7 @@ import static org.graalvm.compiler.core.common.GraalOptions.GeneratePIC; import static org.graalvm.compiler.nodeinfo.NodeCycles.CYCLES_1; +import jdk.vm.ci.meta.MetaAccessProvider; import org.graalvm.compiler.core.common.calc.Condition; import org.graalvm.compiler.core.common.type.AbstractObjectStamp; import org.graalvm.compiler.core.common.type.AbstractPointerStamp; @@ -32,7 +33,6 @@ import org.graalvm.compiler.debug.GraalError; import org.graalvm.compiler.graph.NodeClass; import org.graalvm.compiler.graph.spi.Canonicalizable; -import org.graalvm.compiler.graph.spi.CanonicalizerTool; import org.graalvm.compiler.nodeinfo.NodeInfo; import org.graalvm.compiler.nodes.BinaryOpLogicNode; import org.graalvm.compiler.nodes.ConstantNode; @@ -45,6 +45,7 @@ import jdk.vm.ci.meta.Constant; import jdk.vm.ci.meta.ConstantReflectionProvider; import jdk.vm.ci.meta.PrimitiveConstant; +import org.graalvm.compiler.options.OptionValues; @NodeInfo(cycles = CYCLES_1) public abstract class CompareNode extends BinaryOpLogicNode implements Canonicalizable.Binary { @@ -83,74 +84,6 @@ return this.unorderedIsTrue; } - private ValueNode optimizeConditional(Constant constant, ConditionalNode conditionalNode, ConstantReflectionProvider constantReflection, Condition cond) { - Constant trueConstant = conditionalNode.trueValue().asConstant(); - Constant falseConstant = conditionalNode.falseValue().asConstant(); - - if (falseConstant != null && trueConstant != null && constantReflection != null) { - boolean trueResult = cond.foldCondition(trueConstant, constant, constantReflection, unorderedIsTrue()); - boolean falseResult = cond.foldCondition(falseConstant, constant, constantReflection, unorderedIsTrue()); - - if (trueResult == falseResult) { - return LogicConstantNode.forBoolean(trueResult); - } else { - if (trueResult) { - assert falseResult == false; - return conditionalNode.condition(); - } else { - assert falseResult == true; - return LogicNegationNode.create(conditionalNode.condition()); - - } - } - } - return this; - } - - protected ValueNode optimizeNormalizeCmp(Constant constant, NormalizeCompareNode normalizeNode, boolean mirrored) { - throw new GraalError("NormalizeCompareNode connected to %s (%s %s %s)", this, constant, normalizeNode, mirrored); - } - - @Override - public ValueNode canonical(CanonicalizerTool tool, ValueNode forX, ValueNode forY) { - ConstantReflectionProvider constantReflection = tool.getConstantReflection(); - LogicNode constantCondition = tryConstantFold(condition(), forX, forY, constantReflection, unorderedIsTrue()); - if (constantCondition != null) { - return constantCondition; - } - ValueNode result; - if (forX.isConstant()) { - if ((result = canonicalizeSymmetricConstant(tool, forX.asConstant(), forY, true)) != this) { - return result; - } - } else if (forY.isConstant()) { - if ((result = canonicalizeSymmetricConstant(tool, forY.asConstant(), forX, false)) != this) { - return result; - } - } else if (forX instanceof ConvertNode && forY instanceof ConvertNode) { - ConvertNode convertX = (ConvertNode) forX; - ConvertNode convertY = (ConvertNode) forY; - if (convertX.preservesOrder(condition()) && convertY.preservesOrder(condition()) && convertX.getValue().stamp().isCompatible(convertY.getValue().stamp())) { - boolean supported = true; - if (convertX.getValue().stamp() instanceof IntegerStamp) { - IntegerStamp intStamp = (IntegerStamp) convertX.getValue().stamp(); - supported = tool.supportSubwordCompare(intStamp.getBits()); - } - - if (supported) { - boolean multiUsage = (convertX.asNode().hasMoreThanOneUsage() || convertY.asNode().hasMoreThanOneUsage()); - if ((forX instanceof ZeroExtendNode || forX instanceof SignExtendNode) && multiUsage) { - // Do not perform for zero or sign extend if there are multiple usages of - // the value. - return this; - } - return duplicateModified(convertX.getValue(), convertY.getValue()); - } - } - } - return this; - } - public static LogicNode tryConstantFold(Condition condition, ValueNode forX, ValueNode forY, ConstantReflectionProvider constantReflection, boolean unorderedIsTrue) { if (forX.isConstant() && forY.isConstant() && (constantReflection != null || forX.asConstant() instanceof PrimitiveConstant)) { return LogicConstantNode.forBoolean(condition.foldCondition(forX.asConstant(), forY.asConstant(), constantReflection, unorderedIsTrue)); @@ -175,56 +108,129 @@ return condition == Condition.EQ; } - protected abstract LogicNode duplicateModified(ValueNode newX, ValueNode newY); - - protected ValueNode canonicalizeSymmetricConstant(CanonicalizerTool tool, Constant constant, ValueNode nonConstant, boolean mirrored) { - if (nonConstant instanceof ConditionalNode) { - return optimizeConditional(constant, (ConditionalNode) nonConstant, tool.getConstantReflection(), mirrored ? condition().mirror() : condition()); - } else if (nonConstant instanceof NormalizeCompareNode) { - return optimizeNormalizeCmp(constant, (NormalizeCompareNode) nonConstant, mirrored); - } else if (nonConstant instanceof ConvertNode) { - ConvertNode convert = (ConvertNode) nonConstant; - boolean multiUsage = (convert.asNode().hasMoreThanOneUsage() && convert.getValue().hasExactlyOneUsage()); - if ((convert instanceof ZeroExtendNode || convert instanceof SignExtendNode) && multiUsage) { - // Do not perform for zero or sign extend if it could introduce - // new live values. - return this; + public abstract static class CompareOp { + public LogicNode canonical(ConstantReflectionProvider constantReflection, MetaAccessProvider metaAccess, OptionValues options, Integer smallestCompareWidth, Condition condition, + boolean unorderedIsTrue, ValueNode forX, ValueNode forY) { + LogicNode constantCondition = tryConstantFold(condition, forX, forY, constantReflection, unorderedIsTrue); + if (constantCondition != null) { + return constantCondition; } - - boolean supported = true; - if (convert.getValue().stamp() instanceof IntegerStamp) { - IntegerStamp intStamp = (IntegerStamp) convert.getValue().stamp(); - supported = tool.supportSubwordCompare(intStamp.getBits()); - } + LogicNode result; + if (forX.isConstant()) { + if ((result = canonicalizeSymmetricConstant(constantReflection, metaAccess, options, smallestCompareWidth, condition, forX.asConstant(), forY, true, unorderedIsTrue)) != null) { + return result; + } + } else if (forY.isConstant()) { + if ((result = canonicalizeSymmetricConstant(constantReflection, metaAccess, options, smallestCompareWidth, condition, forY.asConstant(), forX, false, unorderedIsTrue)) != null) { + return result; + } + } else if (forX instanceof ConvertNode && forY instanceof ConvertNode) { + ConvertNode convertX = (ConvertNode) forX; + ConvertNode convertY = (ConvertNode) forY; + if (convertX.preservesOrder(condition) && convertY.preservesOrder(condition) && convertX.getValue().stamp().isCompatible(convertY.getValue().stamp())) { + boolean supported = true; + if (convertX.getValue().stamp() instanceof IntegerStamp) { + IntegerStamp intStamp = (IntegerStamp) convertX.getValue().stamp(); + supported = smallestCompareWidth != null && intStamp.getBits() >= smallestCompareWidth; + } - if (supported) { - ConstantNode newConstant = canonicalConvertConstant(tool, convert, constant); - if (newConstant != null) { - if (mirrored) { - return duplicateModified(newConstant, convert.getValue()); - } else { - return duplicateModified(convert.getValue(), newConstant); + if (supported) { + boolean multiUsage = (convertX.asNode().hasMoreThanOneUsage() || convertY.asNode().hasMoreThanOneUsage()); + if ((forX instanceof ZeroExtendNode || forX instanceof SignExtendNode) && multiUsage) { + // Do not perform for zero or sign extend if there are multiple usages + // of the value. + return null; + } + return duplicateModified(convertX.getValue(), convertY.getValue(), unorderedIsTrue); } } } + return null; + } + + protected LogicNode canonicalizeSymmetricConstant(ConstantReflectionProvider constantReflection, MetaAccessProvider metaAccess, OptionValues options, Integer smallestCompareWidth, + Condition condition, Constant constant, ValueNode nonConstant, boolean mirrored, boolean unorderedIsTrue) { + if (nonConstant instanceof ConditionalNode) { + return optimizeConditional(constant, (ConditionalNode) nonConstant, constantReflection, mirrored ? condition.mirror() : condition, unorderedIsTrue); + } else if (nonConstant instanceof NormalizeCompareNode) { + return optimizeNormalizeCompare(constantReflection, metaAccess, options, smallestCompareWidth, constant, (NormalizeCompareNode) nonConstant, mirrored); + } else if (nonConstant instanceof ConvertNode) { + ConvertNode convert = (ConvertNode) nonConstant; + boolean multiUsage = (convert.asNode().hasMoreThanOneUsage() && convert.getValue().hasExactlyOneUsage()); + if ((convert instanceof ZeroExtendNode || convert instanceof SignExtendNode) && multiUsage) { + // Do not perform for zero or sign extend if it could introduce + // new live values. + return null; + } + + boolean supported = true; + if (convert.getValue().stamp() instanceof IntegerStamp) { + IntegerStamp intStamp = (IntegerStamp) convert.getValue().stamp(); + supported = smallestCompareWidth != null && intStamp.getBits() > smallestCompareWidth; + } + + if (supported) { + ConstantNode newConstant = canonicalConvertConstant(constantReflection, metaAccess, options, condition, convert, constant); + if (newConstant != null) { + if (mirrored) { + return duplicateModified(newConstant, convert.getValue(), unorderedIsTrue); + } else { + return duplicateModified(convert.getValue(), newConstant, unorderedIsTrue); + } + } + } + } + + return null; } - return this; - } + private static ConstantNode canonicalConvertConstant(ConstantReflectionProvider constantReflection, MetaAccessProvider metaAccess, OptionValues options, Condition condition, + ConvertNode convert, Constant constant) { + if (convert.preservesOrder(condition, constant, constantReflection)) { + Constant reverseConverted = convert.reverse(constant, constantReflection); + if (reverseConverted != null && convert.convert(reverseConverted, constantReflection).equals(constant)) { + if (GeneratePIC.getValue(options)) { + // We always want uncompressed constants + return null; + } + return ConstantNode.forConstant(convert.getValue().stamp(), reverseConverted, metaAccess); + } + } + return null; + } + + @SuppressWarnings("unused") + protected LogicNode optimizeNormalizeCompare(ConstantReflectionProvider constantReflection, MetaAccessProvider metaAccess, OptionValues options, Integer smallestCompareWidth, + Constant constant, NormalizeCompareNode normalizeNode, boolean mirrored) { + throw new GraalError("NormalizeCompareNode connected to %s (%s %s %s)", this, constant, normalizeNode, mirrored); + } - private ConstantNode canonicalConvertConstant(CanonicalizerTool tool, ConvertNode convert, Constant constant) { - ConstantReflectionProvider constantReflection = tool.getConstantReflection(); - if (convert.preservesOrder(condition(), constant, constantReflection)) { - Constant reverseConverted = convert.reverse(constant, constantReflection); - if (reverseConverted != null && convert.convert(reverseConverted, constantReflection).equals(constant)) { - if (GeneratePIC.getValue(tool.getOptions())) { - // We always want uncompressed constants - return null; + private static LogicNode optimizeConditional(Constant constant, ConditionalNode conditionalNode, ConstantReflectionProvider constantReflection, Condition cond, boolean unorderedIsTrue) { + Constant trueConstant = conditionalNode.trueValue().asConstant(); + Constant falseConstant = conditionalNode.falseValue().asConstant(); + + if (falseConstant != null && trueConstant != null && constantReflection != null) { + boolean trueResult = cond.foldCondition(trueConstant, constant, constantReflection, unorderedIsTrue); + boolean falseResult = cond.foldCondition(falseConstant, constant, constantReflection, unorderedIsTrue); + + if (trueResult == falseResult) { + return LogicConstantNode.forBoolean(trueResult); + } else { + if (trueResult) { + assert falseResult == false; + return conditionalNode.condition(); + } else { + assert falseResult == true; + return LogicNegationNode.create(conditionalNode.condition()); + + } } - return ConstantNode.forConstant(convert.getValue().stamp(), reverseConverted, tool.getMetaAccess()); } + + return null; } - return null; + + protected abstract LogicNode duplicateModified(ValueNode newW, ValueNode newY, boolean unorderedIsTrue); } public static LogicNode createCompareNode(StructuredGraph graph, Condition condition, ValueNode x, ValueNode y, ConstantReflectionProvider constantReflection) { @@ -258,4 +264,39 @@ return comparison; } + + public static LogicNode createCompareNode(StructuredGraph graph, ConstantReflectionProvider constantReflection, MetaAccessProvider metaAccess, OptionValues options, Integer smallestCompareWidth, + Condition condition, ValueNode x, ValueNode y) { + LogicNode result = createCompareNode(constantReflection, metaAccess, options, smallestCompareWidth, condition, x, y); + return (result.graph() == null ? graph.addOrUniqueWithInputs(result) : result); + } + + public static LogicNode createCompareNode(ConstantReflectionProvider constantReflection, MetaAccessProvider metaAccess, OptionValues options, Integer smallestCompareWidth, + Condition condition, ValueNode x, ValueNode y) { + assert x.getStackKind() == y.getStackKind(); + assert condition.isCanonical(); + assert !x.getStackKind().isNumericFloat(); + + LogicNode comparison; + if (condition == Condition.EQ) { + if (x.stamp() instanceof AbstractObjectStamp) { + assert smallestCompareWidth == null; + comparison = ObjectEqualsNode.create(constantReflection, metaAccess, options, x, y); + } else if (x.stamp() instanceof AbstractPointerStamp) { + comparison = PointerEqualsNode.create(x, y); + } else { + assert x.getStackKind().isNumericInteger(); + comparison = IntegerEqualsNode.create(constantReflection, metaAccess, options, smallestCompareWidth, x, y); + } + } else if (condition == Condition.LT) { + assert x.getStackKind().isNumericInteger(); + comparison = IntegerLessThanNode.create(constantReflection, metaAccess, options, smallestCompareWidth, x, y); + } else { + assert condition == Condition.BT; + assert x.getStackKind().isNumericInteger(); + comparison = IntegerBelowNode.create(constantReflection, metaAccess, options, smallestCompareWidth, x, y); + } + + return comparison; + } } diff -r d5572756efd6 -r ab5b504181d8 hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/calc/DivNode.java --- a/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/calc/DivNode.java Tue Apr 18 20:10:55 2017 -0700 +++ b/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/calc/DivNode.java Wed Apr 19 04:10:56 2017 +0000 @@ -22,6 +22,8 @@ */ package org.graalvm.compiler.nodes.calc; +import static org.graalvm.compiler.nodeinfo.NodeCycles.CYCLES_32; + import org.graalvm.compiler.core.common.type.ArithmeticOpTable; import org.graalvm.compiler.core.common.type.ArithmeticOpTable.BinaryOp; import org.graalvm.compiler.core.common.type.ArithmeticOpTable.BinaryOp.Div; @@ -29,7 +31,6 @@ import org.graalvm.compiler.graph.NodeClass; import org.graalvm.compiler.graph.spi.CanonicalizerTool; import org.graalvm.compiler.lir.gen.ArithmeticLIRGeneratorTool; -import org.graalvm.compiler.nodeinfo.NodeCycles; import org.graalvm.compiler.nodeinfo.NodeInfo; import org.graalvm.compiler.nodes.ConstantNode; import org.graalvm.compiler.nodes.ValueNode; @@ -39,7 +40,7 @@ import jdk.vm.ci.meta.Constant; import jdk.vm.ci.meta.PrimitiveConstant; -@NodeInfo(shortName = "/", cycles = NodeCycles.CYCLES_30) +@NodeInfo(shortName = "/", cycles = CYCLES_32) public class DivNode extends BinaryArithmeticNode
{ public static final NodeClass TYPE = NodeClass.create(DivNode.class); diff -r d5572756efd6 -r ab5b504181d8 hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/calc/FloatConvertNode.java --- a/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/calc/FloatConvertNode.java Tue Apr 18 20:10:55 2017 -0700 +++ b/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/calc/FloatConvertNode.java Wed Apr 19 04:10:56 2017 +0000 @@ -22,7 +22,7 @@ */ package org.graalvm.compiler.nodes.calc; -import static org.graalvm.compiler.nodeinfo.NodeCycles.CYCLES_5; +import static org.graalvm.compiler.nodeinfo.NodeCycles.CYCLES_8; import java.util.EnumMap; @@ -46,7 +46,7 @@ * A {@code FloatConvert} converts between integers and floating point numbers according to Java * semantics. */ -@NodeInfo(cycles = CYCLES_5) +@NodeInfo(cycles = CYCLES_8) public final class FloatConvertNode extends UnaryArithmeticNode implements ConvertNode, Lowerable, ArithmeticLIRLowerable { public static final NodeClass TYPE = NodeClass.create(FloatConvertNode.class); diff -r d5572756efd6 -r ab5b504181d8 hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/calc/FloatEqualsNode.java --- a/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/calc/FloatEqualsNode.java Tue Apr 18 20:10:55 2017 -0700 +++ b/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/calc/FloatEqualsNode.java Wed Apr 19 04:10:56 2017 +0000 @@ -22,26 +22,31 @@ */ package org.graalvm.compiler.nodes.calc; +import jdk.vm.ci.meta.ConstantReflectionProvider; +import jdk.vm.ci.meta.MetaAccessProvider; +import jdk.vm.ci.meta.TriState; import org.graalvm.compiler.core.common.calc.Condition; import org.graalvm.compiler.core.common.type.FloatStamp; import org.graalvm.compiler.core.common.type.IntegerStamp; import org.graalvm.compiler.core.common.type.Stamp; import org.graalvm.compiler.debug.GraalError; +import org.graalvm.compiler.graph.Node; import org.graalvm.compiler.graph.NodeClass; import org.graalvm.compiler.graph.spi.Canonicalizable.BinaryCommutative; import org.graalvm.compiler.graph.spi.CanonicalizerTool; -import org.graalvm.compiler.nodeinfo.NodeCycles; import org.graalvm.compiler.nodeinfo.NodeInfo; import org.graalvm.compiler.nodes.LogicConstantNode; import org.graalvm.compiler.nodes.LogicNode; import org.graalvm.compiler.nodes.ValueNode; import org.graalvm.compiler.nodes.util.GraphUtil; +import org.graalvm.compiler.options.OptionValues; -import jdk.vm.ci.meta.TriState; +import static org.graalvm.compiler.nodeinfo.NodeCycles.CYCLES_2; -@NodeInfo(shortName = "==", cycles = NodeCycles.CYCLES_3) +@NodeInfo(shortName = "==", cycles = CYCLES_2) public final class FloatEqualsNode extends CompareNode implements BinaryCommutative { public static final NodeClass TYPE = NodeClass.create(FloatEqualsNode.class); + private static final FloatEqualsOp OP = new FloatEqualsOp(); public FloatEqualsNode(ValueNode x, ValueNode y) { super(TYPE, Condition.EQ, false, x, y); @@ -58,6 +63,15 @@ } } + public static LogicNode create(ConstantReflectionProvider constantReflection, MetaAccessProvider metaAccess, OptionValues options, Integer smallestCompareWidth, + ValueNode x, ValueNode y) { + LogicNode value = OP.canonical(constantReflection, metaAccess, options, smallestCompareWidth, Condition.EQ, false, x, y); + if (value != null) { + return value; + } + return create(x, y); + } + @Override public boolean isIdentityComparison() { FloatStamp xStamp = (FloatStamp) x.stamp(); @@ -72,33 +86,46 @@ } @Override - public ValueNode canonical(CanonicalizerTool tool, ValueNode forX, ValueNode forY) { - ValueNode result = super.canonical(tool, forX, forY); - if (result != this) { - return result; - } - Stamp xStampGeneric = forX.stamp(); - Stamp yStampGeneric = forY.stamp(); - if (xStampGeneric instanceof FloatStamp && yStampGeneric instanceof FloatStamp) { - FloatStamp xStamp = (FloatStamp) xStampGeneric; - FloatStamp yStamp = (FloatStamp) yStampGeneric; - if (GraphUtil.unproxify(forX) == GraphUtil.unproxify(forY) && xStamp.isNonNaN() && yStamp.isNonNaN()) { - return LogicConstantNode.tautology(); - } else if (xStamp.alwaysDistinct(yStamp)) { - return LogicConstantNode.contradiction(); - } + public Node canonical(CanonicalizerTool tool, ValueNode forX, ValueNode forY) { + ValueNode value = OP.canonical(tool.getConstantReflection(), tool.getMetaAccess(), tool.getOptions(), tool.smallestCompareWidth(), Condition.EQ, unorderedIsTrue, forX, forY); + if (value != null) { + return value; } return this; } - @Override - protected CompareNode duplicateModified(ValueNode newX, ValueNode newY) { - if (newX.stamp() instanceof FloatStamp && newY.stamp() instanceof FloatStamp) { - return new FloatEqualsNode(newX, newY); - } else if (newX.stamp() instanceof IntegerStamp && newY.stamp() instanceof IntegerStamp) { - return new IntegerEqualsNode(newX, newY); + public static class FloatEqualsOp extends CompareOp { + + @Override + public LogicNode canonical(ConstantReflectionProvider constantReflection, MetaAccessProvider metaAccess, OptionValues options, Integer smallestCompareWidth, Condition condition, + boolean unorderedIsTrue, ValueNode forX, ValueNode forY) { + LogicNode result = super.canonical(constantReflection, metaAccess, options, smallestCompareWidth, condition, unorderedIsTrue, forX, forY); + if (result != null) { + return result; + } + Stamp xStampGeneric = forX.stamp(); + Stamp yStampGeneric = forY.stamp(); + if (xStampGeneric instanceof FloatStamp && yStampGeneric instanceof FloatStamp) { + FloatStamp xStamp = (FloatStamp) xStampGeneric; + FloatStamp yStamp = (FloatStamp) yStampGeneric; + if (GraphUtil.unproxify(forX) == GraphUtil.unproxify(forY) && xStamp.isNonNaN() && yStamp.isNonNaN()) { + return LogicConstantNode.tautology(); + } else if (xStamp.alwaysDistinct(yStamp)) { + return LogicConstantNode.contradiction(); + } + } + return null; } - throw GraalError.shouldNotReachHere(); + + @Override + protected CompareNode duplicateModified(ValueNode newX, ValueNode newY, boolean unorderedIsTrue) { + if (newX.stamp() instanceof FloatStamp && newY.stamp() instanceof FloatStamp) { + return new FloatEqualsNode(newX, newY); + } else if (newX.stamp() instanceof IntegerStamp && newY.stamp() instanceof IntegerStamp) { + return new IntegerEqualsNode(newX, newY); + } + throw GraalError.shouldNotReachHere(); + } } @Override diff -r d5572756efd6 -r ab5b504181d8 hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/calc/FloatLessThanNode.java --- a/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/calc/FloatLessThanNode.java Tue Apr 18 20:10:55 2017 -0700 +++ b/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/calc/FloatLessThanNode.java Wed Apr 19 04:10:56 2017 +0000 @@ -22,25 +22,30 @@ */ package org.graalvm.compiler.nodes.calc; +import jdk.vm.ci.meta.ConstantReflectionProvider; +import jdk.vm.ci.meta.MetaAccessProvider; +import jdk.vm.ci.meta.TriState; import org.graalvm.compiler.core.common.calc.Condition; import org.graalvm.compiler.core.common.type.FloatStamp; import org.graalvm.compiler.core.common.type.IntegerStamp; import org.graalvm.compiler.core.common.type.Stamp; import org.graalvm.compiler.debug.GraalError; +import org.graalvm.compiler.graph.Node; import org.graalvm.compiler.graph.NodeClass; import org.graalvm.compiler.graph.spi.CanonicalizerTool; -import org.graalvm.compiler.nodeinfo.NodeCycles; import org.graalvm.compiler.nodeinfo.NodeInfo; import org.graalvm.compiler.nodes.LogicConstantNode; import org.graalvm.compiler.nodes.LogicNode; import org.graalvm.compiler.nodes.ValueNode; import org.graalvm.compiler.nodes.util.GraphUtil; +import org.graalvm.compiler.options.OptionValues; -import jdk.vm.ci.meta.TriState; +import static org.graalvm.compiler.nodeinfo.NodeCycles.CYCLES_2; -@NodeInfo(shortName = "<", cycles = NodeCycles.CYCLES_3) +@NodeInfo(shortName = "<", cycles = CYCLES_2) public final class FloatLessThanNode extends CompareNode { public static final NodeClass TYPE = NodeClass.create(FloatLessThanNode.class); + private static final FloatLessThanOp OP = new FloatLessThanOp(); public FloatLessThanNode(ValueNode x, ValueNode y, boolean unorderedIsTrue) { super(TYPE, Condition.LT, unorderedIsTrue, x, y); @@ -52,31 +57,52 @@ LogicNode result = CompareNode.tryConstantFoldPrimitive(Condition.LT, x, y, unorderedIsTrue); if (result != null) { return result; - } else { - return new FloatLessThanNode(x, y, unorderedIsTrue); } + return new FloatLessThanNode(x, y, unorderedIsTrue); + } + + public static LogicNode create(ConstantReflectionProvider constantReflection, MetaAccessProvider metaAccess, OptionValues options, Integer smallestCompareWidth, + ValueNode x, ValueNode y, boolean unorderedIsTrue) { + LogicNode result = OP.canonical(constantReflection, metaAccess, options, smallestCompareWidth, Condition.LT, unorderedIsTrue, x, y); + if (result != null) { + return result; + } + return create(x, y, unorderedIsTrue); } @Override - public ValueNode canonical(CanonicalizerTool tool, ValueNode forX, ValueNode forY) { - ValueNode result = super.canonical(tool, forX, forY); - if (result != this) { - return result; - } - if (GraphUtil.unproxify(forX) == GraphUtil.unproxify(forY) && !unorderedIsTrue()) { - return LogicConstantNode.contradiction(); + public Node canonical(CanonicalizerTool tool, ValueNode forX, ValueNode forY) { + ValueNode value = OP.canonical(tool.getConstantReflection(), tool.getMetaAccess(), tool.getOptions(), tool.smallestCompareWidth(), Condition.LT, unorderedIsTrue, forX, forY); + if (value != null) { + return value; } return this; } - @Override - protected CompareNode duplicateModified(ValueNode newX, ValueNode newY) { - if (newX.stamp() instanceof FloatStamp && newY.stamp() instanceof FloatStamp) { - return new FloatLessThanNode(newX, newY, unorderedIsTrue); - } else if (newX.stamp() instanceof IntegerStamp && newY.stamp() instanceof IntegerStamp) { - return new IntegerLessThanNode(newX, newY); + public static class FloatLessThanOp extends CompareOp { + + @Override + public LogicNode canonical(ConstantReflectionProvider constantReflection, MetaAccessProvider metaAccess, OptionValues options, Integer smallestCompareWidth, Condition condition, + boolean unorderedIsTrue, ValueNode forX, ValueNode forY) { + LogicNode result = super.canonical(constantReflection, metaAccess, options, smallestCompareWidth, condition, unorderedIsTrue, forX, forY); + if (result != null) { + return result; + } + if (GraphUtil.unproxify(forX) == GraphUtil.unproxify(forY) && !unorderedIsTrue) { + return LogicConstantNode.contradiction(); + } + return null; } - throw GraalError.shouldNotReachHere(); + + @Override + protected CompareNode duplicateModified(ValueNode newX, ValueNode newY, boolean unorderedIsTrue) { + if (newX.stamp() instanceof FloatStamp && newY.stamp() instanceof FloatStamp) { + return new FloatLessThanNode(newX, newY, unorderedIsTrue); + } else if (newX.stamp() instanceof IntegerStamp && newY.stamp() instanceof IntegerStamp) { + return new IntegerLessThanNode(newX, newY); + } + throw GraalError.shouldNotReachHere(); + } } @Override diff -r d5572756efd6 -r ab5b504181d8 hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/calc/IntegerBelowNode.java --- a/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/calc/IntegerBelowNode.java Tue Apr 18 20:10:55 2017 -0700 +++ b/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/calc/IntegerBelowNode.java Wed Apr 19 04:10:56 2017 +0000 @@ -22,16 +22,21 @@ */ package org.graalvm.compiler.nodes.calc; +import jdk.vm.ci.meta.ConstantReflectionProvider; +import jdk.vm.ci.meta.MetaAccessProvider; import org.graalvm.compiler.core.common.NumUtil; import org.graalvm.compiler.core.common.calc.Condition; import org.graalvm.compiler.core.common.type.IntegerStamp; import org.graalvm.compiler.core.common.type.StampFactory; +import org.graalvm.compiler.graph.Node; import org.graalvm.compiler.graph.NodeClass; +import org.graalvm.compiler.graph.spi.CanonicalizerTool; import org.graalvm.compiler.nodeinfo.NodeInfo; import org.graalvm.compiler.nodes.LogicNode; import org.graalvm.compiler.nodes.ValueNode; import jdk.vm.ci.code.CodeUtil; +import org.graalvm.compiler.options.OptionValues; @NodeInfo(shortName = "|<|") public final class IntegerBelowNode extends IntegerLowerThanNode { @@ -48,13 +53,29 @@ return OP.create(x, y); } + public static LogicNode create(ConstantReflectionProvider constantReflection, MetaAccessProvider metaAccess, OptionValues options, Integer smallestCompareWidth, ValueNode x, ValueNode y) { + LogicNode value = OP.canonical(constantReflection, metaAccess, options, smallestCompareWidth, OP.getCondition(), false, x, y); + if (value != null) { + return value; + } + return create(x, y); + } + @Override - protected CompareNode duplicateModified(ValueNode newX, ValueNode newY) { - assert newX.stamp() instanceof IntegerStamp && newY.stamp() instanceof IntegerStamp; - return new IntegerBelowNode(newX, newY); + public Node canonical(CanonicalizerTool tool, ValueNode forX, ValueNode forY) { + ValueNode value = OP.canonical(tool.getConstantReflection(), tool.getMetaAccess(), tool.getOptions(), tool.smallestCompareWidth(), OP.getCondition(), false, forX, forY); + if (value != null) { + return value; + } + return this; } public static class BelowOp extends LowerOp { + @Override + protected CompareNode duplicateModified(ValueNode newX, ValueNode newY, boolean unorderedIsTrue) { + assert newX.stamp() instanceof IntegerStamp && newY.stamp() instanceof IntegerStamp; + return new IntegerBelowNode(newX, newY); + } @Override protected long upperBound(IntegerStamp stamp) { diff -r d5572756efd6 -r ab5b504181d8 hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/calc/IntegerDivRemNode.java --- a/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/calc/IntegerDivRemNode.java Tue Apr 18 20:10:55 2017 -0700 +++ b/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/calc/IntegerDivRemNode.java Wed Apr 19 04:10:56 2017 +0000 @@ -22,8 +22,8 @@ */ package org.graalvm.compiler.nodes.calc; -import static org.graalvm.compiler.nodeinfo.NodeCycles.CYCLES_40; -import static org.graalvm.compiler.nodeinfo.NodeSize.SIZE_2; +import static org.graalvm.compiler.nodeinfo.NodeCycles.CYCLES_32; +import static org.graalvm.compiler.nodeinfo.NodeSize.SIZE_1; import org.graalvm.compiler.core.common.type.IntegerStamp; import org.graalvm.compiler.core.common.type.Stamp; @@ -33,7 +33,7 @@ import org.graalvm.compiler.nodes.spi.Lowerable; import org.graalvm.compiler.nodes.spi.LoweringTool; -@NodeInfo(cycles = CYCLES_40, size = SIZE_2) +@NodeInfo(cycles = CYCLES_32, size = SIZE_1) public abstract class IntegerDivRemNode extends FixedBinaryNode implements Lowerable { public static final NodeClass TYPE = NodeClass.create(IntegerDivRemNode.class); diff -r d5572756efd6 -r ab5b504181d8 hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/calc/IntegerEqualsNode.java --- a/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/calc/IntegerEqualsNode.java Tue Apr 18 20:10:55 2017 -0700 +++ b/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/calc/IntegerEqualsNode.java Wed Apr 19 04:10:56 2017 +0000 @@ -22,12 +22,15 @@ */ package org.graalvm.compiler.nodes.calc; +import jdk.vm.ci.meta.ConstantReflectionProvider; +import jdk.vm.ci.meta.MetaAccessProvider; import org.graalvm.compiler.core.common.calc.Condition; import org.graalvm.compiler.core.common.type.AbstractPointerStamp; import org.graalvm.compiler.core.common.type.FloatStamp; import org.graalvm.compiler.core.common.type.IntegerStamp; import org.graalvm.compiler.core.common.type.Stamp; import org.graalvm.compiler.debug.GraalError; +import org.graalvm.compiler.graph.Node; import org.graalvm.compiler.graph.NodeClass; import org.graalvm.compiler.graph.spi.Canonicalizable.BinaryCommutative; import org.graalvm.compiler.graph.spi.CanonicalizerTool; @@ -43,10 +46,12 @@ import jdk.vm.ci.meta.JavaKind; import jdk.vm.ci.meta.PrimitiveConstant; import jdk.vm.ci.meta.TriState; +import org.graalvm.compiler.options.OptionValues; @NodeInfo(shortName = "==") public final class IntegerEqualsNode extends CompareNode implements BinaryCommutative { public static final NodeClass TYPE = NodeClass.create(IntegerEqualsNode.class); + private static final IntegerEqualsOp OP = new IntegerEqualsOp(); public IntegerEqualsNode(ValueNode x, ValueNode y) { super(TYPE, Condition.EQ, false, x, y); @@ -58,165 +63,201 @@ LogicNode result = CompareNode.tryConstantFoldPrimitive(Condition.EQ, x, y, false); if (result != null) { return result; - } else { - if (x instanceof ConditionalNode) { - ConditionalNode conditionalNode = (ConditionalNode) x; - if (conditionalNode.trueValue() == y) { - return conditionalNode.condition(); - } - if (conditionalNode.falseValue() == y) { - return LogicNegationNode.create(conditionalNode.condition()); - } - } else if (y instanceof ConditionalNode) { - ConditionalNode conditionalNode = (ConditionalNode) y; - if (conditionalNode.trueValue() == x) { - return conditionalNode.condition(); - } - if (conditionalNode.falseValue() == x) { - return LogicNegationNode.create(conditionalNode.condition()); - } + } + if (x instanceof ConditionalNode) { + ConditionalNode conditionalNode = (ConditionalNode) x; + if (conditionalNode.trueValue() == y) { + return conditionalNode.condition(); + } + if (conditionalNode.falseValue() == y) { + return LogicNegationNode.create(conditionalNode.condition()); + } + } else if (y instanceof ConditionalNode) { + ConditionalNode conditionalNode = (ConditionalNode) y; + if (conditionalNode.trueValue() == x) { + return conditionalNode.condition(); } + if (conditionalNode.falseValue() == x) { + return LogicNegationNode.create(conditionalNode.condition()); + } + } + return new IntegerEqualsNode(x, y).maybeCommuteInputs(); + } - return new IntegerEqualsNode(x, y).maybeCommuteInputs(); + public static LogicNode create(ConstantReflectionProvider constantReflection, MetaAccessProvider metaAccess, OptionValues options, Integer smallestCompareWidth, ValueNode x, ValueNode y) { + LogicNode value = OP.canonical(constantReflection, metaAccess, options, smallestCompareWidth, Condition.EQ, false, x, y); + if (value != null) { + return value; } + return create(x, y); } @Override - protected ValueNode optimizeNormalizeCmp(Constant constant, NormalizeCompareNode normalizeNode, boolean mirrored) { - PrimitiveConstant primitive = (PrimitiveConstant) constant; - if (primitive.getJavaKind() == JavaKind.Int && primitive.asInt() == 0) { - ValueNode a = mirrored ? normalizeNode.getY() : normalizeNode.getX(); - ValueNode b = mirrored ? normalizeNode.getX() : normalizeNode.getY(); - - if (normalizeNode.getX().getStackKind() == JavaKind.Double || normalizeNode.getX().getStackKind() == JavaKind.Float) { - return new FloatEqualsNode(a, b); - } else { - return new IntegerEqualsNode(a, b); - } + public Node canonical(CanonicalizerTool tool, ValueNode forX, ValueNode forY) { + ValueNode value = OP.canonical(tool.getConstantReflection(), tool.getMetaAccess(), tool.getOptions(), tool.smallestCompareWidth(), Condition.EQ, false, forX, forY); + if (value != null) { + return value; } return this; } - @Override - protected CompareNode duplicateModified(ValueNode newX, ValueNode newY) { - if (newX.stamp() instanceof FloatStamp && newY.stamp() instanceof FloatStamp) { - return new FloatEqualsNode(newX, newY); - } else if (newX.stamp() instanceof IntegerStamp && newY.stamp() instanceof IntegerStamp) { - return new IntegerEqualsNode(newX, newY); - } else if (newX.stamp() instanceof AbstractPointerStamp && newY.stamp() instanceof AbstractPointerStamp) { - return new IntegerEqualsNode(newX, newY); - } - throw GraalError.shouldNotReachHere(); - } + public static class IntegerEqualsOp extends CompareOp { + @Override + protected LogicNode optimizeNormalizeCompare(ConstantReflectionProvider constantReflection, MetaAccessProvider metaAccess, OptionValues options, Integer smallestCompareWidth, + Constant constant, NormalizeCompareNode normalizeNode, boolean mirrored) { + PrimitiveConstant primitive = (PrimitiveConstant) constant; + ValueNode a = normalizeNode.getX(); + ValueNode b = normalizeNode.getY(); + long cst = primitive.asLong(); - @Override - public ValueNode canonical(CanonicalizerTool tool, ValueNode forX, ValueNode forY) { - if (GraphUtil.unproxify(forX) == GraphUtil.unproxify(forY)) { - return LogicConstantNode.tautology(); - } else if (forX.stamp().alwaysDistinct(forY.stamp())) { - return LogicConstantNode.contradiction(); - } - if (forX instanceof AddNode && forY instanceof AddNode) { - AddNode addX = (AddNode) forX; - AddNode addY = (AddNode) forY; - ValueNode v1 = null; - ValueNode v2 = null; - if (addX.getX() == addY.getX()) { - v1 = addX.getY(); - v2 = addY.getY(); - } else if (addX.getX() == addY.getY()) { - v1 = addX.getY(); - v2 = addY.getX(); - } else if (addX.getY() == addY.getX()) { - v1 = addX.getX(); - v2 = addY.getY(); - } else if (addX.getY() == addY.getY()) { - v1 = addX.getX(); - v2 = addY.getX(); - } - if (v1 != null) { - assert v2 != null; - return create(v1, v2); + if (cst == 0) { + if (normalizeNode.getX().getStackKind() == JavaKind.Double || normalizeNode.getX().getStackKind() == JavaKind.Float) { + return FloatEqualsNode.create(constantReflection, metaAccess, options, smallestCompareWidth, a, b); + } else { + return IntegerEqualsNode.create(constantReflection, metaAccess, options, smallestCompareWidth, a, b); + } + } else if (cst == 1) { + if (normalizeNode.getX().getStackKind() == JavaKind.Double || normalizeNode.getX().getStackKind() == JavaKind.Float) { + return FloatLessThanNode.create(b, a, !normalizeNode.isUnorderedLess); + } else { + return IntegerLessThanNode.create(constantReflection, metaAccess, options, smallestCompareWidth, b, a); + } + } else if (cst == -1) { + if (normalizeNode.getX().getStackKind() == JavaKind.Double || normalizeNode.getX().getStackKind() == JavaKind.Float) { + return FloatLessThanNode.create(a, b, normalizeNode.isUnorderedLess); + } else { + return IntegerLessThanNode.create(constantReflection, metaAccess, options, smallestCompareWidth, a, b); + } + } else { + return LogicConstantNode.contradiction(); } } - return super.canonical(tool, forX, forY); - } + + @Override + protected CompareNode duplicateModified(ValueNode newX, ValueNode newY, boolean unorderedIsTrue) { + if (newX.stamp() instanceof FloatStamp && newY.stamp() instanceof FloatStamp) { + return new FloatEqualsNode(newX, newY); + } else if (newX.stamp() instanceof IntegerStamp && newY.stamp() instanceof IntegerStamp) { + return new IntegerEqualsNode(newX, newY); + } else if (newX.stamp() instanceof AbstractPointerStamp && newY.stamp() instanceof AbstractPointerStamp) { + return new IntegerEqualsNode(newX, newY); + } + throw GraalError.shouldNotReachHere(); + } + + @Override + public LogicNode canonical(ConstantReflectionProvider constantReflection, MetaAccessProvider metaAccess, OptionValues options, Integer smallestCompareWidth, Condition condition, + boolean unorderedIsTrue, ValueNode forX, ValueNode forY) { + if (GraphUtil.unproxify(forX) == GraphUtil.unproxify(forY)) { + return LogicConstantNode.tautology(); + } else if (forX.stamp().alwaysDistinct(forY.stamp())) { + return LogicConstantNode.contradiction(); + } + if (forX instanceof AddNode && forY instanceof AddNode) { + AddNode addX = (AddNode) forX; + AddNode addY = (AddNode) forY; + ValueNode v1 = null; + ValueNode v2 = null; + if (addX.getX() == addY.getX()) { + v1 = addX.getY(); + v2 = addY.getY(); + } else if (addX.getX() == addY.getY()) { + v1 = addX.getY(); + v2 = addY.getX(); + } else if (addX.getY() == addY.getX()) { + v1 = addX.getX(); + v2 = addY.getY(); + } else if (addX.getY() == addY.getY()) { + v1 = addX.getX(); + v2 = addY.getX(); + } + if (v1 != null) { + assert v2 != null; + return create(v1, v2); + } + } + return super.canonical(constantReflection, metaAccess, options, smallestCompareWidth, condition, unorderedIsTrue, forX, forY); + } - @Override - protected ValueNode canonicalizeSymmetricConstant(CanonicalizerTool tool, Constant constant, ValueNode nonConstant, boolean mirrored) { - if (constant instanceof PrimitiveConstant) { - PrimitiveConstant primitiveConstant = (PrimitiveConstant) constant; - IntegerStamp nonConstantStamp = ((IntegerStamp) nonConstant.stamp()); - if ((primitiveConstant.asLong() == 1 && nonConstantStamp.upperBound() == 1 && nonConstantStamp.lowerBound() == 0) || - (primitiveConstant.asLong() == -1 && nonConstantStamp.upperBound() == 0 && nonConstantStamp.lowerBound() == -1)) { - // nonConstant can only be 0 or 1 (respective -1), test against 0 instead of 1 - // (respective -1) for a more canonical graph and also to allow for faster execution - // on specific platforms. - return LogicNegationNode.create(IntegerEqualsNode.create(nonConstant, ConstantNode.forIntegerKind(nonConstant.getStackKind(), 0))); - } else if (primitiveConstant.asLong() == 0) { - if (nonConstant instanceof AndNode) { - AndNode andNode = (AndNode) nonConstant; - return new IntegerTestNode(andNode.getX(), andNode.getY()); - } else if (nonConstant instanceof SubNode) { - SubNode subNode = (SubNode) nonConstant; - return IntegerEqualsNode.create(subNode.getX(), subNode.getY()); - } else if (nonConstant instanceof ShiftNode && nonConstant.stamp() instanceof IntegerStamp) { - if (nonConstant instanceof LeftShiftNode) { - LeftShiftNode shift = (LeftShiftNode) nonConstant; - if (shift.getY().isConstant()) { - int mask = shift.getShiftAmountMask(); - int amount = shift.getY().asJavaConstant().asInt() & mask; - if (shift.getX().getStackKind() == JavaKind.Int) { - return new IntegerTestNode(shift.getX(), ConstantNode.forInt(-1 >>> amount)); - } else { - assert shift.getX().getStackKind() == JavaKind.Long; - return new IntegerTestNode(shift.getX(), ConstantNode.forLong(-1L >>> amount)); + @Override + protected LogicNode canonicalizeSymmetricConstant(ConstantReflectionProvider constantReflection, MetaAccessProvider metaAccess, OptionValues options, Integer smallestCompareWidth, + Condition condition, Constant constant, ValueNode nonConstant, boolean mirrored, boolean unorderedIsTrue) { + if (constant instanceof PrimitiveConstant) { + PrimitiveConstant primitiveConstant = (PrimitiveConstant) constant; + IntegerStamp nonConstantStamp = ((IntegerStamp) nonConstant.stamp()); + if ((primitiveConstant.asLong() == 1 && nonConstantStamp.upperBound() == 1 && nonConstantStamp.lowerBound() == 0) || + (primitiveConstant.asLong() == -1 && nonConstantStamp.upperBound() == 0 && nonConstantStamp.lowerBound() == -1)) { + // nonConstant can only be 0 or 1 (respective -1), test against 0 instead of 1 + // (respective -1) for a more canonical graph and also to allow for faster + // execution + // on specific platforms. + return LogicNegationNode.create( + IntegerEqualsNode.create(constantReflection, metaAccess, options, smallestCompareWidth, nonConstant, ConstantNode.forIntegerKind(nonConstant.getStackKind(), 0))); + } else if (primitiveConstant.asLong() == 0) { + if (nonConstant instanceof AndNode) { + AndNode andNode = (AndNode) nonConstant; + return new IntegerTestNode(andNode.getX(), andNode.getY()); + } else if (nonConstant instanceof SubNode) { + SubNode subNode = (SubNode) nonConstant; + return IntegerEqualsNode.create(constantReflection, metaAccess, options, smallestCompareWidth, subNode.getX(), subNode.getY()); + } else if (nonConstant instanceof ShiftNode && nonConstant.stamp() instanceof IntegerStamp) { + if (nonConstant instanceof LeftShiftNode) { + LeftShiftNode shift = (LeftShiftNode) nonConstant; + if (shift.getY().isConstant()) { + int mask = shift.getShiftAmountMask(); + int amount = shift.getY().asJavaConstant().asInt() & mask; + if (shift.getX().getStackKind() == JavaKind.Int) { + return new IntegerTestNode(shift.getX(), ConstantNode.forInt(-1 >>> amount)); + } else { + assert shift.getX().getStackKind() == JavaKind.Long; + return new IntegerTestNode(shift.getX(), ConstantNode.forLong(-1L >>> amount)); + } } - } - } else if (nonConstant instanceof RightShiftNode) { - RightShiftNode shift = (RightShiftNode) nonConstant; - if (shift.getY().isConstant() && ((IntegerStamp) shift.getX().stamp()).isPositive()) { - int mask = shift.getShiftAmountMask(); - int amount = shift.getY().asJavaConstant().asInt() & mask; - if (shift.getX().getStackKind() == JavaKind.Int) { - return new IntegerTestNode(shift.getX(), ConstantNode.forInt(-1 << amount)); - } else { - assert shift.getX().getStackKind() == JavaKind.Long; - return new IntegerTestNode(shift.getX(), ConstantNode.forLong(-1L << amount)); + } else if (nonConstant instanceof RightShiftNode) { + RightShiftNode shift = (RightShiftNode) nonConstant; + if (shift.getY().isConstant() && ((IntegerStamp) shift.getX().stamp()).isPositive()) { + int mask = shift.getShiftAmountMask(); + int amount = shift.getY().asJavaConstant().asInt() & mask; + if (shift.getX().getStackKind() == JavaKind.Int) { + return new IntegerTestNode(shift.getX(), ConstantNode.forInt(-1 << amount)); + } else { + assert shift.getX().getStackKind() == JavaKind.Long; + return new IntegerTestNode(shift.getX(), ConstantNode.forLong(-1L << amount)); + } } - } - } else if (nonConstant instanceof UnsignedRightShiftNode) { - UnsignedRightShiftNode shift = (UnsignedRightShiftNode) nonConstant; - if (shift.getY().isConstant()) { - int mask = shift.getShiftAmountMask(); - int amount = shift.getY().asJavaConstant().asInt() & mask; - if (shift.getX().getStackKind() == JavaKind.Int) { - return new IntegerTestNode(shift.getX(), ConstantNode.forInt(-1 << amount)); - } else { - assert shift.getX().getStackKind() == JavaKind.Long; - return new IntegerTestNode(shift.getX(), ConstantNode.forLong(-1L << amount)); + } else if (nonConstant instanceof UnsignedRightShiftNode) { + UnsignedRightShiftNode shift = (UnsignedRightShiftNode) nonConstant; + if (shift.getY().isConstant()) { + int mask = shift.getShiftAmountMask(); + int amount = shift.getY().asJavaConstant().asInt() & mask; + if (shift.getX().getStackKind() == JavaKind.Int) { + return new IntegerTestNode(shift.getX(), ConstantNode.forInt(-1 << amount)); + } else { + assert shift.getX().getStackKind() == JavaKind.Long; + return new IntegerTestNode(shift.getX(), ConstantNode.forLong(-1L << amount)); + } } } } } - } - if (nonConstant instanceof AddNode) { - AddNode addNode = (AddNode) nonConstant; - if (addNode.getY().isJavaConstant()) { - return new IntegerEqualsNode(addNode.getX(), ConstantNode.forIntegerStamp(nonConstantStamp, primitiveConstant.asLong() - addNode.getY().asJavaConstant().asLong())); + if (nonConstant instanceof AddNode) { + AddNode addNode = (AddNode) nonConstant; + if (addNode.getY().isJavaConstant()) { + return new IntegerEqualsNode(addNode.getX(), ConstantNode.forIntegerStamp(nonConstantStamp, primitiveConstant.asLong() - addNode.getY().asJavaConstant().asLong())); + } + } + if (nonConstant instanceof AndNode) { + /* + * a & c == c is the same as a & c != 0, if c is a single bit. + */ + AndNode andNode = (AndNode) nonConstant; + if (Long.bitCount(((PrimitiveConstant) constant).asLong()) == 1 && andNode.getY().isConstant() && andNode.getY().asJavaConstant().equals(constant)) { + return new LogicNegationNode(new IntegerTestNode(andNode.getX(), andNode.getY())); + } } } - if (nonConstant instanceof AndNode) { - /* - * a & c == c is the same as a & c != 0, if c is a single bit. - */ - AndNode andNode = (AndNode) nonConstant; - if (Long.bitCount(((PrimitiveConstant) constant).asLong()) == 1 && andNode.getY().isConstant() && andNode.getY().asJavaConstant().equals(constant)) { - return new LogicNegationNode(new IntegerTestNode(andNode.getX(), andNode.getY())); - } - } + return super.canonicalizeSymmetricConstant(constantReflection, metaAccess, options, smallestCompareWidth, condition, constant, nonConstant, mirrored, unorderedIsTrue); } - return super.canonicalizeSymmetricConstant(tool, constant, nonConstant, mirrored); } @Override diff -r d5572756efd6 -r ab5b504181d8 hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/calc/IntegerLessThanNode.java --- a/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/calc/IntegerLessThanNode.java Tue Apr 18 20:10:55 2017 -0700 +++ b/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/calc/IntegerLessThanNode.java Wed Apr 19 04:10:56 2017 +0000 @@ -24,15 +24,20 @@ import static org.graalvm.compiler.core.common.calc.Condition.LT; +import jdk.vm.ci.meta.ConstantReflectionProvider; +import jdk.vm.ci.meta.MetaAccessProvider; import org.graalvm.compiler.core.common.NumUtil; import org.graalvm.compiler.core.common.calc.Condition; import org.graalvm.compiler.core.common.type.FloatStamp; import org.graalvm.compiler.core.common.type.IntegerStamp; 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.NodeClass; +import org.graalvm.compiler.graph.spi.CanonicalizerTool; import org.graalvm.compiler.nodeinfo.NodeInfo; import org.graalvm.compiler.nodes.ConstantNode; +import org.graalvm.compiler.nodes.LogicConstantNode; import org.graalvm.compiler.nodes.LogicNegationNode; import org.graalvm.compiler.nodes.LogicNode; import org.graalvm.compiler.nodes.ValueNode; @@ -42,6 +47,7 @@ import jdk.vm.ci.meta.JavaConstant; import jdk.vm.ci.meta.JavaKind; import jdk.vm.ci.meta.PrimitiveConstant; +import org.graalvm.compiler.options.OptionValues; @NodeInfo(shortName = "<") public final class IntegerLessThanNode extends IntegerLowerThanNode { @@ -58,19 +64,20 @@ return OP.create(x, y); } + public static LogicNode create(ConstantReflectionProvider constantReflection, MetaAccessProvider metaAccess, OptionValues options, Integer smallestCompareWidth, + ValueNode x, ValueNode y) { + LogicNode value = OP.canonical(constantReflection, metaAccess, options, smallestCompareWidth, OP.getCondition(), false, x, y); + if (value != null) { + return value; + } + return create(x, y); + } + @Override - protected ValueNode optimizeNormalizeCmp(Constant constant, NormalizeCompareNode normalizeNode, boolean mirrored) { - PrimitiveConstant primitive = (PrimitiveConstant) constant; - assert condition() == LT; - if (primitive.getJavaKind() == JavaKind.Int && primitive.asInt() == 0) { - ValueNode a = mirrored ? normalizeNode.getY() : normalizeNode.getX(); - ValueNode b = mirrored ? normalizeNode.getX() : normalizeNode.getY(); - - if (normalizeNode.getX().getStackKind() == JavaKind.Double || normalizeNode.getX().getStackKind() == JavaKind.Float) { - return new FloatLessThanNode(a, b, mirrored ^ normalizeNode.isUnorderedLess); - } else { - return new IntegerLessThanNode(a, b); - } + public Node canonical(CanonicalizerTool tool, ValueNode forX, ValueNode forY) { + ValueNode value = OP.canonical(tool.getConstantReflection(), tool.getMetaAccess(), tool.getOptions(), tool.smallestCompareWidth(), OP.getCondition(), false, forX, forY); + if (value != null) { + return value; } return this; } @@ -89,17 +96,69 @@ return (((x ^ y) & (x ^ r)) < 0) || r > maxValue; } - @Override - protected CompareNode duplicateModified(ValueNode newX, ValueNode newY) { - if (newX.stamp() instanceof FloatStamp && newY.stamp() instanceof FloatStamp) { - return new FloatLessThanNode(newX, newY, true); - } else if (newX.stamp() instanceof IntegerStamp && newY.stamp() instanceof IntegerStamp) { - return new IntegerLessThanNode(newX, newY); + public static class LessThanOp extends LowerOp { + @Override + protected CompareNode duplicateModified(ValueNode newX, ValueNode newY, boolean unorderedIsTrue) { + if (newX.stamp() instanceof FloatStamp && newY.stamp() instanceof FloatStamp) { + return new FloatLessThanNode(newX, newY, unorderedIsTrue); // TODO: Is the last arg + // supposed to be true? + } else if (newX.stamp() instanceof IntegerStamp && newY.stamp() instanceof IntegerStamp) { + return new IntegerLessThanNode(newX, newY); + } + throw GraalError.shouldNotReachHere(); } - throw GraalError.shouldNotReachHere(); - } - public static class LessThanOp extends LowerOp { + @Override + protected LogicNode optimizeNormalizeCompare(ConstantReflectionProvider constantReflection, MetaAccessProvider metaAccess, OptionValues options, Integer smallestCompareWidth, + Constant constant, NormalizeCompareNode normalizeNode, boolean mirrored) { + PrimitiveConstant primitive = (PrimitiveConstant) constant; + /* @formatter:off + * a NC b < c (not mirrored) + * cases for c: + * 0 -> a < b + * [MIN, -1] -> false + * 1 -> a <= b + * [2, MAX] -> true + * unordered-is-less means unordered-is-true. + * + * c < a NC b (mirrored) + * cases for c: + * 0 -> a > b + * [1, MAX] -> false + * -1 -> a >= b + * [MIN, -2] -> true + * unordered-is-less means unordered-is-false. + * + * We can handle mirroring by swapping a & b and negating the constant. + * @formatter:on + */ + ValueNode a = mirrored ? normalizeNode.getY() : normalizeNode.getX(); + ValueNode b = mirrored ? normalizeNode.getX() : normalizeNode.getY(); + long cst = mirrored ? -primitive.asLong() : primitive.asLong(); + + if (cst == 0) { + if (normalizeNode.getX().getStackKind() == JavaKind.Double || normalizeNode.getX().getStackKind() == JavaKind.Float) { + return FloatLessThanNode.create(constantReflection, metaAccess, options, smallestCompareWidth, a, b, mirrored ^ normalizeNode.isUnorderedLess); + } else { + return IntegerLessThanNode.create(constantReflection, metaAccess, options, smallestCompareWidth, a, b); + } + } else if (cst == 1) { + // a <= b <=> !(a > b) + LogicNode compare; + if (normalizeNode.getX().getStackKind() == JavaKind.Double || normalizeNode.getX().getStackKind() == JavaKind.Float) { + // since we negate, we have to reverse the unordered result + compare = FloatLessThanNode.create(constantReflection, metaAccess, options, smallestCompareWidth, b, a, mirrored == normalizeNode.isUnorderedLess); + } else { + compare = IntegerLessThanNode.create(constantReflection, metaAccess, options, smallestCompareWidth, b, a); + } + return LogicNegationNode.create(compare); + } else if (cst <= -1) { + return LogicConstantNode.contradiction(); + } else { + assert cst >= 2; + return LogicConstantNode.tautology(); + } + } @Override protected LogicNode findSynonym(ValueNode forX, ValueNode forY) { diff -r d5572756efd6 -r ab5b504181d8 hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/calc/IntegerLowerThanNode.java --- a/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/calc/IntegerLowerThanNode.java Tue Apr 18 20:10:55 2017 -0700 +++ b/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/calc/IntegerLowerThanNode.java Wed Apr 19 04:10:56 2017 +0000 @@ -22,11 +22,12 @@ */ package org.graalvm.compiler.nodes.calc; +import jdk.vm.ci.meta.ConstantReflectionProvider; +import jdk.vm.ci.meta.MetaAccessProvider; import org.graalvm.compiler.core.common.calc.Condition; import org.graalvm.compiler.core.common.type.IntegerStamp; import org.graalvm.compiler.core.common.type.Stamp; import org.graalvm.compiler.graph.NodeClass; -import org.graalvm.compiler.graph.spi.CanonicalizerTool; import org.graalvm.compiler.nodeinfo.NodeInfo; import org.graalvm.compiler.nodes.ConstantNode; import org.graalvm.compiler.nodes.LogicConstantNode; @@ -36,6 +37,7 @@ import org.graalvm.compiler.nodes.util.GraphUtil; import jdk.vm.ci.meta.TriState; +import org.graalvm.compiler.options.OptionValues; /** * Common super-class for "a < b" comparisons both {@linkplain IntegerLowerThanNode signed} and @@ -56,19 +58,6 @@ } @Override - public ValueNode canonical(CanonicalizerTool tool, ValueNode forX, ValueNode forY) { - ValueNode result = super.canonical(tool, forX, forY); - if (result != this) { - return result; - } - LogicNode synonym = getOp().findSynonym(forX, forY); - if (synonym != null) { - return synonym; - } - return this; - } - - @Override public Stamp getSucceedingStampForX(boolean negated, Stamp xStampGeneric, Stamp yStampGeneric) { return getSucceedingStampForX(negated, !negated, xStampGeneric, yStampGeneric, getX(), getY()); } @@ -125,7 +114,21 @@ return getOp().tryFold(xStampGeneric, yStampGeneric); } - public abstract static class LowerOp { + public abstract static class LowerOp extends CompareOp { + @Override + public LogicNode canonical(ConstantReflectionProvider constantReflection, MetaAccessProvider metaAccess, OptionValues options, Integer smallestCompareWidth, Condition condition, + boolean unorderedIsTrue, ValueNode forX, ValueNode forY) { + LogicNode result = super.canonical(constantReflection, metaAccess, options, smallestCompareWidth, condition, unorderedIsTrue, forX, forY); + if (result != null) { + return result; + } + LogicNode synonym = findSynonym(forX, forY); + if (synonym != null) { + return synonym; + } + return null; + } + protected abstract long upperBound(IntegerStamp stamp); protected abstract long lowerBound(IntegerStamp stamp); diff -r d5572756efd6 -r ab5b504181d8 hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/calc/MulNode.java --- a/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/calc/MulNode.java Tue Apr 18 20:10:55 2017 -0700 +++ b/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/calc/MulNode.java Wed Apr 19 04:10:56 2017 +0000 @@ -22,6 +22,8 @@ */ package org.graalvm.compiler.nodes.calc; +import static org.graalvm.compiler.nodeinfo.NodeCycles.CYCLES_2; + import org.graalvm.compiler.core.common.type.ArithmeticOpTable; import org.graalvm.compiler.core.common.type.ArithmeticOpTable.BinaryOp; import org.graalvm.compiler.core.common.type.ArithmeticOpTable.BinaryOp.Mul; @@ -30,7 +32,6 @@ import org.graalvm.compiler.graph.spi.Canonicalizable.BinaryCommutative; import org.graalvm.compiler.graph.spi.CanonicalizerTool; import org.graalvm.compiler.lir.gen.ArithmeticLIRGeneratorTool; -import org.graalvm.compiler.nodeinfo.NodeCycles; import org.graalvm.compiler.nodeinfo.NodeInfo; import org.graalvm.compiler.nodes.ConstantNode; import org.graalvm.compiler.nodes.ValueNode; @@ -41,7 +42,7 @@ import jdk.vm.ci.meta.PrimitiveConstant; import jdk.vm.ci.meta.Value; -@NodeInfo(shortName = "*", cycles = NodeCycles.CYCLES_3) +@NodeInfo(shortName = "*", cycles = CYCLES_2) public class MulNode extends BinaryArithmeticNode implements NarrowableArithmeticNode, BinaryCommutative { public static final NodeClass TYPE = NodeClass.create(MulNode.class); diff -r d5572756efd6 -r ab5b504181d8 hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/calc/NormalizeCompareNode.java --- a/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/calc/NormalizeCompareNode.java Tue Apr 18 20:10:55 2017 -0700 +++ b/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/calc/NormalizeCompareNode.java Wed Apr 19 04:10:56 2017 +0000 @@ -22,6 +22,8 @@ */ package org.graalvm.compiler.nodes.calc; +import static org.graalvm.compiler.nodeinfo.NodeSize.SIZE_2; + import org.graalvm.compiler.core.common.calc.Condition; import org.graalvm.compiler.core.common.type.FloatStamp; import org.graalvm.compiler.core.common.type.Stamp; @@ -30,7 +32,6 @@ import org.graalvm.compiler.graph.spi.CanonicalizerTool; import org.graalvm.compiler.nodeinfo.NodeCycles; import org.graalvm.compiler.nodeinfo.NodeInfo; -import org.graalvm.compiler.nodeinfo.NodeSize; import org.graalvm.compiler.nodes.ConstantNode; import org.graalvm.compiler.nodes.LogicConstantNode; import org.graalvm.compiler.nodes.LogicNode; @@ -46,7 +47,7 @@ * of the inputs is NaN), the result is 1 if isUnorderedLess is false and -1 if isUnorderedLess is * true. */ -@NodeInfo(cycles = NodeCycles.CYCLES_2, size = NodeSize.SIZE_4) +@NodeInfo(cycles = NodeCycles.CYCLES_2, size = SIZE_2) public final class NormalizeCompareNode extends BinaryNode implements Lowerable { public static final NodeClass TYPE = NodeClass.create(NormalizeCompareNode.class); diff -r d5572756efd6 -r ab5b504181d8 hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/calc/ObjectEqualsNode.java --- a/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/calc/ObjectEqualsNode.java Tue Apr 18 20:10:55 2017 -0700 +++ b/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/calc/ObjectEqualsNode.java Wed Apr 19 04:10:56 2017 +0000 @@ -48,11 +48,13 @@ import jdk.vm.ci.meta.JavaKind; import jdk.vm.ci.meta.MetaAccessProvider; import jdk.vm.ci.meta.ResolvedJavaType; +import org.graalvm.compiler.options.OptionValues; @NodeInfo(shortName = "==") public final class ObjectEqualsNode extends PointerEqualsNode implements Virtualizable { public static final NodeClass TYPE = NodeClass.create(ObjectEqualsNode.class); + private static final ObjectEqualsOp OP = new ObjectEqualsOp(); public ObjectEqualsNode(ValueNode x, ValueNode y) { super(TYPE, x, y); @@ -73,19 +75,50 @@ } } + public static LogicNode create(ConstantReflectionProvider constantReflection, MetaAccessProvider metaAccess, OptionValues options, ValueNode x, ValueNode y) { + LogicNode result = OP.canonical(constantReflection, metaAccess, options, null, Condition.EQ, false, x, y); + if (result != null) { + return result; + } + return create(x, y, constantReflection); + } + @Override - protected ValueNode canonicalizeSymmetricConstant(CanonicalizerTool tool, Constant constant, ValueNode nonConstant, boolean mirrored) { - ResolvedJavaType type = tool.getConstantReflection().asJavaType(constant); - if (type != null && nonConstant instanceof GetClassNode) { - GetClassNode getClassNode = (GetClassNode) nonConstant; - ValueNode object = getClassNode.getObject(); - assert ((ObjectStamp) object.stamp()).nonNull(); - if (!type.isPrimitive() && (type.isConcrete() || type.isArray())) { - return InstanceOfNode.create(TypeReference.createExactTrusted(type), object); + public ValueNode canonical(CanonicalizerTool tool, ValueNode forX, ValueNode forY) { + ValueNode value = OP.canonical(tool.getConstantReflection(), tool.getMetaAccess(), tool.getOptions(), tool.smallestCompareWidth(), Condition.EQ, false, forX, forY); + if (value != null) { + return value; + } + return this; + } + + public static class ObjectEqualsOp extends PointerEqualsOp { + + @Override + protected LogicNode canonicalizeSymmetricConstant(ConstantReflectionProvider constantReflection, MetaAccessProvider metaAccess, OptionValues options, Integer smallestCompareWidth, + Condition condition, Constant constant, ValueNode nonConstant, boolean mirrored, boolean unorderedIsTrue) { + ResolvedJavaType type = constantReflection.asJavaType(constant); + if (type != null && nonConstant instanceof GetClassNode) { + GetClassNode getClassNode = (GetClassNode) nonConstant; + ValueNode object = getClassNode.getObject(); + assert ((ObjectStamp) object.stamp()).nonNull(); + if (!type.isPrimitive() && (type.isConcrete() || type.isArray())) { + return InstanceOfNode.create(TypeReference.createExactTrusted(type), object); + } + return LogicConstantNode.forBoolean(false); } - return LogicConstantNode.forBoolean(false); + return super.canonicalizeSymmetricConstant(constantReflection, metaAccess, options, smallestCompareWidth, condition, constant, nonConstant, mirrored, unorderedIsTrue); } - return super.canonicalizeSymmetricConstant(tool, constant, nonConstant, mirrored); + + @Override + protected CompareNode duplicateModified(ValueNode newX, ValueNode newY, boolean unorderedIsTrue) { + if (newX.stamp() instanceof ObjectStamp && newY.stamp() instanceof ObjectStamp) { + return new ObjectEqualsNode(newX, newY); + } else if (newX.stamp() instanceof AbstractPointerStamp && newY.stamp() instanceof AbstractPointerStamp) { + return new PointerEqualsNode(newX, newY); + } + throw GraalError.shouldNotReachHere(); + } } private void virtualizeNonVirtualComparison(VirtualObjectNode virtual, ValueNode other, VirtualizerTool tool) { @@ -150,14 +183,4 @@ } } } - - @Override - protected CompareNode duplicateModified(ValueNode newX, ValueNode newY) { - if (newX.stamp() instanceof ObjectStamp && newY.stamp() instanceof ObjectStamp) { - return new ObjectEqualsNode(newX, newY); - } else if (newX.stamp() instanceof AbstractPointerStamp && newY.stamp() instanceof AbstractPointerStamp) { - return new PointerEqualsNode(newX, newY); - } - throw GraalError.shouldNotReachHere(); - } } diff -r d5572756efd6 -r ab5b504181d8 hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/calc/PointerEqualsNode.java --- a/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/calc/PointerEqualsNode.java Tue Apr 18 20:10:55 2017 -0700 +++ b/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/calc/PointerEqualsNode.java Wed Apr 19 04:10:56 2017 +0000 @@ -22,10 +22,13 @@ */ package org.graalvm.compiler.nodes.calc; +import jdk.vm.ci.meta.ConstantReflectionProvider; +import jdk.vm.ci.meta.MetaAccessProvider; import org.graalvm.compiler.core.common.calc.Condition; import org.graalvm.compiler.core.common.type.AbstractPointerStamp; import org.graalvm.compiler.core.common.type.ObjectStamp; import org.graalvm.compiler.core.common.type.Stamp; +import org.graalvm.compiler.graph.Node; import org.graalvm.compiler.graph.NodeClass; import org.graalvm.compiler.graph.spi.Canonicalizable.BinaryCommutative; import org.graalvm.compiler.graph.spi.CanonicalizerTool; @@ -41,11 +44,13 @@ import jdk.vm.ci.meta.ResolvedJavaMethod; import jdk.vm.ci.meta.ResolvedJavaType; import jdk.vm.ci.meta.TriState; +import org.graalvm.compiler.options.OptionValues; @NodeInfo(shortName = "==") public class PointerEqualsNode extends CompareNode implements BinaryCommutative { public static final NodeClass TYPE = NodeClass.create(PointerEqualsNode.class); + private static final PointerEqualsOp OP = new PointerEqualsOp(); public PointerEqualsNode(ValueNode x, ValueNode y) { this(TYPE, x, y); @@ -65,44 +70,62 @@ assert y.stamp() instanceof AbstractPointerStamp; } - /** - * Determines if this is a comparison used to determine whether dispatching on a receiver could - * select a certain method and if so, returns {@code true} if the answer is guaranteed to be - * false. Otherwise, returns {@code false}. - */ - private boolean isAlwaysFailingVirtualDispatchTest(ValueNode forX, ValueNode forY) { - if (forY.isConstant()) { - if (forX instanceof LoadMethodNode && condition == Condition.EQ) { - LoadMethodNode lm = ((LoadMethodNode) forX); - if (lm.getMethod().getEncoding().equals(forY.asConstant())) { - if (lm.getHub() instanceof LoadHubNode) { - ValueNode object = ((LoadHubNode) lm.getHub()).getValue(); - ResolvedJavaType type = StampTool.typeOrNull(object); - ResolvedJavaType declaringClass = lm.getMethod().getDeclaringClass(); - if (type != null && !type.equals(declaringClass) && declaringClass.isAssignableFrom(type)) { - ResolvedJavaMethod override = type.resolveMethod(lm.getMethod(), lm.getCallerType()); - if (override != null && !override.equals(lm.getMethod())) { - assert declaringClass.isAssignableFrom(override.getDeclaringClass()); - return true; + @Override + public Node canonical(CanonicalizerTool tool, ValueNode forX, ValueNode forY) { + ValueNode value = OP.canonical(tool.getConstantReflection(), tool.getMetaAccess(), tool.getOptions(), tool.smallestCompareWidth(), Condition.EQ, false, forX, forY); + if (value != null) { + return value; + } + return this; + } + + public static class PointerEqualsOp extends CompareOp { + + /** + * Determines if this is a comparison used to determine whether dispatching on a receiver + * could select a certain method and if so, returns {@code true} if the answer is guaranteed + * to be false. Otherwise, returns {@code false}. + */ + private static boolean isAlwaysFailingVirtualDispatchTest(Condition condition, ValueNode forX, ValueNode forY) { + if (forY.isConstant()) { + if (forX instanceof LoadMethodNode && condition == Condition.EQ) { + LoadMethodNode lm = ((LoadMethodNode) forX); + if (lm.getMethod().getEncoding().equals(forY.asConstant())) { + if (lm.getHub() instanceof LoadHubNode) { + ValueNode object = ((LoadHubNode) lm.getHub()).getValue(); + ResolvedJavaType type = StampTool.typeOrNull(object); + ResolvedJavaType declaringClass = lm.getMethod().getDeclaringClass(); + if (type != null && !type.equals(declaringClass) && declaringClass.isAssignableFrom(type)) { + ResolvedJavaMethod override = type.resolveMethod(lm.getMethod(), lm.getCallerType()); + if (override != null && !override.equals(lm.getMethod())) { + assert declaringClass.isAssignableFrom(override.getDeclaringClass()); + return true; + } } } } } } + return false; } - return false; - } - @Override - public ValueNode canonical(CanonicalizerTool tool, ValueNode forX, ValueNode forY) { - LogicNode result = findSynonym(forX, forY); - if (result != null) { - return result; + @Override + public LogicNode canonical(ConstantReflectionProvider constantReflection, MetaAccessProvider metaAccess, OptionValues options, Integer smallestCompareWidth, Condition condition, + boolean unorderedIsTrue, ValueNode forX, ValueNode forY) { + LogicNode result = findSynonym(forX, forY); + if (result != null) { + return result; + } + if (isAlwaysFailingVirtualDispatchTest(condition, forX, forY)) { + return LogicConstantNode.contradiction(); + } + return super.canonical(constantReflection, metaAccess, options, smallestCompareWidth, condition, unorderedIsTrue, forX, forY); } - if (isAlwaysFailingVirtualDispatchTest(forX, forY)) { - return LogicConstantNode.contradiction(); + + @Override + protected CompareNode duplicateModified(ValueNode newX, ValueNode newY, boolean unorderedIsTrue) { + return new PointerEqualsNode(newX, newY); } - return super.canonical(tool, forX, forY); } public static LogicNode findSynonym(ValueNode forX, ValueNode forY) { @@ -120,11 +143,6 @@ } @Override - protected CompareNode duplicateModified(ValueNode newX, ValueNode newY) { - return new PointerEqualsNode(newX, newY); - } - - @Override public Stamp getSucceedingStampForX(boolean negated, Stamp xStamp, Stamp yStamp) { if (!negated) { Stamp newStamp = xStamp.join(yStamp); diff -r d5572756efd6 -r ab5b504181d8 hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/calc/RemNode.java --- a/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/calc/RemNode.java Tue Apr 18 20:10:55 2017 -0700 +++ b/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/calc/RemNode.java Wed Apr 19 04:10:56 2017 +0000 @@ -22,18 +22,19 @@ */ package org.graalvm.compiler.nodes.calc; +import static org.graalvm.compiler.nodeinfo.NodeCycles.CYCLES_8; + import org.graalvm.compiler.core.common.type.ArithmeticOpTable; import org.graalvm.compiler.core.common.type.ArithmeticOpTable.BinaryOp.Rem; import org.graalvm.compiler.graph.NodeClass; import org.graalvm.compiler.lir.gen.ArithmeticLIRGeneratorTool; -import org.graalvm.compiler.nodeinfo.NodeCycles; import org.graalvm.compiler.nodeinfo.NodeInfo; import org.graalvm.compiler.nodes.ValueNode; import org.graalvm.compiler.nodes.spi.Lowerable; import org.graalvm.compiler.nodes.spi.LoweringTool; import org.graalvm.compiler.nodes.spi.NodeLIRBuilderTool; -@NodeInfo(shortName = "%", cycles = NodeCycles.CYCLES_30/* div */) +@NodeInfo(shortName = "%", cycles = CYCLES_8/* div */) public class RemNode extends BinaryArithmeticNode implements Lowerable { public static final NodeClass TYPE = NodeClass.create(RemNode.class); diff -r d5572756efd6 -r ab5b504181d8 hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/calc/SqrtNode.java --- a/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/calc/SqrtNode.java Tue Apr 18 20:10:55 2017 -0700 +++ b/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/calc/SqrtNode.java Wed Apr 19 04:10:56 2017 +0000 @@ -22,7 +22,7 @@ */ package org.graalvm.compiler.nodes.calc; -import static org.graalvm.compiler.nodeinfo.NodeCycles.CYCLES_30; +import static org.graalvm.compiler.nodeinfo.NodeCycles.CYCLES_16; import static org.graalvm.compiler.nodeinfo.NodeSize.SIZE_1; import org.graalvm.compiler.core.common.type.ArithmeticOpTable; @@ -37,7 +37,7 @@ /** * Square root. */ -@NodeInfo(cycles = CYCLES_30, size = SIZE_1) +@NodeInfo(cycles = CYCLES_16, size = SIZE_1) public final class SqrtNode extends UnaryArithmeticNode implements ArithmeticLIRLowerable { public static final NodeClass TYPE = NodeClass.create(SqrtNode.class); diff -r d5572756efd6 -r ab5b504181d8 hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/debug/DynamicCounterNode.java --- a/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/debug/DynamicCounterNode.java Tue Apr 18 20:10:55 2017 -0700 +++ b/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/debug/DynamicCounterNode.java Wed Apr 19 04:10:56 2017 +0000 @@ -22,8 +22,8 @@ */ package org.graalvm.compiler.nodes.debug; -import static org.graalvm.compiler.nodeinfo.NodeCycles.CYCLES_20; -import static org.graalvm.compiler.nodeinfo.NodeSize.SIZE_10; +import static org.graalvm.compiler.nodeinfo.NodeCycles.CYCLES_IGNORED; +import static org.graalvm.compiler.nodeinfo.NodeSize.SIZE_IGNORED; import org.graalvm.compiler.core.common.type.StampFactory; import org.graalvm.compiler.debug.GraalError; @@ -47,7 +47,12 @@ * A unique counter will be created for each unique name passed to the constructor. Depending on the * value of withContext, the name of the root method is added to the counter's name. */ -@NodeInfo(size = SIZE_10, cycles = CYCLES_20) +//@formatter:off +@NodeInfo(size = SIZE_IGNORED, + sizeRationale = "Node is a debugging node that should not be used in production.", + cycles = CYCLES_IGNORED, + cyclesRationale = "Node is a debugging node that should not be used in production.") +//@formatter:on public class DynamicCounterNode extends FixedWithNextNode implements LIRLowerable { public static final NodeClass TYPE = NodeClass.create(DynamicCounterNode.class); diff -r d5572756efd6 -r ab5b504181d8 hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/debug/VerifyHeapNode.java --- a/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/debug/VerifyHeapNode.java Tue Apr 18 20:10:55 2017 -0700 +++ b/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/debug/VerifyHeapNode.java Wed Apr 19 04:10:56 2017 +0000 @@ -22,8 +22,8 @@ */ package org.graalvm.compiler.nodes.debug; -import static org.graalvm.compiler.nodeinfo.NodeCycles.CYCLES_30; -import static org.graalvm.compiler.nodeinfo.NodeSize.SIZE_50; +import static org.graalvm.compiler.nodeinfo.NodeCycles.CYCLES_IGNORED; +import static org.graalvm.compiler.nodeinfo.NodeSize.SIZE_IGNORED; import org.graalvm.compiler.core.common.type.StampFactory; import org.graalvm.compiler.graph.NodeClass; @@ -38,7 +38,12 @@ * A node for platform dependent verification of the Java heap. Intended to be used for debugging * heap corruption issues. */ -@NodeInfo(cycles = CYCLES_30, size = SIZE_50) +//@formatter:off +@NodeInfo(size = SIZE_IGNORED, + sizeRationale = "Node is a debugging node that should not be used in production.", + cycles = CYCLES_IGNORED, + cyclesRationale = "Node is a debugging node that should not be used in production.") +//@formatter:on public final class VerifyHeapNode extends FixedWithNextNode implements Lowerable { public static final NodeClass TYPE = NodeClass.create(VerifyHeapNode.class); diff -r d5572756efd6 -r ab5b504181d8 hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/extended/BoxNode.java --- a/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/extended/BoxNode.java Tue Apr 18 20:10:55 2017 -0700 +++ b/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/extended/BoxNode.java Wed Apr 19 04:10:56 2017 +0000 @@ -22,8 +22,7 @@ */ package org.graalvm.compiler.nodes.extended; -import static org.graalvm.compiler.nodeinfo.NodeCycles.CYCLES_20; -import static org.graalvm.compiler.nodeinfo.NodeSize.SIZE_20; +import static org.graalvm.compiler.nodeinfo.NodeSize.SIZE_8; import java.util.Collections; @@ -32,6 +31,7 @@ import org.graalvm.compiler.graph.NodeClass; import org.graalvm.compiler.graph.spi.Canonicalizable; import org.graalvm.compiler.graph.spi.CanonicalizerTool; +import org.graalvm.compiler.nodeinfo.NodeCycles; import org.graalvm.compiler.nodeinfo.NodeInfo; import org.graalvm.compiler.nodes.FixedWithNextNode; import org.graalvm.compiler.nodes.ValueNode; @@ -50,7 +50,7 @@ * This node represents the boxing of a primitive value. This corresponds to a call to the valueOf * methods in Integer, Long, etc. */ -@NodeInfo(cycles = CYCLES_20, size = SIZE_20) +@NodeInfo(cycles = NodeCycles.CYCLES_8, size = SIZE_8) public class BoxNode extends FixedWithNextNode implements VirtualizableAllocation, Lowerable, Canonicalizable.Unary { public static final NodeClass TYPE = NodeClass.create(BoxNode.class); diff -r d5572756efd6 -r ab5b504181d8 hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/extended/BytecodeExceptionNode.java --- a/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/extended/BytecodeExceptionNode.java Tue Apr 18 20:10:55 2017 -0700 +++ b/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/extended/BytecodeExceptionNode.java Wed Apr 19 04:10:56 2017 +0000 @@ -22,8 +22,8 @@ */ package org.graalvm.compiler.nodes.extended; -import static org.graalvm.compiler.nodeinfo.NodeCycles.CYCLES_UNKNOWN; -import static org.graalvm.compiler.nodeinfo.NodeSize.SIZE_20; +import static org.graalvm.compiler.nodeinfo.NodeCycles.CYCLES_8; +import static org.graalvm.compiler.nodeinfo.NodeSize.SIZE_8; import org.graalvm.compiler.core.common.LocationIdentity; import org.graalvm.compiler.core.common.spi.ForeignCallDescriptor; @@ -46,9 +46,9 @@ * either a {@linkplain ForeignCallDescriptor foreign} call or a pre-allocated exception object. */ // @formatter:off -@NodeInfo(cycles = CYCLES_UNKNOWN, +@NodeInfo(cycles = CYCLES_8, cyclesRationale = "Node will be lowered to a foreign call.", - size = SIZE_20) + size = SIZE_8) // @formatter:on public final class BytecodeExceptionNode extends AbstractMemoryCheckpoint implements Lowerable, MemoryCheckpoint.Single { diff -r d5572756efd6 -r ab5b504181d8 hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/extended/ForeignCallNode.java --- a/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/extended/ForeignCallNode.java Tue Apr 18 20:10:55 2017 -0700 +++ b/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/extended/ForeignCallNode.java Wed Apr 19 04:10:56 2017 +0000 @@ -24,8 +24,8 @@ import static org.graalvm.compiler.nodeinfo.InputType.Memory; import static org.graalvm.compiler.nodeinfo.InputType.State; -import static org.graalvm.compiler.nodeinfo.NodeCycles.CYCLES_UNKNOWN; -import static org.graalvm.compiler.nodeinfo.NodeSize.SIZE_20; +import static org.graalvm.compiler.nodeinfo.NodeCycles.CYCLES_2; +import static org.graalvm.compiler.nodeinfo.NodeSize.SIZE_2; import java.util.List; @@ -60,9 +60,10 @@ // @formatter:off @NodeInfo(nameTemplate = "ForeignCall#{p#descriptor/s}", allowedUsageTypes = Memory, - cycles = CYCLES_UNKNOWN, - cyclesRationale = "A foreign call is a block box in terms of time spent in the callee.", - size = SIZE_20) + cycles = CYCLES_2, + cyclesRationale = "Rough estimation of the call operation itself.", + size = SIZE_2, + sizeRationale = "Rough estimation of the call operation itself.") // @formatter:on public class ForeignCallNode extends AbstractMemoryCheckpoint implements LIRLowerable, DeoptimizingNode.DeoptDuring, MemoryCheckpoint.Multi { public static final NodeClass TYPE = NodeClass.create(ForeignCallNode.class); diff -r d5572756efd6 -r ab5b504181d8 hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/extended/LoadMethodNode.java --- a/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/extended/LoadMethodNode.java Tue Apr 18 20:10:55 2017 -0700 +++ b/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/extended/LoadMethodNode.java Wed Apr 19 04:10:56 2017 +0000 @@ -22,7 +22,7 @@ */ package org.graalvm.compiler.nodes.extended; -import static org.graalvm.compiler.nodeinfo.NodeCycles.CYCLES_3; +import static org.graalvm.compiler.nodeinfo.NodeCycles.CYCLES_2; import static org.graalvm.compiler.nodeinfo.NodeSize.SIZE_1; import org.graalvm.compiler.core.common.type.Stamp; @@ -49,7 +49,7 @@ /** * Loads a method from the virtual method table of a given hub. */ -@NodeInfo(cycles = CYCLES_3, size = SIZE_1) +@NodeInfo(cycles = CYCLES_2, size = SIZE_1) public final class LoadMethodNode extends FixedWithNextNode implements Lowerable, Canonicalizable { public static final NodeClass TYPE = NodeClass.create(LoadMethodNode.class); diff -r d5572756efd6 -r ab5b504181d8 hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/extended/MembarNode.java --- a/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/extended/MembarNode.java Tue Apr 18 20:10:55 2017 -0700 +++ b/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/extended/MembarNode.java Wed Apr 19 04:10:56 2017 +0000 @@ -23,7 +23,7 @@ package org.graalvm.compiler.nodes.extended; import static org.graalvm.compiler.nodeinfo.InputType.Memory; -import static org.graalvm.compiler.nodeinfo.NodeCycles.CYCLES_20; +import static org.graalvm.compiler.nodeinfo.NodeCycles.CYCLES_2; import static org.graalvm.compiler.nodeinfo.NodeSize.SIZE_2; import org.graalvm.compiler.core.common.LocationIdentity; @@ -38,7 +38,7 @@ /** * Creates a memory barrier. */ -@NodeInfo(nameTemplate = "Membar#{p#location/s}", allowedUsageTypes = Memory, cycles = CYCLES_20, size = SIZE_2) +@NodeInfo(nameTemplate = "Membar#{p#location/s}", allowedUsageTypes = Memory, cycles = CYCLES_2, size = SIZE_2) public final class MembarNode extends FixedWithNextNode implements LIRLowerable, MemoryCheckpoint.Single { public static final NodeClass TYPE = NodeClass.create(MembarNode.class); diff -r d5572756efd6 -r ab5b504181d8 hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/extended/RawStoreNode.java --- a/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/extended/RawStoreNode.java Tue Apr 18 20:10:55 2017 -0700 +++ b/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/extended/RawStoreNode.java Wed Apr 19 04:10:56 2017 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, 2016, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 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 @@ -23,7 +23,7 @@ package org.graalvm.compiler.nodes.extended; import static org.graalvm.compiler.nodeinfo.InputType.State; -import static org.graalvm.compiler.nodeinfo.NodeCycles.CYCLES_3; +import static org.graalvm.compiler.nodeinfo.NodeCycles.CYCLES_2; import static org.graalvm.compiler.nodeinfo.NodeSize.SIZE_1; import org.graalvm.compiler.core.common.LocationIdentity; @@ -51,7 +51,7 @@ * Store of a value at a location specified as an offset relative to an object. No null check is * performed before the store. */ -@NodeInfo(cycles = CYCLES_3, size = SIZE_1) +@NodeInfo(cycles = CYCLES_2, size = SIZE_1) public final class RawStoreNode extends UnsafeAccessNode implements StateSplit, Lowerable, Virtualizable, MemoryCheckpoint.Single { public static final NodeClass TYPE = NodeClass.create(RawStoreNode.class); @@ -124,8 +124,7 @@ int entryIndex = virtual.entryIndexForOffset(off, accessKind()); if (entryIndex != -1) { JavaKind entryKind = virtual.entryKind(entryIndex); - ValueNode entry = tool.getEntry(virtual, entryIndex); - if (entry.getStackKind() == value.getStackKind() || entryKind == accessKind()) { + if (entryKind == accessKind() || entryKind == accessKind().getStackKind()) { tool.setVirtualEntry(virtual, entryIndex, value(), true); tool.delete(); } else { diff -r d5572756efd6 -r ab5b504181d8 hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/extended/SwitchNode.java --- a/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/extended/SwitchNode.java Tue Apr 18 20:10:55 2017 -0700 +++ b/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/extended/SwitchNode.java Wed Apr 19 04:10:56 2017 +0000 @@ -22,7 +22,13 @@ */ package org.graalvm.compiler.nodes.extended; +import static org.graalvm.compiler.nodeinfo.NodeCycles.CYCLES_2; +import static org.graalvm.compiler.nodeinfo.NodeCycles.CYCLES_64; +import static org.graalvm.compiler.nodeinfo.NodeCycles.CYCLES_8; import static org.graalvm.compiler.nodeinfo.NodeCycles.CYCLES_UNKNOWN; +import static org.graalvm.compiler.nodeinfo.NodeSize.SIZE_2; +import static org.graalvm.compiler.nodeinfo.NodeSize.SIZE_64; +import static org.graalvm.compiler.nodeinfo.NodeSize.SIZE_8; import static org.graalvm.compiler.nodeinfo.NodeSize.SIZE_UNKNOWN; import java.util.Arrays; @@ -35,7 +41,9 @@ import org.graalvm.compiler.graph.NodeClass; import org.graalvm.compiler.graph.NodeSuccessorList; import org.graalvm.compiler.graph.spi.SimplifierTool; +import org.graalvm.compiler.nodeinfo.NodeCycles; import org.graalvm.compiler.nodeinfo.NodeInfo; +import org.graalvm.compiler.nodeinfo.NodeSize; import org.graalvm.compiler.nodes.AbstractBeginNode; import org.graalvm.compiler.nodes.ControlSplitNode; import org.graalvm.compiler.nodes.ValueNode; @@ -242,4 +250,33 @@ } public abstract Stamp getValueStampForSuccessor(AbstractBeginNode beginNode); + + @Override + public NodeCycles estimatedNodeCycles() { + if (keyCount() == 1) { + // if + return CYCLES_2; + } else if (isSorted()) { + // good heuristic + return CYCLES_8; + } else { + // not so good + return CYCLES_64; + } + } + + @Override + public NodeSize estimatedNodeSize() { + if (keyCount() == 1) { + // if + return SIZE_2; + } else if (isSorted()) { + // good heuristic + return SIZE_8; + } else { + // not so good + return SIZE_64; + } + } + } diff -r d5572756efd6 -r ab5b504181d8 hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/extended/UnboxNode.java --- a/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/extended/UnboxNode.java Tue Apr 18 20:10:55 2017 -0700 +++ b/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/extended/UnboxNode.java Wed Apr 19 04:10:56 2017 +0000 @@ -22,8 +22,8 @@ */ package org.graalvm.compiler.nodes.extended; -import static org.graalvm.compiler.nodeinfo.NodeCycles.CYCLES_100; -import static org.graalvm.compiler.nodeinfo.NodeSize.SIZE_50; +import static org.graalvm.compiler.nodeinfo.NodeCycles.CYCLES_2; +import static org.graalvm.compiler.nodeinfo.NodeSize.SIZE_2; import org.graalvm.compiler.core.common.type.StampFactory; import org.graalvm.compiler.graph.NodeClass; @@ -46,7 +46,7 @@ import jdk.vm.ci.meta.MetaAccessProvider; import jdk.vm.ci.meta.ResolvedJavaType; -@NodeInfo(cycles = CYCLES_100, size = SIZE_50) +@NodeInfo(cycles = CYCLES_2, size = SIZE_2) public final class UnboxNode extends FixedWithNextNode implements Virtualizable, Lowerable, Canonicalizable.Unary { public static final NodeClass TYPE = NodeClass.create(UnboxNode.class); diff -r d5572756efd6 -r ab5b504181d8 hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/graphbuilderconf/GraphBuilderContext.java --- a/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/graphbuilderconf/GraphBuilderContext.java Tue Apr 18 20:10:55 2017 -0700 +++ b/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/graphbuilderconf/GraphBuilderContext.java Wed Apr 19 04:10:56 2017 +0000 @@ -107,7 +107,7 @@ assert !(value instanceof StateSplit) || ((StateSplit) value).stateAfter() != null; return value; } - T equivalentValue = recursiveAppend(value); + T equivalentValue = append(value); if (equivalentValue instanceof StateSplit) { StateSplit stateSplit = (StateSplit) equivalentValue; if (stateSplit.stateAfter() == null && stateSplit.hasSideEffect()) { diff -r d5572756efd6 -r ab5b504181d8 hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/graphbuilderconf/GraphBuilderTool.java --- a/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/graphbuilderconf/GraphBuilderTool.java Tue Apr 18 20:10:55 2017 -0700 +++ b/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/graphbuilderconf/GraphBuilderTool.java Wed Apr 19 04:10:56 2017 +0000 @@ -38,19 +38,12 @@ public interface GraphBuilderTool { /** - * Raw operation for adding a node to the graph. - * - * @return either the node added or an equivalent node - */ - T append(T value); - - /** * Adds the given node to the graph and also adds recursively all referenced inputs. * * @param value the node to be added to the graph * @return either the node added or an equivalent node */ - T recursiveAppend(T value); + T append(T value); StampProvider getStampProvider(); diff -r d5572756efd6 -r ab5b504181d8 hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/java/AbstractNewObjectNode.java --- a/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/java/AbstractNewObjectNode.java Tue Apr 18 20:10:55 2017 -0700 +++ b/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/java/AbstractNewObjectNode.java Wed Apr 19 04:10:56 2017 +0000 @@ -22,8 +22,8 @@ */ package org.graalvm.compiler.nodes.java; -import static org.graalvm.compiler.nodeinfo.NodeCycles.CYCLES_20; -import static org.graalvm.compiler.nodeinfo.NodeSize.SIZE_20; +import static org.graalvm.compiler.nodeinfo.NodeCycles.CYCLES_8; +import static org.graalvm.compiler.nodeinfo.NodeSize.SIZE_8; import org.graalvm.compiler.core.common.type.Stamp; import org.graalvm.compiler.graph.NodeClass; @@ -36,7 +36,7 @@ /** * The {@code AbstractNewObjectNode} is the base class for the new instance and new array nodes. */ -@NodeInfo(cycles = CYCLES_20, size = SIZE_20) +@NodeInfo(cycles = CYCLES_8, cyclesRationale = "tlab alloc + header init", size = SIZE_8) public abstract class AbstractNewObjectNode extends DeoptimizingFixedWithNextNode implements Lowerable { public static final NodeClass TYPE = NodeClass.create(AbstractNewObjectNode.class); diff -r d5572756efd6 -r ab5b504181d8 hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/java/AccessFieldNode.java --- a/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/java/AccessFieldNode.java Tue Apr 18 20:10:55 2017 -0700 +++ b/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/java/AccessFieldNode.java Wed Apr 19 04:10:56 2017 +0000 @@ -22,12 +22,14 @@ */ package org.graalvm.compiler.nodes.java; -import static org.graalvm.compiler.nodeinfo.NodeCycles.CYCLES_15; -import static org.graalvm.compiler.nodeinfo.NodeSize.SIZE_10; +import static org.graalvm.compiler.nodeinfo.NodeCycles.CYCLES_2; +import static org.graalvm.compiler.nodeinfo.NodeSize.SIZE_1; +import static org.graalvm.compiler.nodeinfo.NodeSize.SIZE_2; import org.graalvm.compiler.core.common.type.Stamp; import org.graalvm.compiler.graph.NodeClass; import org.graalvm.compiler.nodeinfo.NodeInfo; +import org.graalvm.compiler.nodeinfo.NodeSize; import org.graalvm.compiler.nodeinfo.Verbosity; import org.graalvm.compiler.nodes.FixedWithNextNode; import org.graalvm.compiler.nodes.ValueNode; @@ -39,7 +41,7 @@ /** * The base class of all instructions that access fields. */ -@NodeInfo(cycles = CYCLES_15, size = SIZE_10) +@NodeInfo(cycles = CYCLES_2, size = SIZE_1) public abstract class AccessFieldNode extends FixedWithNextNode implements Lowerable { public static final NodeClass TYPE = NodeClass.create(AccessFieldNode.class); @@ -110,4 +112,12 @@ assertTrue((object == null) == isStatic(), "static field must not have object, instance field must have object"); return super.verify(); } + + @Override + public NodeSize estimatedNodeSize() { + if (field.isVolatile()) { + return SIZE_2; + } + return super.estimatedNodeSize(); + } } diff -r d5572756efd6 -r ab5b504181d8 hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/java/AtomicReadAndAddNode.java --- a/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/java/AtomicReadAndAddNode.java Tue Apr 18 20:10:55 2017 -0700 +++ b/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/java/AtomicReadAndAddNode.java Wed Apr 19 04:10:56 2017 +0000 @@ -24,8 +24,8 @@ import static org.graalvm.compiler.nodeinfo.InputType.Association; import static org.graalvm.compiler.nodeinfo.InputType.Memory; -import static org.graalvm.compiler.nodeinfo.NodeCycles.CYCLES_10; -import static org.graalvm.compiler.nodeinfo.NodeSize.SIZE_3; +import static org.graalvm.compiler.nodeinfo.NodeCycles.CYCLES_8; +import static org.graalvm.compiler.nodeinfo.NodeSize.SIZE_2; import org.graalvm.compiler.core.common.LocationIdentity; import org.graalvm.compiler.core.common.type.StampFactory; @@ -44,7 +44,7 @@ /** * Represents an atomic read-and-add operation like {@link Unsafe#getAndAddInt(Object, long, int)}. */ -@NodeInfo(allowedUsageTypes = Memory, cycles = CYCLES_10, size = SIZE_3) +@NodeInfo(allowedUsageTypes = Memory, cycles = CYCLES_8, size = SIZE_2) public final class AtomicReadAndAddNode extends AbstractMemoryCheckpoint implements LIRLowerable, MemoryCheckpoint.Single { public static final NodeClass TYPE = NodeClass.create(AtomicReadAndAddNode.class); diff -r d5572756efd6 -r ab5b504181d8 hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/java/AtomicReadAndWriteNode.java --- a/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/java/AtomicReadAndWriteNode.java Tue Apr 18 20:10:55 2017 -0700 +++ b/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/java/AtomicReadAndWriteNode.java Wed Apr 19 04:10:56 2017 +0000 @@ -22,8 +22,8 @@ */ package org.graalvm.compiler.nodes.java; -import static org.graalvm.compiler.nodeinfo.NodeCycles.CYCLES_10; -import static org.graalvm.compiler.nodeinfo.NodeSize.SIZE_4; +import static org.graalvm.compiler.nodeinfo.NodeCycles.CYCLES_8; +import static org.graalvm.compiler.nodeinfo.NodeSize.SIZE_2; import org.graalvm.compiler.core.common.LocationIdentity; import org.graalvm.compiler.core.common.type.StampFactory; @@ -42,7 +42,7 @@ * Represents an atomic read-and-write operation like {@link Unsafe#getAndSetInt(Object, long, int)} * . */ -@NodeInfo(cycles = CYCLES_10, size = SIZE_4) +@NodeInfo(cycles = CYCLES_8, size = SIZE_2) public final class AtomicReadAndWriteNode extends AbstractMemoryCheckpoint implements Lowerable, MemoryCheckpoint.Single { public static final NodeClass TYPE = NodeClass.create(AtomicReadAndWriteNode.class); diff -r d5572756efd6 -r ab5b504181d8 hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/java/ClassIsAssignableFromNode.java --- a/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/java/ClassIsAssignableFromNode.java Tue Apr 18 20:10:55 2017 -0700 +++ b/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/java/ClassIsAssignableFromNode.java Wed Apr 19 04:10:56 2017 +0000 @@ -22,8 +22,8 @@ */ package org.graalvm.compiler.nodes.java; -import static org.graalvm.compiler.nodeinfo.NodeCycles.CYCLES_30; -import static org.graalvm.compiler.nodeinfo.NodeSize.SIZE_30; +import static org.graalvm.compiler.nodeinfo.NodeCycles.CYCLES_32; +import static org.graalvm.compiler.nodeinfo.NodeSize.SIZE_32; import org.graalvm.compiler.core.common.type.Stamp; import org.graalvm.compiler.graph.Node; @@ -46,7 +46,7 @@ * against instances. This is used, for instance, to intrinsify * {@link Class#isAssignableFrom(Class)} . */ -@NodeInfo(cycles = CYCLES_30, size = SIZE_30) +@NodeInfo(cycles = CYCLES_32, size = SIZE_32) public final class ClassIsAssignableFromNode extends BinaryOpLogicNode implements Canonicalizable.Binary, Lowerable { public static final NodeClass TYPE = NodeClass.create(ClassIsAssignableFromNode.class); diff -r d5572756efd6 -r ab5b504181d8 hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/java/ExceptionObjectNode.java --- a/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/java/ExceptionObjectNode.java Tue Apr 18 20:10:55 2017 -0700 +++ b/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/java/ExceptionObjectNode.java Wed Apr 19 04:10:56 2017 +0000 @@ -23,7 +23,7 @@ package org.graalvm.compiler.nodes.java; import static org.graalvm.compiler.nodeinfo.InputType.Memory; -import static org.graalvm.compiler.nodeinfo.NodeCycles.CYCLES_10; +import static org.graalvm.compiler.nodeinfo.NodeCycles.CYCLES_8; import static org.graalvm.compiler.nodeinfo.NodeSize.SIZE_8; import org.graalvm.compiler.core.common.LocationIdentity; @@ -47,7 +47,7 @@ * The entry to an exception handler with the exception coming from a call (as opposed to a local * throw instruction or implicit exception). */ -@NodeInfo(allowedUsageTypes = Memory, cycles = CYCLES_10, size = SIZE_8) +@NodeInfo(allowedUsageTypes = Memory, cycles = CYCLES_8, size = SIZE_8) public final class ExceptionObjectNode extends BeginStateSplitNode implements Lowerable, MemoryCheckpoint.Single { public static final NodeClass TYPE = NodeClass.create(ExceptionObjectNode.class); diff -r d5572756efd6 -r ab5b504181d8 hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/java/FinalFieldBarrierNode.java --- a/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/java/FinalFieldBarrierNode.java Tue Apr 18 20:10:55 2017 -0700 +++ b/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/java/FinalFieldBarrierNode.java Wed Apr 19 04:10:56 2017 +0000 @@ -22,10 +22,10 @@ */ package org.graalvm.compiler.nodes.java; -import static org.graalvm.compiler.nodeinfo.NodeCycles.CYCLES_20; -import static org.graalvm.compiler.nodeinfo.NodeSize.SIZE_2; import static jdk.vm.ci.code.MemoryBarriers.LOAD_STORE; import static jdk.vm.ci.code.MemoryBarriers.STORE_STORE; +import static org.graalvm.compiler.nodeinfo.NodeCycles.CYCLES_2; +import static org.graalvm.compiler.nodeinfo.NodeSize.SIZE_2; import org.graalvm.compiler.core.common.type.StampFactory; import org.graalvm.compiler.graph.NodeClass; @@ -39,7 +39,7 @@ import org.graalvm.compiler.nodes.spi.VirtualizerTool; import org.graalvm.compiler.nodes.virtual.VirtualObjectNode; -@NodeInfo(cycles = CYCLES_20, size = SIZE_2) +@NodeInfo(cycles = CYCLES_2, size = SIZE_2) public class FinalFieldBarrierNode extends FixedWithNextNode implements Virtualizable, Lowerable { public static final NodeClass TYPE = NodeClass.create(FinalFieldBarrierNode.class); diff -r d5572756efd6 -r ab5b504181d8 hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/java/InstanceOfDynamicNode.java --- a/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/java/InstanceOfDynamicNode.java Tue Apr 18 20:10:55 2017 -0700 +++ b/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/java/InstanceOfDynamicNode.java Wed Apr 19 04:10:56 2017 +0000 @@ -22,8 +22,8 @@ */ package org.graalvm.compiler.nodes.java; -import static org.graalvm.compiler.nodeinfo.NodeCycles.CYCLES_30; -import static org.graalvm.compiler.nodeinfo.NodeSize.SIZE_30; +import static org.graalvm.compiler.nodeinfo.NodeCycles.CYCLES_32; +import static org.graalvm.compiler.nodeinfo.NodeSize.SIZE_32; import org.graalvm.compiler.core.common.type.Stamp; import org.graalvm.compiler.core.common.type.TypeReference; @@ -50,7 +50,7 @@ * known at compile time. This is used, for instance, to intrinsify {@link Class#isInstance(Object)} * . */ -@NodeInfo(cycles = CYCLES_30, size = SIZE_30) +@NodeInfo(cycles = CYCLES_32, size = SIZE_32) public class InstanceOfDynamicNode extends BinaryOpLogicNode implements Canonicalizable.Binary, Lowerable { public static final NodeClass TYPE = NodeClass.create(InstanceOfDynamicNode.class); diff -r d5572756efd6 -r ab5b504181d8 hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/java/InstanceOfNode.java --- a/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/java/InstanceOfNode.java Tue Apr 18 20:10:55 2017 -0700 +++ b/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/java/InstanceOfNode.java Wed Apr 19 04:10:56 2017 +0000 @@ -23,8 +23,8 @@ package org.graalvm.compiler.nodes.java; import static org.graalvm.compiler.nodeinfo.InputType.Anchor; -import static org.graalvm.compiler.nodeinfo.NodeCycles.CYCLES_15; -import static org.graalvm.compiler.nodeinfo.NodeSize.SIZE_15; +import static org.graalvm.compiler.nodeinfo.NodeCycles.CYCLES_8; +import static org.graalvm.compiler.nodeinfo.NodeSize.SIZE_8; import org.graalvm.compiler.core.common.type.ObjectStamp; import org.graalvm.compiler.core.common.type.Stamp; @@ -52,7 +52,7 @@ /** * The {@code InstanceOfNode} represents an instanceof test. */ -@NodeInfo(cycles = CYCLES_15, size = SIZE_15) +@NodeInfo(cycles = CYCLES_8, size = SIZE_8) public class InstanceOfNode extends UnaryOpLogicNode implements Lowerable, Virtualizable { public static final NodeClass TYPE = NodeClass.create(InstanceOfNode.class); diff -r d5572756efd6 -r ab5b504181d8 hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/java/LoadExceptionObjectNode.java --- a/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/java/LoadExceptionObjectNode.java Tue Apr 18 20:10:55 2017 -0700 +++ b/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/java/LoadExceptionObjectNode.java Wed Apr 19 04:10:56 2017 +0000 @@ -22,7 +22,7 @@ */ package org.graalvm.compiler.nodes.java; -import static org.graalvm.compiler.nodeinfo.NodeCycles.CYCLES_10; +import static org.graalvm.compiler.nodeinfo.NodeCycles.CYCLES_8; import static org.graalvm.compiler.nodeinfo.NodeSize.SIZE_8; import org.graalvm.compiler.core.common.type.Stamp; @@ -32,7 +32,7 @@ import org.graalvm.compiler.nodes.spi.Lowerable; import org.graalvm.compiler.nodes.spi.LoweringTool; -@NodeInfo(cycles = CYCLES_10, size = SIZE_8) +@NodeInfo(cycles = CYCLES_8, size = SIZE_8) public final class LoadExceptionObjectNode extends AbstractStateSplit implements Lowerable { public static final NodeClass TYPE = NodeClass.create(LoadExceptionObjectNode.class); diff -r d5572756efd6 -r ab5b504181d8 hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/java/LoadFieldNode.java --- a/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/java/LoadFieldNode.java Tue Apr 18 20:10:55 2017 -0700 +++ b/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/java/LoadFieldNode.java Wed Apr 19 04:10:56 2017 +0000 @@ -23,6 +23,7 @@ package org.graalvm.compiler.nodes.java; import static org.graalvm.compiler.graph.iterators.NodePredicates.isNotA; +import static org.graalvm.compiler.nodeinfo.NodeCycles.CYCLES_2; import jdk.vm.ci.meta.ConstantReflectionProvider; import org.graalvm.compiler.core.common.spi.ConstantFieldProvider; @@ -32,6 +33,7 @@ import org.graalvm.compiler.graph.NodeClass; import org.graalvm.compiler.graph.spi.Canonicalizable; import org.graalvm.compiler.graph.spi.CanonicalizerTool; +import org.graalvm.compiler.nodeinfo.NodeCycles; import org.graalvm.compiler.nodeinfo.NodeInfo; import org.graalvm.compiler.nodes.ConstantNode; import org.graalvm.compiler.nodes.DeoptimizeNode; @@ -195,4 +197,12 @@ this.updateUsages(object, newObject); this.object = newObject; } + + @Override + public NodeCycles estimatedNodeCycles() { + if (field.isVolatile()) { + return CYCLES_2; + } + return super.estimatedNodeCycles(); + } } diff -r d5572756efd6 -r ab5b504181d8 hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/java/LogicCompareAndSwapNode.java --- a/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/java/LogicCompareAndSwapNode.java Tue Apr 18 20:10:55 2017 -0700 +++ b/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/java/LogicCompareAndSwapNode.java Wed Apr 19 04:10:56 2017 +0000 @@ -22,7 +22,7 @@ */ package org.graalvm.compiler.nodes.java; -import static org.graalvm.compiler.nodeinfo.NodeCycles.CYCLES_30; +import static org.graalvm.compiler.nodeinfo.NodeCycles.CYCLES_8; import static org.graalvm.compiler.nodeinfo.NodeSize.SIZE_8; import org.graalvm.compiler.core.common.LIRKind; @@ -44,7 +44,7 @@ * * This version returns a boolean indicating is the CAS was successful or not. */ -@NodeInfo(cycles = CYCLES_30, size = SIZE_8) +@NodeInfo(cycles = CYCLES_8, size = SIZE_8) public final class LogicCompareAndSwapNode extends AbstractCompareAndSwapNode { public static final NodeClass TYPE = NodeClass.create(LogicCompareAndSwapNode.class); diff -r d5572756efd6 -r ab5b504181d8 hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/java/MethodCallTargetNode.java --- a/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/java/MethodCallTargetNode.java Tue Apr 18 20:10:55 2017 -0700 +++ b/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/java/MethodCallTargetNode.java Wed Apr 19 04:10:56 2017 +0000 @@ -132,8 +132,11 @@ return targetMethod; } - Assumptions assumptions = receiver.graph().getAssumptions(); - TypeReference type = StampTool.typeReferenceOrNull(receiver); + return devirtualizeCall(invokeKind, targetMethod, contextType, receiver.graph().getAssumptions(), receiver.stamp()); + } + + public static ResolvedJavaMethod devirtualizeCall(InvokeKind invokeKind, ResolvedJavaMethod targetMethod, ResolvedJavaType contextType, Assumptions assumptions, Stamp receiverStamp) { + TypeReference type = StampTool.typeReferenceOrNull(receiverStamp); if (type == null && invokeKind == InvokeKind.Virtual) { // For virtual calls, we are guaranteed to receive a correct receiver type. type = TypeReference.createTrusted(assumptions, targetMethod.getDeclaringClass()); @@ -155,7 +158,6 @@ return uniqueConcreteMethod.getResult(); } } - return null; } diff -r d5572756efd6 -r ab5b504181d8 hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/java/MonitorEnterNode.java --- a/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/java/MonitorEnterNode.java Tue Apr 18 20:10:55 2017 -0700 +++ b/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/java/MonitorEnterNode.java Wed Apr 19 04:10:56 2017 +0000 @@ -22,8 +22,8 @@ */ package org.graalvm.compiler.nodes.java; -import static org.graalvm.compiler.nodeinfo.NodeCycles.CYCLES_100; -import static org.graalvm.compiler.nodeinfo.NodeSize.SIZE_100; +import static org.graalvm.compiler.nodeinfo.NodeCycles.CYCLES_64; +import static org.graalvm.compiler.nodeinfo.NodeSize.SIZE_64; import org.graalvm.compiler.core.common.LocationIdentity; import org.graalvm.compiler.graph.IterableNodeType; @@ -41,7 +41,7 @@ /** * The {@code MonitorEnterNode} represents the acquisition of a monitor. */ -@NodeInfo(cycles = CYCLES_100, size = SIZE_100) +@NodeInfo(cycles = CYCLES_64, size = SIZE_64) public class MonitorEnterNode extends AccessMonitorNode implements Virtualizable, Lowerable, IterableNodeType, MonitorEnter, MemoryCheckpoint.Single { public static final NodeClass TYPE = NodeClass.create(MonitorEnterNode.class); diff -r d5572756efd6 -r ab5b504181d8 hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/java/MonitorExitNode.java --- a/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/java/MonitorExitNode.java Tue Apr 18 20:10:55 2017 -0700 +++ b/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/java/MonitorExitNode.java Wed Apr 19 04:10:56 2017 +0000 @@ -22,8 +22,8 @@ */ package org.graalvm.compiler.nodes.java; -import static org.graalvm.compiler.nodeinfo.NodeCycles.CYCLES_50; -import static org.graalvm.compiler.nodeinfo.NodeSize.SIZE_100; +import static org.graalvm.compiler.nodeinfo.NodeCycles.CYCLES_64; +import static org.graalvm.compiler.nodeinfo.NodeSize.SIZE_64; import org.graalvm.compiler.core.common.LocationIdentity; import org.graalvm.compiler.graph.IterableNodeType; @@ -43,7 +43,7 @@ * a synchronized method, then the return value of the method will be referenced via the edge * {@link #escapedReturnValue}, so that it will be materialized before releasing the monitor. */ -@NodeInfo(cycles = CYCLES_50, size = SIZE_100) +@NodeInfo(cycles = CYCLES_64, size = SIZE_64) public final class MonitorExitNode extends AccessMonitorNode implements Virtualizable, Lowerable, IterableNodeType, MonitorExit, MemoryCheckpoint.Single { public static final NodeClass TYPE = NodeClass.create(MonitorExitNode.class); diff -r d5572756efd6 -r ab5b504181d8 hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/java/NewMultiArrayNode.java --- a/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/java/NewMultiArrayNode.java Tue Apr 18 20:10:55 2017 -0700 +++ b/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/java/NewMultiArrayNode.java Wed Apr 19 04:10:56 2017 +0000 @@ -22,8 +22,8 @@ */ package org.graalvm.compiler.nodes.java; -import static org.graalvm.compiler.nodeinfo.NodeCycles.CYCLES_50; -import static org.graalvm.compiler.nodeinfo.NodeSize.SIZE_50; +import static org.graalvm.compiler.nodeinfo.NodeCycles.CYCLES_8; +import static org.graalvm.compiler.nodeinfo.NodeSize.SIZE_8; import org.graalvm.compiler.core.common.type.StampFactory; import org.graalvm.compiler.core.common.type.TypeReference; @@ -42,7 +42,7 @@ /** * The {@code NewMultiArrayNode} represents an allocation of a multi-dimensional object array. */ -@NodeInfo(cycles = CYCLES_50, size = SIZE_50) +@NodeInfo(cycles = CYCLES_8, size = SIZE_8) public class NewMultiArrayNode extends DeoptimizingFixedWithNextNode implements Lowerable, ArrayLengthProvider { public static final NodeClass TYPE = NodeClass.create(NewMultiArrayNode.class); diff -r d5572756efd6 -r ab5b504181d8 hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/java/RawMonitorEnterNode.java --- a/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/java/RawMonitorEnterNode.java Tue Apr 18 20:10:55 2017 -0700 +++ b/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/java/RawMonitorEnterNode.java Wed Apr 19 04:10:56 2017 +0000 @@ -22,8 +22,8 @@ */ package org.graalvm.compiler.nodes.java; -import static org.graalvm.compiler.nodeinfo.NodeCycles.CYCLES_80; -import static org.graalvm.compiler.nodeinfo.NodeSize.SIZE_80; +import static org.graalvm.compiler.nodeinfo.NodeCycles.CYCLES_64; +import static org.graalvm.compiler.nodeinfo.NodeSize.SIZE_64; import org.graalvm.compiler.core.common.LocationIdentity; import org.graalvm.compiler.core.common.type.ObjectStamp; @@ -44,9 +44,9 @@ * already be non-null and the hub is an additional parameter to the node. */ // @formatter:off -@NodeInfo(cycles = CYCLES_80, +@NodeInfo(cycles = CYCLES_64, cyclesRationale = "Rough estimation of the enter operation", - size = SIZE_80) + size = SIZE_64) // @formatter:on public final class RawMonitorEnterNode extends AccessMonitorNode implements Virtualizable, Lowerable, IterableNodeType, MonitorEnter, MemoryCheckpoint.Single { diff -r d5572756efd6 -r ab5b504181d8 hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/java/RegisterFinalizerNode.java --- a/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/java/RegisterFinalizerNode.java Tue Apr 18 20:10:55 2017 -0700 +++ b/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/java/RegisterFinalizerNode.java Wed Apr 19 04:10:56 2017 +0000 @@ -24,7 +24,7 @@ import static org.graalvm.compiler.nodeinfo.InputType.State; import static org.graalvm.compiler.nodeinfo.NodeCycles.CYCLES_UNKNOWN; -import static org.graalvm.compiler.nodeinfo.NodeSize.SIZE_20; +import static org.graalvm.compiler.nodeinfo.NodeSize.SIZE_8; import static org.graalvm.compiler.nodes.java.ForeignCallDescriptors.REGISTER_FINALIZER; import org.graalvm.compiler.core.common.spi.ForeignCallLinkage; @@ -54,7 +54,7 @@ // @formatter:off @NodeInfo(cycles = CYCLES_UNKNOWN, cyclesRationale = "We cannot estimate the time of a runtime call.", - size = SIZE_20, + size = SIZE_8, sizeRationale = "Rough estimation for register handling & calling") // @formatter:on public final class RegisterFinalizerNode extends AbstractStateSplit implements Canonicalizable.Unary, LIRLowerable, Virtualizable, DeoptimizingNode.DeoptAfter { diff -r d5572756efd6 -r ab5b504181d8 hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/java/StoreFieldNode.java --- a/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/java/StoreFieldNode.java Tue Apr 18 20:10:55 2017 -0700 +++ b/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/java/StoreFieldNode.java Wed Apr 19 04:10:56 2017 +0000 @@ -22,9 +22,12 @@ */ package org.graalvm.compiler.nodes.java; +import static org.graalvm.compiler.nodeinfo.NodeCycles.CYCLES_8; + import org.graalvm.compiler.core.common.type.StampFactory; import org.graalvm.compiler.graph.NodeClass; import org.graalvm.compiler.nodeinfo.InputType; +import org.graalvm.compiler.nodeinfo.NodeCycles; import org.graalvm.compiler.nodeinfo.NodeInfo; import org.graalvm.compiler.nodes.ConstantNode; import org.graalvm.compiler.nodes.FrameState; @@ -103,4 +106,12 @@ public FrameState getState() { return stateAfter; } + + @Override + public NodeCycles estimatedNodeCycles() { + if (field.isVolatile()) { + return CYCLES_8; + } + return super.estimatedNodeCycles(); + } } diff -r d5572756efd6 -r ab5b504181d8 hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/java/UnsafeCompareAndSwapNode.java --- a/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/java/UnsafeCompareAndSwapNode.java Tue Apr 18 20:10:55 2017 -0700 +++ b/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/java/UnsafeCompareAndSwapNode.java Wed Apr 19 04:10:56 2017 +0000 @@ -24,7 +24,7 @@ import static org.graalvm.compiler.nodeinfo.InputType.Memory; import static org.graalvm.compiler.nodeinfo.InputType.Value; -import static org.graalvm.compiler.nodeinfo.NodeCycles.CYCLES_30; +import static org.graalvm.compiler.nodeinfo.NodeCycles.CYCLES_8; import static org.graalvm.compiler.nodeinfo.NodeSize.SIZE_8; import org.graalvm.compiler.core.common.LocationIdentity; @@ -43,7 +43,7 @@ * Represents an atomic compare-and-swap operation The result is a boolean that contains whether the * value matched the expected value. */ -@NodeInfo(allowedUsageTypes = {Value, Memory}, cycles = CYCLES_30, size = SIZE_8) +@NodeInfo(allowedUsageTypes = {Value, Memory}, cycles = CYCLES_8, size = SIZE_8) public final class UnsafeCompareAndSwapNode extends AbstractMemoryCheckpoint implements Lowerable, MemoryCheckpoint.Single { public static final NodeClass TYPE = NodeClass.create(UnsafeCompareAndSwapNode.class); diff -r d5572756efd6 -r ab5b504181d8 hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/java/ValueCompareAndSwapNode.java --- a/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/java/ValueCompareAndSwapNode.java Tue Apr 18 20:10:55 2017 -0700 +++ b/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/java/ValueCompareAndSwapNode.java Wed Apr 19 04:10:56 2017 +0000 @@ -22,7 +22,7 @@ */ package org.graalvm.compiler.nodes.java; -import static org.graalvm.compiler.nodeinfo.NodeCycles.CYCLES_30; +import static org.graalvm.compiler.nodeinfo.NodeCycles.CYCLES_8; import static org.graalvm.compiler.nodeinfo.NodeSize.SIZE_8; import org.graalvm.compiler.core.common.LocationIdentity; @@ -37,7 +37,7 @@ * A special purpose store node that differs from {@link LogicCompareAndSwapNode} in that it returns * either the expected value or the compared against value instead of a boolean. */ -@NodeInfo(cycles = CYCLES_30, size = SIZE_8) +@NodeInfo(cycles = CYCLES_8, size = SIZE_8) public final class ValueCompareAndSwapNode extends AbstractCompareAndSwapNode { public static final NodeClass TYPE = NodeClass.create(ValueCompareAndSwapNode.class); diff -r d5572756efd6 -r ab5b504181d8 hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/memory/AbstractWriteNode.java --- a/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/memory/AbstractWriteNode.java Tue Apr 18 20:10:55 2017 -0700 +++ b/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/memory/AbstractWriteNode.java Wed Apr 19 04:10:56 2017 +0000 @@ -22,7 +22,7 @@ */ package org.graalvm.compiler.nodes.memory; -import static org.graalvm.compiler.nodeinfo.NodeCycles.CYCLES_3; +import static org.graalvm.compiler.nodeinfo.NodeCycles.CYCLES_2; import static org.graalvm.compiler.nodeinfo.NodeSize.SIZE_1; import org.graalvm.compiler.core.common.LocationIdentity; @@ -38,7 +38,7 @@ import org.graalvm.compiler.nodes.extended.GuardingNode; import org.graalvm.compiler.nodes.memory.address.AddressNode; -@NodeInfo(allowedUsageTypes = {InputType.Memory, InputType.Guard}, cycles = CYCLES_3, size = SIZE_1) +@NodeInfo(allowedUsageTypes = {InputType.Memory, InputType.Guard}, cycles = CYCLES_2, size = SIZE_1) public abstract class AbstractWriteNode extends FixedAccessNode implements StateSplit, MemoryCheckpoint.Single, MemoryAccess, GuardingNode { public static final NodeClass TYPE = NodeClass.create(AbstractWriteNode.class); diff -r d5572756efd6 -r ab5b504181d8 hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/spi/DefaultNodeCostProvider.java --- a/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/spi/DefaultNodeCostProvider.java Tue Apr 18 20:10:55 2017 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,195 +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.nodes.spi; - -import static org.graalvm.compiler.nodeinfo.NodeCycles.CYCLES_1; -import static org.graalvm.compiler.nodeinfo.NodeCycles.CYCLES_100; -import static org.graalvm.compiler.nodeinfo.NodeCycles.CYCLES_15; -import static org.graalvm.compiler.nodeinfo.NodeCycles.CYCLES_2; -import static org.graalvm.compiler.nodeinfo.NodeCycles.CYCLES_20; -import static org.graalvm.compiler.nodeinfo.NodeCycles.CYCLES_30; -import static org.graalvm.compiler.nodeinfo.NodeCycles.CYCLES_4; -import static org.graalvm.compiler.nodeinfo.NodeCycles.CYCLES_40; -import static org.graalvm.compiler.nodeinfo.NodeCycles.CYCLES_80; -import static org.graalvm.compiler.nodeinfo.NodeSize.SIZE_1; -import static org.graalvm.compiler.nodeinfo.NodeSize.SIZE_10; -import static org.graalvm.compiler.nodeinfo.NodeSize.SIZE_100; -import static org.graalvm.compiler.nodeinfo.NodeSize.SIZE_15; -import static org.graalvm.compiler.nodeinfo.NodeSize.SIZE_2; -import static org.graalvm.compiler.nodeinfo.NodeSize.SIZE_200; -import static org.graalvm.compiler.nodeinfo.NodeSize.SIZE_30; -import static org.graalvm.compiler.nodeinfo.NodeSize.SIZE_4; -import static org.graalvm.compiler.nodeinfo.NodeSize.SIZE_50; -import static org.graalvm.compiler.nodeinfo.NodeSize.SIZE_6; -import static org.graalvm.compiler.nodeinfo.NodeSize.SIZE_80; - -import org.graalvm.compiler.graph.Node; -import org.graalvm.compiler.nodeinfo.NodeCycles; -import org.graalvm.compiler.nodeinfo.NodeSize; -import org.graalvm.compiler.nodes.CallTargetNode; -import org.graalvm.compiler.nodes.Invoke; -import org.graalvm.compiler.nodes.LoopEndNode; -import org.graalvm.compiler.nodes.extended.IntegerSwitchNode; -import org.graalvm.compiler.nodes.extended.SwitchNode; -import org.graalvm.compiler.nodes.java.AccessFieldNode; -import org.graalvm.compiler.nodes.virtual.CommitAllocationNode; - -/* - * Certain node costs can not, based on the meta information encoded in the node properties, - * be computed before a real node is instantiated. E.g. the type of a call in Java heavily - * influences the cost of an invocation and thus must be decided dynamically. - */ -public abstract class DefaultNodeCostProvider implements NodeCostProvider { - - @Override - public final int getEstimatedCodeSize(Node n) { - return size(n).estimatedCodeSize; - } - - @Override - public final int getEstimatedCPUCycles(Node n) { - return cycles(n).estimatedCPUCycles; - } - - @Override - public NodeSize size(Node n) { - if (n instanceof Invoke) { - /* - * Code size for the invoke itself is a very weak approximation. - */ - Invoke ivk = (Invoke) n; - CallTargetNode mct = ivk.callTarget(); - switch (mct.invokeKind()) { - case Interface: - return SIZE_50; - case Special: - case Static: - return SIZE_2; - case Virtual: - return SIZE_4; - default: - break; - } - } else if (n instanceof CommitAllocationNode) { - CommitAllocationNode commit = (CommitAllocationNode) n; - /* - * very weak approximation, current problem is node size is an enum and we cannot - * dynamically instantiate a new case like nrOfAllocs*allocationCodeSize - */ - int nrOfAllocs = commit.getVirtualObjects().size(); - if (nrOfAllocs < 5) { - return SIZE_80; - } else if (nrOfAllocs < 10) { - return SIZE_100; - } else { - return SIZE_200; - } - } else if (n instanceof AccessFieldNode) { - if (((AccessFieldNode) n).field().isVolatile()) { - // membar size is added - return SIZE_10; - } - } else if (n instanceof LoopEndNode) { - if (((LoopEndNode) n).canSafepoint()) { - return SIZE_6; - } - } else if (n instanceof SwitchNode) { - SwitchNode x = (SwitchNode) n; - int keyCount = x.keyCount(); - if (keyCount == 0) { - return SIZE_1; - } else { - if (keyCount == 1) { - // if - return SIZE_2; - } else if (x instanceof IntegerSwitchNode && x.isSorted()) { - // good heuristic - return SIZE_15; - } else { - // not so good - return SIZE_30; - } - } - } - - return n.getNodeClass().size(); - } - - @Override - public NodeCycles cycles(Node n) { - if (n instanceof Invoke) { - Invoke ivk = (Invoke) n; - CallTargetNode mct = ivk.callTarget(); - switch (mct.invokeKind()) { - case Interface: - return CYCLES_100; - case Special: - case Static: - return CYCLES_2; - case Virtual: - return CYCLES_4; - default: - break; - } - } else if (n instanceof CommitAllocationNode) { - CommitAllocationNode commit = (CommitAllocationNode) n; - /* - * very weak approximation, current problem is node cycles is an enum and we cannot - * dynamically instantiate a new case like nrOfAllocs*allocationCost - */ - int nrOfAllocs = commit.getVirtualObjects().size(); - if (nrOfAllocs < 5) { - return CYCLES_20; - } else if (nrOfAllocs < 10) { - return CYCLES_40; - } else { - return CYCLES_80; - } - } else if (n instanceof AccessFieldNode) { - if (((AccessFieldNode) n).field().isVolatile()) { - // membar cycles is added - return CYCLES_30; - } - } else if (n instanceof SwitchNode) { - SwitchNode x = (SwitchNode) n; - int keyCount = x.keyCount(); - if (keyCount == 0) { - return CYCLES_1; - } else { - if (keyCount == 1) { - // if - return CYCLES_2; - } else if (x instanceof IntegerSwitchNode && x.isSorted()) { - // good heuristic - return CYCLES_15; - } else { - // not so good - return CYCLES_30; - } - } - } - - return n.getNodeClass().cycles(); - } - -} diff -r d5572756efd6 -r ab5b504181d8 hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/spi/LoweringProvider.java --- a/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/spi/LoweringProvider.java Tue Apr 18 20:10:55 2017 -0700 +++ b/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/spi/LoweringProvider.java Wed Apr 19 04:10:56 2017 +0000 @@ -46,11 +46,10 @@ ValueNode reconstructArrayIndex(JavaKind elementKind, AddressNode address); /** - * Indicates whether the target platform supports comparison of integers of a particular bit - * width. This check is used by optimizations that might introduce subword compares. + * Indicates the smallest width for comparing an integer value on the target platform. */ - default boolean supportSubwordCompare(int bits) { + default Integer smallestCompareWidth() { // most platforms only support 32 and 64 bit compares - return bits >= 32; + return 32; } } diff -r d5572756efd6 -r ab5b504181d8 hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/spi/LoweringTool.java --- a/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/spi/LoweringTool.java Tue Apr 18 20:10:55 2017 -0700 +++ b/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/spi/LoweringTool.java Wed Apr 19 04:10:56 2017 +0000 @@ -49,8 +49,6 @@ StampProvider getStampProvider(); - NodeCostProvider getNodeCostProvider(); - GuardingNode createGuard(FixedNode before, LogicNode condition, DeoptimizationReason deoptReason, DeoptimizationAction action); GuardingNode createGuard(FixedNode before, LogicNode condition, DeoptimizationReason deoptReason, DeoptimizationAction action, JavaConstant speculation, boolean negated); diff -r d5572756efd6 -r ab5b504181d8 hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/spi/NodeCostProvider.java --- a/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/spi/NodeCostProvider.java Tue Apr 18 20:10:55 2017 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,56 +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.nodes.spi; - -import org.graalvm.compiler.graph.Node; -import org.graalvm.compiler.nodeinfo.NodeCycles; -import org.graalvm.compiler.nodeinfo.NodeInfo; -import org.graalvm.compiler.nodeinfo.NodeSize; - -/** - * A provider that enables overriding and customization of the {@link NodeCycles} and - * {@link NodeSize} values for a {@linkplain Node node}. - */ -public interface NodeCostProvider { - - /** - * Gets the estimated size of machine code generated for {@code n}. - */ - int getEstimatedCodeSize(Node n); - - /** - * Gets the estimated execution cost for {@code n} in terms of CPU cycles. - */ - int getEstimatedCPUCycles(Node n); - - /** - * @see NodeInfo#size() - */ - NodeSize size(Node n); - - /** - * @see NodeInfo#cycles() - */ - NodeCycles cycles(Node n); - -} diff -r d5572756efd6 -r ab5b504181d8 hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/util/GraphUtil.java --- a/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/util/GraphUtil.java Tue Apr 18 20:10:55 2017 -0700 +++ b/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/util/GraphUtil.java Wed Apr 19 04:10:56 2017 +0000 @@ -877,11 +877,11 @@ } @Override - public boolean supportSubwordCompare(int bits) { + public Integer smallestCompareWidth() { if (loweringProvider != null) { - return loweringProvider.supportSubwordCompare(bits); + return loweringProvider.smallestCompareWidth(); } else { - return false; + return null; } } } diff -r d5572756efd6 -r ab5b504181d8 hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/virtual/CommitAllocationNode.java --- a/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/virtual/CommitAllocationNode.java Tue Apr 18 20:10:55 2017 -0700 +++ b/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/virtual/CommitAllocationNode.java Wed Apr 19 04:10:56 2017 +0000 @@ -38,11 +38,15 @@ import org.graalvm.compiler.graph.NodeInputList; import org.graalvm.compiler.graph.spi.Simplifiable; import org.graalvm.compiler.graph.spi.SimplifierTool; +import org.graalvm.compiler.nodeinfo.NodeCycles; import org.graalvm.compiler.nodeinfo.NodeInfo; +import org.graalvm.compiler.nodeinfo.NodeSize; import org.graalvm.compiler.nodeinfo.Verbosity; import org.graalvm.compiler.nodes.FixedWithNextNode; import org.graalvm.compiler.nodes.ValueNode; +import org.graalvm.compiler.nodes.java.AbstractNewObjectNode; import org.graalvm.compiler.nodes.java.MonitorIdNode; +import org.graalvm.compiler.nodes.memory.WriteNode; import org.graalvm.compiler.nodes.spi.Lowerable; import org.graalvm.compiler.nodes.spi.LoweringTool; import org.graalvm.compiler.nodes.spi.VirtualizableAllocation; @@ -227,4 +231,28 @@ ensureVirtual = newEnsureVirtual; } } + + @Override + public NodeCycles estimatedNodeCycles() { + List v = getVirtualObjects(); + int fieldWriteCount = 0; + for (int i = 0; i < v.size(); i++) { + fieldWriteCount += v.get(i).entryCount(); + } + int rawValueWrites = NodeCycles.compute(WriteNode.TYPE.cycles(), fieldWriteCount).value; + int rawValuesTlabBumps = AbstractNewObjectNode.TYPE.cycles().value; + return NodeCycles.compute(rawValueWrites + rawValuesTlabBumps); + } + + @Override + public NodeSize estimatedNodeSize() { + List v = getVirtualObjects(); + int fieldWriteCount = 0; + for (int i = 0; i < v.size(); i++) { + fieldWriteCount += v.get(i).entryCount(); + } + int rawValueWrites = NodeSize.compute(WriteNode.TYPE.size(), fieldWriteCount).value; + int rawValuesTlabBumps = AbstractNewObjectNode.TYPE.size().value; + return NodeSize.compute(rawValueWrites + rawValuesTlabBumps); + } } diff -r d5572756efd6 -r ab5b504181d8 hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.phases.common/src/org/graalvm/compiler/phases/common/CanonicalizerPhase.java --- a/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.phases.common/src/org/graalvm/compiler/phases/common/CanonicalizerPhase.java Tue Apr 18 20:10:55 2017 -0700 +++ b/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.phases.common/src/org/graalvm/compiler/phases/common/CanonicalizerPhase.java Wed Apr 19 04:10:56 2017 +0000 @@ -180,6 +180,11 @@ } @Override + public boolean checkContract() { + return false; + } + + @Override protected void run(StructuredGraph graph) { boolean wholeGraph = newNodesMark == null || newNodesMark.isStart(); if (initWorkingSet == null) { @@ -497,8 +502,8 @@ } @Override - public boolean supportSubwordCompare(int bits) { - return context.getLowerer().supportSubwordCompare(bits); + public Integer smallestCompareWidth() { + return context.getLowerer().smallestCompareWidth(); } @Override diff -r d5572756efd6 -r ab5b504181d8 hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.phases.common/src/org/graalvm/compiler/phases/common/FixReadsPhase.java --- a/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.phases.common/src/org/graalvm/compiler/phases/common/FixReadsPhase.java Tue Apr 18 20:10:55 2017 -0700 +++ b/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.phases.common/src/org/graalvm/compiler/phases/common/FixReadsPhase.java Wed Apr 19 04:10:56 2017 +0000 @@ -88,6 +88,11 @@ private boolean replaceInputsWithConstants; private Phase schedulePhase; + @Override + public float codeSizeIncrease() { + return 2.0f; + } + private static class FixReadsClosure extends ScheduledNodeIterator { @Override diff -r d5572756efd6 -r ab5b504181d8 hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.phases.common/src/org/graalvm/compiler/phases/common/LoweringPhase.java --- a/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.phases.common/src/org/graalvm/compiler/phases/common/LoweringPhase.java Tue Apr 18 20:10:55 2017 -0700 +++ b/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.phases.common/src/org/graalvm/compiler/phases/common/LoweringPhase.java Wed Apr 19 04:10:56 2017 +0000 @@ -66,7 +66,6 @@ import org.graalvm.compiler.nodes.spi.Lowerable; import org.graalvm.compiler.nodes.spi.LoweringProvider; import org.graalvm.compiler.nodes.spi.LoweringTool; -import org.graalvm.compiler.nodes.spi.NodeCostProvider; import org.graalvm.compiler.nodes.spi.Replacements; import org.graalvm.compiler.nodes.spi.StampProvider; import org.graalvm.compiler.options.OptionValues; @@ -209,11 +208,6 @@ return lastFixedNode; } - @Override - public NodeCostProvider getNodeCostProvider() { - return context.getNodeCostProvider(); - } - private void setLastFixedNode(FixedWithNextNode n) { assert n.isAlive() : n; lastFixedNode = n; diff -r d5572756efd6 -r ab5b504181d8 hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.phases.common/src/org/graalvm/compiler/phases/common/inlining/InliningUtil.java --- a/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.phases.common/src/org/graalvm/compiler/phases/common/inlining/InliningUtil.java Tue Apr 18 20:10:55 2017 -0700 +++ b/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.phases.common/src/org/graalvm/compiler/phases/common/inlining/InliningUtil.java Wed Apr 19 04:10:56 2017 +0000 @@ -29,7 +29,6 @@ import java.lang.reflect.Constructor; import java.util.ArrayList; import java.util.List; -import java.util.function.Function; import org.graalvm.compiler.api.replacements.MethodSubstitution; import org.graalvm.compiler.core.common.GraalOptions; @@ -58,9 +57,7 @@ import org.graalvm.compiler.nodes.BeginNode; import org.graalvm.compiler.nodes.CallTargetNode; import org.graalvm.compiler.nodes.CallTargetNode.InvokeKind; -import org.graalvm.compiler.nodes.ControlSinkNode; import org.graalvm.compiler.nodes.DeoptimizeNode; -import org.graalvm.compiler.nodes.EndNode; import org.graalvm.compiler.nodes.FixedGuardNode; import org.graalvm.compiler.nodes.FixedNode; import org.graalvm.compiler.nodes.FixedWithNextNode; @@ -72,7 +69,6 @@ import org.graalvm.compiler.nodes.LogicNode; import org.graalvm.compiler.nodes.MergeNode; import org.graalvm.compiler.nodes.ParameterNode; -import org.graalvm.compiler.nodes.PhiNode; import org.graalvm.compiler.nodes.PiNode; import org.graalvm.compiler.nodes.ReturnNode; import org.graalvm.compiler.nodes.StartNode; @@ -80,7 +76,6 @@ import org.graalvm.compiler.nodes.StructuredGraph; import org.graalvm.compiler.nodes.UnwindNode; import org.graalvm.compiler.nodes.ValueNode; -import org.graalvm.compiler.nodes.ValuePhiNode; import org.graalvm.compiler.nodes.calc.IsNullNode; import org.graalvm.compiler.nodes.extended.ForeignCallNode; import org.graalvm.compiler.nodes.extended.GuardingNode; @@ -93,6 +88,7 @@ import org.graalvm.compiler.nodes.util.GraphUtil; import org.graalvm.compiler.phases.common.inlining.info.InlineInfo; import org.graalvm.compiler.phases.common.util.HashSetNodeEventListener; +import org.graalvm.compiler.phases.util.ValueMergeUtil; import org.graalvm.util.EconomicMap; import org.graalvm.util.EconomicSet; import org.graalvm.util.Equivalence; @@ -108,7 +104,7 @@ import jdk.vm.ci.meta.ResolvedJavaMethod; import jdk.vm.ci.meta.ResolvedJavaType; -public class InliningUtil { +public class InliningUtil extends ValueMergeUtil { private static final String inliningDecisionsScopeString = "InliningDecisions"; @@ -686,48 +682,6 @@ return nonReplaceableFrameState; } - public static ValueNode mergeReturns(AbstractMergeNode merge, List returnNodes) { - return mergeValueProducers(merge, returnNodes, returnNode -> returnNode.result()); - } - - public static ValueNode mergeValueProducers(AbstractMergeNode merge, List valueProducers, Function valueFunction) { - ValueNode singleResult = null; - PhiNode phiResult = null; - for (T valueProducer : valueProducers) { - ValueNode result = valueFunction.apply(valueProducer); - if (result != null) { - if (phiResult == null && (singleResult == null || singleResult == result)) { - /* Only one result value, so no need yet for a phi node. */ - singleResult = result; - } else if (phiResult == null) { - /* Found a second result value, so create phi node. */ - phiResult = merge.graph().addWithoutUnique(new ValuePhiNode(result.stamp().unrestricted(), merge)); - for (int i = 0; i < merge.forwardEndCount(); i++) { - phiResult.addInput(singleResult); - } - phiResult.addInput(result); - - } else { - /* Multiple return values, just add to existing phi node. */ - phiResult.addInput(result); - } - } - - // create and wire up a new EndNode - EndNode endNode = merge.graph().add(new EndNode()); - merge.addForwardEnd(endNode); - valueProducer.replaceAndDelete(endNode); - } - - if (phiResult != null) { - assert phiResult.verify(); - phiResult.inferStamp(); - return phiResult; - } else { - return singleResult; - } - } - /** * Ensure that all states are either {@link BytecodeFrame#INVALID_FRAMESTATE_BCI} or one of * {@link BytecodeFrame#AFTER_BCI} or {@link BytecodeFrame#BEFORE_BCI}. Mixing of before and diff -r d5572756efd6 -r ab5b504181d8 hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.phases/src/org/graalvm/compiler/phases/BasePhase.java --- a/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.phases/src/org/graalvm/compiler/phases/BasePhase.java Tue Apr 18 20:10:55 2017 -0700 +++ b/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.phases/src/org/graalvm/compiler/phases/BasePhase.java Wed Apr 19 04:10:56 2017 +0000 @@ -40,7 +40,6 @@ import org.graalvm.compiler.options.OptionValues; import org.graalvm.compiler.phases.contract.NodeCostUtil; import org.graalvm.compiler.phases.contract.PhaseSizeContract; -import org.graalvm.compiler.phases.tiers.PhaseContext; /** * Base class for all compiler phases. Subclasses should be stateless. There will be one global @@ -193,10 +192,8 @@ OptionValues options = graph.getOptions(); boolean verifySizeContract = PhaseOptions.VerifyGraalPhasesSize.getValue(options) && checkContract(); if (verifySizeContract) { - if (context instanceof PhaseContext) { - sizeBefore = NodeCostUtil.computeGraphSize(graph, ((PhaseContext) context).getNodeCostProvider()); - before = graph.getMark(); - } + sizeBefore = NodeCostUtil.computeGraphSize(graph); + before = graph.getMark(); } BasePhase enclosingPhase = null; if (dumpGraph && Debug.isEnabled()) { @@ -206,11 +203,9 @@ this.run(graph, context); executionCount.increment(); if (verifySizeContract) { - if (context instanceof PhaseContext) { - if (!before.isCurrent()) { - int sizeAfter = NodeCostUtil.computeGraphSize(graph, ((PhaseContext) context).getNodeCostProvider()); - NodeCostUtil.phaseFulfillsSizeContract(graph, sizeBefore, sizeAfter, this); - } + if (!before.isCurrent()) { + int sizeAfter = NodeCostUtil.computeGraphSize(graph); + NodeCostUtil.phaseFulfillsSizeContract(graph, sizeBefore, sizeAfter, this); } } diff -r d5572756efd6 -r ab5b504181d8 hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.phases/src/org/graalvm/compiler/phases/contract/NodeCostUtil.java --- a/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.phases/src/org/graalvm/compiler/phases/contract/NodeCostUtil.java Tue Apr 18 20:10:55 2017 -0700 +++ b/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.phases/src/org/graalvm/compiler/phases/contract/NodeCostUtil.java Wed Apr 19 04:10:56 2017 +0000 @@ -35,7 +35,6 @@ import org.graalvm.compiler.nodes.StructuredGraph; import org.graalvm.compiler.nodes.cfg.Block; import org.graalvm.compiler.nodes.cfg.ControlFlowGraph; -import org.graalvm.compiler.nodes.spi.NodeCostProvider; import org.graalvm.compiler.phases.schedule.SchedulePhase; import jdk.vm.ci.meta.ResolvedJavaMethod; @@ -46,18 +45,18 @@ private static final DebugCounter sizeVerificationCount = Debug.counter("GraphCostVerificationCount_Size"); @SuppressWarnings("try") - public static int computeGraphSize(StructuredGraph graph, NodeCostProvider nodeCostProvider) { + public static int computeGraphSize(StructuredGraph graph) { sizeComputationCount.increment(); int size = 0; for (Node n : graph.getNodes()) { - size += nodeCostProvider.getEstimatedCodeSize(n); + size += n.estimatedNodeSize().value; } assert size >= 0; return size; } @SuppressWarnings("try") - public static double computeGraphCycles(StructuredGraph graph, NodeCostProvider nodeCostProvider, boolean fullSchedule) { + public static double computeGraphCycles(StructuredGraph graph, boolean fullSchedule) { Function> blockToNodes; ControlFlowGraph cfg; if (fullSchedule) { @@ -81,12 +80,12 @@ try (Debug.Scope s = Debug.scope("NodeCostSummary")) { for (Block block : cfg.getBlocks()) { for (Node n : blockToNodes.apply(block)) { - double probWeighted = nodeCostProvider.getEstimatedCPUCycles(n) * block.probability(); + double probWeighted = n.estimatedNodeCycles().value * block.probability(); assert Double.isFinite(probWeighted); weightedCycles += probWeighted; if (Debug.isLogEnabled()) { - Debug.log("Node %s contributes cycles:%f size:%d to graph %s [block prob:%f]", n, nodeCostProvider.getEstimatedCPUCycles(n) * block.probability(), - nodeCostProvider.getEstimatedCodeSize(n), graph, block.probability()); + Debug.log("Node %s contributes cycles:%f size:%d to graph %s [block prob:%f]", n, n.estimatedNodeCycles().value * block.probability(), + n.estimatedNodeSize().value, graph, block.probability()); } } } diff -r d5572756efd6 -r ab5b504181d8 hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.phases/src/org/graalvm/compiler/phases/contract/VerifyNodeCosts.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.phases/src/org/graalvm/compiler/phases/contract/VerifyNodeCosts.java Wed Apr 19 04:10:56 2017 +0000 @@ -0,0 +1,90 @@ +/* + * 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.phases.contract; + +import java.lang.reflect.Field; +import java.lang.reflect.Modifier; +import java.util.function.Predicate; + +import org.graalvm.compiler.graph.Node; +import org.graalvm.compiler.graph.NodeClass; +import org.graalvm.compiler.nodeinfo.NodeCycles; +import org.graalvm.compiler.nodeinfo.NodeInfo; +import org.graalvm.compiler.nodeinfo.NodeSize; +import org.graalvm.compiler.phases.VerifyPhase; + +/** + * Utility class that verifies that every {@link Class} extending {@link Node} specifies non default + * values for {@link NodeCycles} and {@link NodeSize} in its {@link NodeInfo} annotation. + */ +public class VerifyNodeCosts { + + public static void verifyNodeClass(Class clazz) { + Class nodeClass = Node.class; + if (nodeClass.isAssignableFrom(clazz)) { + if (!clazz.isAnnotationPresent(NodeInfo.class)) { + throw new VerifyPhase.VerificationError("%s.java extends Node.java but does not specify a NodeInfo annotation.", clazz.getName()); + } + + if (!Modifier.isAbstract(clazz.getModifiers())) { + boolean cyclesSet = walkCHUntil(getType(clazz), getType(nodeClass), cur -> { + return cur.cycles() != NodeCycles.CYCLES_UNSET; + }); + boolean sizeSet = walkCHUntil(getType(clazz), getType(nodeClass), cur -> { + return cur.size() != NodeSize.SIZE_UNSET; + }); + if (!cyclesSet) { + throw new VerifyPhase.VerificationError("%s.java does not specify a NodeCycles value in its class hierarchy.", clazz.getName()); + } + if (!sizeSet) { + throw new VerifyPhase.VerificationError("%s.java does not specify a NodeSize value in its class hierarchy.", clazz.getName()); + } + } + } + } + + private static NodeClass getType(Class c) { + Field f; + try { + f = c.getField("TYPE"); + f.setAccessible(true); + Object val = f.get(null); + NodeClass nodeType = (NodeClass) val; + return nodeType; + } catch (Throwable t) { + throw new VerifyPhase.VerificationError("%s.java does not specify a TYPE field.", c.getName()); + } + } + + private static boolean walkCHUntil(NodeClass start, NodeClass until, Predicate> p) { + NodeClass cur = start; + while (cur != until && cur != null) { + if (p.test(cur)) { + return true; + } + cur = cur.getSuperNodeClass(); + } + return false; + } + +} diff -r d5572756efd6 -r ab5b504181d8 hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.phases/src/org/graalvm/compiler/phases/tiers/PhaseContext.java --- a/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.phases/src/org/graalvm/compiler/phases/tiers/PhaseContext.java Tue Apr 18 20:10:55 2017 -0700 +++ b/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.phases/src/org/graalvm/compiler/phases/tiers/PhaseContext.java Wed Apr 19 04:10:56 2017 +0000 @@ -24,7 +24,6 @@ import org.graalvm.compiler.core.common.spi.ConstantFieldProvider; import org.graalvm.compiler.nodes.spi.LoweringProvider; -import org.graalvm.compiler.nodes.spi.NodeCostProvider; import org.graalvm.compiler.nodes.spi.Replacements; import org.graalvm.compiler.nodes.spi.StampProvider; import org.graalvm.compiler.phases.util.Providers; @@ -40,22 +39,19 @@ private final LoweringProvider lowerer; private final Replacements replacements; private final StampProvider stampProvider; - private final NodeCostProvider nodeCostProvider; public PhaseContext(MetaAccessProvider metaAccess, ConstantReflectionProvider constantReflection, ConstantFieldProvider constantFieldProvider, LoweringProvider lowerer, Replacements replacements, - StampProvider stampProvider, NodeCostProvider nodeCostProvider) { + StampProvider stampProvider) { this.metaAccess = metaAccess; this.constantReflection = constantReflection; this.constantFieldProvider = constantFieldProvider; this.lowerer = lowerer; this.replacements = replacements; this.stampProvider = stampProvider; - this.nodeCostProvider = nodeCostProvider; } public PhaseContext(Providers providers) { - this(providers.getMetaAccess(), providers.getConstantReflection(), providers.getConstantFieldProvider(), providers.getLowerer(), providers.getReplacements(), providers.getStampProvider(), - providers.getNodeCostProvider()); + this(providers.getMetaAccess(), providers.getConstantReflection(), providers.getConstantFieldProvider(), providers.getLowerer(), providers.getReplacements(), providers.getStampProvider()); } public MetaAccessProvider getMetaAccess() { @@ -82,7 +78,4 @@ return stampProvider; } - public NodeCostProvider getNodeCostProvider() { - return nodeCostProvider; - } } diff -r d5572756efd6 -r ab5b504181d8 hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.phases/src/org/graalvm/compiler/phases/util/Providers.java --- a/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.phases/src/org/graalvm/compiler/phases/util/Providers.java Tue Apr 18 20:10:55 2017 -0700 +++ b/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.phases/src/org/graalvm/compiler/phases/util/Providers.java Wed Apr 19 04:10:56 2017 +0000 @@ -26,7 +26,6 @@ import org.graalvm.compiler.core.common.spi.ConstantFieldProvider; import org.graalvm.compiler.core.common.spi.ForeignCallsProvider; import org.graalvm.compiler.nodes.spi.LoweringProvider; -import org.graalvm.compiler.nodes.spi.NodeCostProvider; import org.graalvm.compiler.nodes.spi.Replacements; import org.graalvm.compiler.nodes.spi.StampProvider; import org.graalvm.compiler.phases.tiers.PhaseContext; @@ -48,10 +47,9 @@ private final ForeignCallsProvider foreignCalls; private final Replacements replacements; private final StampProvider stampProvider; - private final NodeCostProvider nodeCostProvider; public Providers(MetaAccessProvider metaAccess, CodeCacheProvider codeCache, ConstantReflectionProvider constantReflection, ConstantFieldProvider constantFieldProvider, - ForeignCallsProvider foreignCalls, LoweringProvider lowerer, Replacements replacements, StampProvider stampProvider, NodeCostProvider nodeCostProvider) { + ForeignCallsProvider foreignCalls, LoweringProvider lowerer, Replacements replacements, StampProvider stampProvider) { this.metaAccess = metaAccess; this.codeCache = codeCache; this.constantReflection = constantReflection; @@ -60,17 +58,16 @@ this.lowerer = lowerer; this.replacements = replacements; this.stampProvider = stampProvider; - this.nodeCostProvider = nodeCostProvider; } public Providers(Providers copyFrom) { this(copyFrom.getMetaAccess(), copyFrom.getCodeCache(), copyFrom.getConstantReflection(), copyFrom.getConstantFieldProvider(), copyFrom.getForeignCalls(), copyFrom.getLowerer(), - copyFrom.getReplacements(), copyFrom.getStampProvider(), copyFrom.getNodeCostProvider()); + copyFrom.getReplacements(), copyFrom.getStampProvider()); } public Providers(PhaseContext copyFrom) { this(copyFrom.getMetaAccess(), null, copyFrom.getConstantReflection(), copyFrom.getConstantFieldProvider(), null, copyFrom.getLowerer(), copyFrom.getReplacements(), - copyFrom.getStampProvider(), copyFrom.getNodeCostProvider()); + copyFrom.getStampProvider()); } @Override @@ -109,39 +106,35 @@ return stampProvider; } - public NodeCostProvider getNodeCostProvider() { - return nodeCostProvider; - } - public Providers copyWith(MetaAccessProvider substitution) { - return new Providers(substitution, codeCache, constantReflection, constantFieldProvider, foreignCalls, lowerer, replacements, stampProvider, nodeCostProvider); + return new Providers(substitution, codeCache, constantReflection, constantFieldProvider, foreignCalls, lowerer, replacements, stampProvider); } public Providers copyWith(CodeCacheProvider substitution) { - return new Providers(metaAccess, substitution, constantReflection, constantFieldProvider, foreignCalls, lowerer, replacements, stampProvider, nodeCostProvider); + return new Providers(metaAccess, substitution, constantReflection, constantFieldProvider, foreignCalls, lowerer, replacements, stampProvider); } public Providers copyWith(ConstantReflectionProvider substitution) { - return new Providers(metaAccess, codeCache, substitution, constantFieldProvider, foreignCalls, lowerer, replacements, stampProvider, nodeCostProvider); + return new Providers(metaAccess, codeCache, substitution, constantFieldProvider, foreignCalls, lowerer, replacements, stampProvider); } public Providers copyWith(ConstantFieldProvider substitution) { - return new Providers(metaAccess, codeCache, constantReflection, substitution, foreignCalls, lowerer, replacements, stampProvider, nodeCostProvider); + return new Providers(metaAccess, codeCache, constantReflection, substitution, foreignCalls, lowerer, replacements, stampProvider); } public Providers copyWith(ForeignCallsProvider substitution) { - return new Providers(metaAccess, codeCache, constantReflection, constantFieldProvider, substitution, lowerer, replacements, stampProvider, nodeCostProvider); + return new Providers(metaAccess, codeCache, constantReflection, constantFieldProvider, substitution, lowerer, replacements, stampProvider); } public Providers copyWith(LoweringProvider substitution) { - return new Providers(metaAccess, codeCache, constantReflection, constantFieldProvider, foreignCalls, substitution, replacements, stampProvider, nodeCostProvider); + return new Providers(metaAccess, codeCache, constantReflection, constantFieldProvider, foreignCalls, substitution, replacements, stampProvider); } public Providers copyWith(Replacements substitution) { - return new Providers(metaAccess, codeCache, constantReflection, constantFieldProvider, foreignCalls, lowerer, substitution, stampProvider, nodeCostProvider); + return new Providers(metaAccess, codeCache, constantReflection, constantFieldProvider, foreignCalls, lowerer, substitution, stampProvider); } public Providers copyWith(StampProvider substitution) { - return new Providers(metaAccess, codeCache, constantReflection, constantFieldProvider, foreignCalls, lowerer, replacements, substitution, nodeCostProvider); + return new Providers(metaAccess, codeCache, constantReflection, constantFieldProvider, foreignCalls, lowerer, replacements, substitution); } } diff -r d5572756efd6 -r ab5b504181d8 hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.phases/src/org/graalvm/compiler/phases/util/ValueMergeUtil.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.phases/src/org/graalvm/compiler/phases/util/ValueMergeUtil.java Wed Apr 19 04:10:56 2017 +0000 @@ -0,0 +1,87 @@ +/* + * Copyright (c) 2017, 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.phases.util; + +import java.util.List; +import java.util.function.Function; + +import org.graalvm.compiler.nodes.AbstractMergeNode; +import org.graalvm.compiler.nodes.ControlSinkNode; +import org.graalvm.compiler.nodes.EndNode; +import org.graalvm.compiler.nodes.FixedWithNextNode; +import org.graalvm.compiler.nodes.PhiNode; +import org.graalvm.compiler.nodes.ReturnNode; +import org.graalvm.compiler.nodes.UnwindNode; +import org.graalvm.compiler.nodes.ValueNode; +import org.graalvm.compiler.nodes.ValuePhiNode; + +public class ValueMergeUtil { + + public static ValueNode mergeReturns(AbstractMergeNode merge, List returnNodes) { + return mergeValueProducers(merge, returnNodes, null, returnNode -> returnNode.result()); + } + + public static ValueNode mergeValueProducers(AbstractMergeNode merge, List valueProducers, Function lastInstrFunction, Function valueFunction) { + ValueNode singleResult = null; + PhiNode phiResult = null; + for (T valueProducer : valueProducers) { + ValueNode result = valueFunction.apply(valueProducer); + if (result != null) { + if (phiResult == null && (singleResult == null || singleResult == result)) { + /* Only one result value, so no need yet for a phi node. */ + singleResult = result; + } else if (phiResult == null) { + /* Found a second result value, so create phi node. */ + phiResult = merge.graph().addWithoutUnique(new ValuePhiNode(result.stamp().unrestricted(), merge)); + for (int i = 0; i < merge.forwardEndCount(); i++) { + phiResult.addInput(singleResult); + } + phiResult.addInput(result); + + } else { + /* Multiple return values, just add to existing phi node. */ + phiResult.addInput(result); + } + } + + // create and wire up a new EndNode + EndNode endNode = merge.graph().add(new EndNode()); + merge.addForwardEnd(endNode); + if (lastInstrFunction == null) { + assert valueProducer instanceof ReturnNode || valueProducer instanceof UnwindNode; + ((ControlSinkNode) valueProducer).replaceAndDelete(endNode); + } else { + FixedWithNextNode lastInstr = lastInstrFunction.apply(valueProducer); + lastInstr.setNext(endNode); + } + } + + if (phiResult != null) { + assert phiResult.verify(); + phiResult.inferStamp(); + return phiResult; + } else { + return singleResult; + } + } +} diff -r d5572756efd6 -r ab5b504181d8 hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.printer/src/org/graalvm/compiler/printer/BinaryGraphPrinter.java --- a/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.printer/src/org/graalvm/compiler/printer/BinaryGraphPrinter.java Tue Apr 18 20:10:55 2017 -0700 +++ b/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.printer/src/org/graalvm/compiler/printer/BinaryGraphPrinter.java Wed Apr 19 04:10:56 2017 +0000 @@ -510,6 +510,14 @@ props.put("probability-exception", t); } } + + try { + props.put("NodeCost-Size", node.estimatedNodeSize()); + props.put("NodeCost-Cycles", node.estimatedNodeCycles()); + } catch (Throwable t) { + props.put("node-cost-exception", t.getMessage()); + } + if (nodeToBlocks != null) { Object block = getBlockForNode(node, nodeToBlocks); if (block != null) { diff -r d5572756efd6 -r ab5b504181d8 hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.printer/src/org/graalvm/compiler/printer/GraphPrinterDumpHandler.java --- a/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.printer/src/org/graalvm/compiler/printer/GraphPrinterDumpHandler.java Tue Apr 18 20:10:55 2017 -0700 +++ b/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.printer/src/org/graalvm/compiler/printer/GraphPrinterDumpHandler.java Wed Apr 19 04:10:56 2017 +0000 @@ -49,6 +49,7 @@ import org.graalvm.compiler.debug.internal.DebugScope; import org.graalvm.compiler.graph.Graph; import org.graalvm.compiler.nodes.StructuredGraph; +import org.graalvm.compiler.phases.contract.NodeCostUtil; import jdk.vm.ci.meta.JavaMethod; import jdk.vm.ci.meta.ResolvedJavaMethod; @@ -175,6 +176,12 @@ properties.put("scope", Debug.currentScope()); if (graph instanceof StructuredGraph) { properties.put("compilationIdentifier", ((StructuredGraph) graph).compilationId()); + try { + int size = NodeCostUtil.computeGraphSize((StructuredGraph) graph); + properties.put("node-cost graph size", size); + } catch (Throwable t) { + properties.put("node-cost-exception", t.getMessage()); + } } addCFGFileName(properties); printer.print(graph, nextDumpId() + ":" + message, properties); diff -r d5572756efd6 -r ab5b504181d8 hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.printer/src/org/graalvm/compiler/printer/IdealGraphPrinter.java --- a/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.printer/src/org/graalvm/compiler/printer/IdealGraphPrinter.java Tue Apr 18 20:10:55 2017 -0700 +++ b/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.printer/src/org/graalvm/compiler/printer/IdealGraphPrinter.java Wed Apr 19 04:10:56 2017 +0000 @@ -231,6 +231,13 @@ printProperty("hasPredecessor", "true"); } + try { + printProperty("NodeCost-Size", node.estimatedNodeSize().toString()); + printProperty("NodeCost-Cycles", node.estimatedNodeCycles().toString()); + } catch (Throwable t) { + props.put("node-cost-exception", t.getMessage()); + } + for (Entry entry : props.entrySet()) { String key = entry.getKey().toString(); Object value = entry.getValue(); diff -r d5572756efd6 -r ab5b504181d8 hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements.aarch64/src/org/graalvm/compiler/replacements/aarch64/AArch64CountLeadingZerosNode.java --- a/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements.aarch64/src/org/graalvm/compiler/replacements/aarch64/AArch64CountLeadingZerosNode.java Tue Apr 18 20:10:55 2017 -0700 +++ b/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements.aarch64/src/org/graalvm/compiler/replacements/aarch64/AArch64CountLeadingZerosNode.java Wed Apr 19 04:10:56 2017 +0000 @@ -22,7 +22,7 @@ */ package org.graalvm.compiler.replacements.aarch64; -import static org.graalvm.compiler.nodeinfo.NodeCycles.CYCLES_6; +import static org.graalvm.compiler.nodeinfo.NodeCycles.CYCLES_2; import static org.graalvm.compiler.nodeinfo.NodeSize.SIZE_1; import org.graalvm.compiler.core.common.type.IntegerStamp; @@ -42,7 +42,7 @@ import jdk.vm.ci.meta.JavaConstant; import jdk.vm.ci.meta.JavaKind; -@NodeInfo(cycles = CYCLES_6, size = SIZE_1) +@NodeInfo(cycles = CYCLES_2, size = SIZE_1) public final class AArch64CountLeadingZerosNode extends UnaryNode implements ArithmeticLIRLowerable { public static final NodeClass TYPE = NodeClass.create(AArch64CountLeadingZerosNode.class); diff -r d5572756efd6 -r ab5b504181d8 hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements.aarch64/src/org/graalvm/compiler/replacements/aarch64/AArch64CountTrailingZerosNode.java --- a/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements.aarch64/src/org/graalvm/compiler/replacements/aarch64/AArch64CountTrailingZerosNode.java Tue Apr 18 20:10:55 2017 -0700 +++ b/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements.aarch64/src/org/graalvm/compiler/replacements/aarch64/AArch64CountTrailingZerosNode.java Wed Apr 19 04:10:56 2017 +0000 @@ -22,7 +22,7 @@ */ package org.graalvm.compiler.replacements.aarch64; -import static org.graalvm.compiler.nodeinfo.NodeCycles.CYCLES_3; +import static org.graalvm.compiler.nodeinfo.NodeCycles.CYCLES_2; import static org.graalvm.compiler.nodeinfo.NodeSize.SIZE_2; import org.graalvm.compiler.core.common.type.IntegerStamp; @@ -45,7 +45,7 @@ /** * Count the number of trailing zeros using the {@code rbit; clz} instructions. */ -@NodeInfo(cycles = CYCLES_3, size = SIZE_2) +@NodeInfo(cycles = CYCLES_2, size = SIZE_2) public final class AArch64CountTrailingZerosNode extends UnaryNode implements ArithmeticLIRLowerable { public static final NodeClass TYPE = NodeClass.create(AArch64CountTrailingZerosNode.class); diff -r d5572756efd6 -r ab5b504181d8 hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements.aarch64/src/org/graalvm/compiler/replacements/aarch64/AArch64GraphBuilderPlugins.java --- a/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements.aarch64/src/org/graalvm/compiler/replacements/aarch64/AArch64GraphBuilderPlugins.java Tue Apr 18 20:10:55 2017 -0700 +++ b/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements.aarch64/src/org/graalvm/compiler/replacements/aarch64/AArch64GraphBuilderPlugins.java Wed Apr 19 04:10:56 2017 +0000 @@ -99,7 +99,7 @@ r.register2("pow", Double.TYPE, Double.TYPE, new InvocationPlugin() { @Override public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver receiver, ValueNode x, ValueNode y) { - b.push(JavaKind.Double, b.recursiveAppend(BinaryMathIntrinsicNode.create(x, y, BinaryMathIntrinsicNode.BinaryOperation.POW))); + b.push(JavaKind.Double, b.append(BinaryMathIntrinsicNode.create(x, y, BinaryMathIntrinsicNode.BinaryOperation.POW))); return true; } }); @@ -109,7 +109,7 @@ r.register1(name, Double.TYPE, new InvocationPlugin() { @Override public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver receiver, ValueNode value) { - b.push(JavaKind.Double, b.recursiveAppend(UnaryMathIntrinsicNode.create(value, operation))); + b.push(JavaKind.Double, b.append(UnaryMathIntrinsicNode.create(value, operation))); return true; } }); diff -r d5572756efd6 -r ab5b504181d8 hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements.amd64/src/org/graalvm/compiler/replacements/amd64/AMD64CountLeadingZerosNode.java --- a/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements.amd64/src/org/graalvm/compiler/replacements/amd64/AMD64CountLeadingZerosNode.java Tue Apr 18 20:10:55 2017 -0700 +++ b/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements.amd64/src/org/graalvm/compiler/replacements/amd64/AMD64CountLeadingZerosNode.java Wed Apr 19 04:10:56 2017 +0000 @@ -22,7 +22,7 @@ */ package org.graalvm.compiler.replacements.amd64; -import static org.graalvm.compiler.nodeinfo.NodeCycles.CYCLES_3; +import static org.graalvm.compiler.nodeinfo.NodeCycles.CYCLES_2; import static org.graalvm.compiler.nodeinfo.NodeSize.SIZE_1; import org.graalvm.compiler.core.common.type.IntegerStamp; @@ -45,7 +45,7 @@ /** * Count the number of leading zeros using the {@code lzcntq} or {@code lzcntl} instructions. */ -@NodeInfo(cycles = CYCLES_3, size = SIZE_1) +@NodeInfo(cycles = CYCLES_2, size = SIZE_1) public final class AMD64CountLeadingZerosNode extends UnaryNode implements ArithmeticLIRLowerable { public static final NodeClass TYPE = NodeClass.create(AMD64CountLeadingZerosNode.class); diff -r d5572756efd6 -r ab5b504181d8 hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements.amd64/src/org/graalvm/compiler/replacements/amd64/AMD64CountTrailingZerosNode.java --- a/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements.amd64/src/org/graalvm/compiler/replacements/amd64/AMD64CountTrailingZerosNode.java Tue Apr 18 20:10:55 2017 -0700 +++ b/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements.amd64/src/org/graalvm/compiler/replacements/amd64/AMD64CountTrailingZerosNode.java Wed Apr 19 04:10:56 2017 +0000 @@ -22,7 +22,7 @@ */ package org.graalvm.compiler.replacements.amd64; -import static org.graalvm.compiler.nodeinfo.NodeCycles.CYCLES_3; +import static org.graalvm.compiler.nodeinfo.NodeCycles.CYCLES_2; import static org.graalvm.compiler.nodeinfo.NodeSize.SIZE_1; import org.graalvm.compiler.core.common.type.IntegerStamp; @@ -45,7 +45,7 @@ /** * Count the number of trailing zeros using the {@code tzcntq} or {@code tzcntl} instructions. */ -@NodeInfo(cycles = CYCLES_3, size = SIZE_1) +@NodeInfo(cycles = CYCLES_2, size = SIZE_1) public final class AMD64CountTrailingZerosNode extends UnaryNode implements ArithmeticLIRLowerable { public static final NodeClass TYPE = NodeClass.create(AMD64CountTrailingZerosNode.class); diff -r d5572756efd6 -r ab5b504181d8 hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements.amd64/src/org/graalvm/compiler/replacements/amd64/AMD64FloatConvertNode.java --- a/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements.amd64/src/org/graalvm/compiler/replacements/amd64/AMD64FloatConvertNode.java Tue Apr 18 20:10:55 2017 -0700 +++ b/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements.amd64/src/org/graalvm/compiler/replacements/amd64/AMD64FloatConvertNode.java Wed Apr 19 04:10:56 2017 +0000 @@ -22,7 +22,7 @@ */ package org.graalvm.compiler.replacements.amd64; -import static org.graalvm.compiler.nodeinfo.NodeCycles.CYCLES_5; +import static org.graalvm.compiler.nodeinfo.NodeCycles.CYCLES_8; import static org.graalvm.compiler.nodeinfo.NodeSize.SIZE_1; import org.graalvm.compiler.core.common.calc.FloatConvert; @@ -42,7 +42,7 @@ * of the {@link FloatConvertNode} which, on AMD64 needs a {@link AMD64FloatConvertNode} plus some * fixup code that handles the corner cases that differ between AMD64 and Java. */ -@NodeInfo(cycles = CYCLES_5, size = SIZE_1) +@NodeInfo(cycles = CYCLES_8, size = SIZE_1) public final class AMD64FloatConvertNode extends UnaryArithmeticNode implements ArithmeticLIRLowerable { public static final NodeClass TYPE = NodeClass.create(AMD64FloatConvertNode.class); diff -r d5572756efd6 -r ab5b504181d8 hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements.amd64/src/org/graalvm/compiler/replacements/amd64/AMD64GraphBuilderPlugins.java --- a/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements.amd64/src/org/graalvm/compiler/replacements/amd64/AMD64GraphBuilderPlugins.java Tue Apr 18 20:10:55 2017 -0700 +++ b/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements.amd64/src/org/graalvm/compiler/replacements/amd64/AMD64GraphBuilderPlugins.java Wed Apr 19 04:10:56 2017 +0000 @@ -118,7 +118,7 @@ r.register1("bitCount", type, new InvocationPlugin() { @Override public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver receiver, ValueNode value) { - b.push(JavaKind.Int, b.recursiveAppend(new BitCountNode(value).canonical(null))); + b.push(JavaKind.Int, b.append(new BitCountNode(value).canonical(null))); return true; } }); @@ -152,7 +152,7 @@ r.register1(name, Double.TYPE, new InvocationPlugin() { @Override public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver receiver, ValueNode value) { - b.push(JavaKind.Double, b.recursiveAppend(UnaryMathIntrinsicNode.create(value, operation))); + b.push(JavaKind.Double, b.append(UnaryMathIntrinsicNode.create(value, operation))); return true; } }); @@ -162,7 +162,7 @@ r.register2(name, Double.TYPE, Double.TYPE, new InvocationPlugin() { @Override public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver receiver, ValueNode x, ValueNode y) { - b.push(JavaKind.Double, b.recursiveAppend(BinaryMathIntrinsicNode.create(x, y, operation))); + b.push(JavaKind.Double, b.append(BinaryMathIntrinsicNode.create(x, y, operation))); return true; } }); diff -r d5572756efd6 -r ab5b504181d8 hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements.amd64/src/org/graalvm/compiler/replacements/amd64/AMD64StringIndexOfNode.java --- a/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements.amd64/src/org/graalvm/compiler/replacements/amd64/AMD64StringIndexOfNode.java Tue Apr 18 20:10:55 2017 -0700 +++ b/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements.amd64/src/org/graalvm/compiler/replacements/amd64/AMD64StringIndexOfNode.java Wed Apr 19 04:10:56 2017 +0000 @@ -22,14 +22,15 @@ */ package org.graalvm.compiler.replacements.amd64; +import static org.graalvm.compiler.nodeinfo.NodeCycles.CYCLES_256; +import static org.graalvm.compiler.nodeinfo.NodeSize.SIZE_64; + import org.graalvm.compiler.core.common.LocationIdentity; import org.graalvm.compiler.core.common.type.StampFactory; import org.graalvm.compiler.graph.NodeClass; import org.graalvm.compiler.graph.NodeInputList; import org.graalvm.compiler.nodeinfo.InputType; -import org.graalvm.compiler.nodeinfo.NodeCycles; import org.graalvm.compiler.nodeinfo.NodeInfo; -import org.graalvm.compiler.nodeinfo.NodeSize; import org.graalvm.compiler.nodes.FixedWithNextNode; import org.graalvm.compiler.nodes.NamedLocationIdentity; import org.graalvm.compiler.nodes.ValueNode; @@ -43,7 +44,7 @@ import jdk.vm.ci.meta.JavaKind; import jdk.vm.ci.meta.Value; -@NodeInfo(size = NodeSize.SIZE_50, cycles = NodeCycles.CYCLES_200) +@NodeInfo(size = SIZE_64, cycles = CYCLES_256) public class AMD64StringIndexOfNode extends FixedWithNextNode implements LIRLowerable, MemoryAccess { public static final NodeClass TYPE = NodeClass.create(AMD64StringIndexOfNode.class); diff -r d5572756efd6 -r ab5b504181d8 hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements.sparc/src/org/graalvm/compiler/replacements/sparc/SPARCGraphBuilderPlugins.java --- a/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements.sparc/src/org/graalvm/compiler/replacements/sparc/SPARCGraphBuilderPlugins.java Tue Apr 18 20:10:55 2017 -0700 +++ b/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements.sparc/src/org/graalvm/compiler/replacements/sparc/SPARCGraphBuilderPlugins.java Wed Apr 19 04:10:56 2017 +0000 @@ -70,7 +70,7 @@ r.register1("bitCount", type, new InvocationPlugin() { @Override public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver receiver, ValueNode value) { - b.push(JavaKind.Int, b.recursiveAppend(new BitCountNode(value).canonical(null))); + b.push(JavaKind.Int, b.append(new BitCountNode(value).canonical(null))); return true; } }); @@ -87,7 +87,7 @@ r.register2("pow", Double.TYPE, Double.TYPE, new InvocationPlugin() { @Override public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver receiver, ValueNode x, ValueNode y) { - b.push(JavaKind.Double, b.recursiveAppend(BinaryMathIntrinsicNode.create(x, y, BinaryMathIntrinsicNode.BinaryOperation.POW))); + b.push(JavaKind.Double, b.append(BinaryMathIntrinsicNode.create(x, y, BinaryMathIntrinsicNode.BinaryOperation.POW))); return true; } }); @@ -97,7 +97,7 @@ r.register1(name, Double.TYPE, new InvocationPlugin() { @Override public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver receiver, ValueNode value) { - b.push(JavaKind.Double, b.recursiveAppend(UnaryMathIntrinsicNode.create(value, operation))); + b.push(JavaKind.Double, b.append(UnaryMathIntrinsicNode.create(value, operation))); return true; } }); diff -r d5572756efd6 -r ab5b504181d8 hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements.test/src/org/graalvm/compiler/replacements/test/PEGraphDecoderTest.java --- a/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements.test/src/org/graalvm/compiler/replacements/test/PEGraphDecoderTest.java Tue Apr 18 20:10:55 2017 -0700 +++ b/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements.test/src/org/graalvm/compiler/replacements/test/PEGraphDecoderTest.java Wed Apr 19 04:10:56 2017 +0000 @@ -135,7 +135,7 @@ registerPlugins(graphBuilderConfig.getPlugins().getInvocationPlugins()); targetGraph = new StructuredGraph.Builder(getInitialOptions(), AllowAssumptions.YES).method(testMethod).build(); CachingPEGraphDecoder decoder = new CachingPEGraphDecoder(getTarget().arch, targetGraph, getProviders(), graphBuilderConfig, OptimisticOptimizations.NONE, AllowAssumptions.YES, - getInitialOptions(), null, null, new InlineInvokePlugin[]{new InlineAll()}, null); + getInitialOptions(), null, null, new InlineInvokePlugin[]{new InlineAll()}, null, null); decoder.decode(testMethod); Debug.dump(Debug.BASIC_LEVEL, targetGraph, "Target Graph"); diff -r d5572756efd6 -r ab5b504181d8 hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/CachingPEGraphDecoder.java --- a/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/CachingPEGraphDecoder.java Tue Apr 18 20:10:55 2017 -0700 +++ b/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/CachingPEGraphDecoder.java Wed Apr 19 04:10:56 2017 +0000 @@ -36,6 +36,7 @@ import org.graalvm.compiler.nodes.graphbuilderconf.IntrinsicContext; import org.graalvm.compiler.nodes.graphbuilderconf.InvocationPlugins; import org.graalvm.compiler.nodes.graphbuilderconf.LoopExplosionPlugin; +import org.graalvm.compiler.nodes.graphbuilderconf.NodePlugin; import org.graalvm.compiler.nodes.graphbuilderconf.ParameterPlugin; import org.graalvm.compiler.options.OptionValues; import org.graalvm.compiler.phases.OptimisticOptimizations; @@ -62,9 +63,9 @@ public CachingPEGraphDecoder(Architecture architecture, StructuredGraph graph, Providers providers, GraphBuilderConfiguration graphBuilderConfig, OptimisticOptimizations optimisticOpts, AllowAssumptions allowAssumptions, OptionValues options, LoopExplosionPlugin loopExplosionPlugin, InvocationPlugins invocationPlugins, InlineInvokePlugin[] inlineInvokePlugins, - ParameterPlugin parameterPlugin) { + ParameterPlugin parameterPlugin, NodePlugin[] nodePlugins) { super(architecture, graph, providers.getMetaAccess(), providers.getConstantReflection(), providers.getConstantFieldProvider(), providers.getStampProvider(), options, loopExplosionPlugin, - invocationPlugins, inlineInvokePlugins, parameterPlugin); + invocationPlugins, inlineInvokePlugins, parameterPlugin, nodePlugins); this.providers = providers; this.graphBuilderConfig = graphBuilderConfig; diff -r d5572756efd6 -r ab5b504181d8 hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/GraphKit.java --- a/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/GraphKit.java Tue Apr 18 20:10:55 2017 -0700 +++ b/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/GraphKit.java Wed Apr 19 04:10:56 2017 +0000 @@ -158,16 +158,7 @@ @Override public T append(T node) { - T result = graph.addOrUnique(changeToWord(node)); - if (result instanceof FixedNode) { - updateLastFixed((FixedNode) result); - } - return result; - } - - @Override - public T recursiveAppend(T node) { - T result = graph.addOrUniqueWithInputs(node); + T result = graph.addOrUniqueWithInputs(changeToWord(node)); if (result instanceof FixedNode) { updateLastFixed((FixedNode) result); } diff -r d5572756efd6 -r ab5b504181d8 hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/IntrinsicGraphBuilder.java --- a/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/IntrinsicGraphBuilder.java Tue Apr 18 20:10:55 2017 -0700 +++ b/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/IntrinsicGraphBuilder.java Wed Apr 19 04:10:56 2017 +0000 @@ -145,18 +145,6 @@ if (v.graph() != null) { return v; } - T added = graph.addOrUnique(v); - if (added == v) { - updateLastInstruction(v); - } - return added; - } - - @Override - public T recursiveAppend(T v) { - if (v.graph() != null) { - return v; - } T added = graph.addOrUniqueWithInputs(v); if (added == v) { updateLastInstruction(v); diff -r d5572756efd6 -r ab5b504181d8 hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/MethodHandlePlugin.java --- a/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/MethodHandlePlugin.java Tue Apr 18 20:10:55 2017 -0700 +++ b/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/MethodHandlePlugin.java Wed Apr 19 04:10:56 2017 +0000 @@ -73,7 +73,7 @@ CallTargetNode callTarget = invoke.callTarget(); NodeInputList argumentsList = callTarget.arguments(); for (int i = 0; i < argumentsList.size(); ++i) { - argumentsList.initialize(i, b.recursiveAppend(argumentsList.get(i))); + argumentsList.initialize(i, b.append(argumentsList.get(i))); } boolean inlineEverything = false; diff -r d5572756efd6 -r ab5b504181d8 hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/PEGraphDecoder.java --- a/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/PEGraphDecoder.java Tue Apr 18 20:10:55 2017 -0700 +++ b/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/PEGraphDecoder.java Wed Apr 19 04:10:56 2017 +0000 @@ -37,6 +37,7 @@ import org.graalvm.compiler.core.common.PermanentBailoutException; import org.graalvm.compiler.core.common.cfg.CFGVerifier; import org.graalvm.compiler.core.common.spi.ConstantFieldProvider; +import org.graalvm.compiler.core.common.type.Stamp; import org.graalvm.compiler.core.common.type.StampFactory; import org.graalvm.compiler.core.common.type.StampPair; import org.graalvm.compiler.debug.Debug; @@ -81,9 +82,17 @@ import org.graalvm.compiler.nodes.graphbuilderconf.InvocationPlugins.InvocationPluginReceiver; import org.graalvm.compiler.nodes.graphbuilderconf.LoopExplosionPlugin; import org.graalvm.compiler.nodes.graphbuilderconf.LoopExplosionPlugin.LoopExplosionKind; +import org.graalvm.compiler.nodes.graphbuilderconf.NodePlugin; import org.graalvm.compiler.nodes.graphbuilderconf.ParameterPlugin; +import org.graalvm.compiler.nodes.java.LoadFieldNode; +import org.graalvm.compiler.nodes.java.LoadIndexedNode; import org.graalvm.compiler.nodes.java.MethodCallTargetNode; import org.graalvm.compiler.nodes.java.MonitorIdNode; +import org.graalvm.compiler.nodes.java.NewArrayNode; +import org.graalvm.compiler.nodes.java.NewInstanceNode; +import org.graalvm.compiler.nodes.java.NewMultiArrayNode; +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.util.GraphUtil; import org.graalvm.compiler.options.Option; @@ -91,6 +100,8 @@ import org.graalvm.compiler.options.OptionType; import org.graalvm.compiler.options.OptionValues; import org.graalvm.compiler.phases.common.inlining.InliningUtil; +import org.graalvm.util.EconomicMap; +import org.graalvm.util.Equivalence; import jdk.vm.ci.code.Architecture; import jdk.vm.ci.code.BailoutException; @@ -102,7 +113,9 @@ import jdk.vm.ci.meta.JavaKind; import jdk.vm.ci.meta.JavaType; import jdk.vm.ci.meta.MetaAccessProvider; +import jdk.vm.ci.meta.ResolvedJavaField; import jdk.vm.ci.meta.ResolvedJavaMethod; +import jdk.vm.ci.meta.ResolvedJavaType; /** * A graph decoder that performs partial evaluation, i.e., that performs method inlining and @@ -118,6 +131,8 @@ */ public abstract class PEGraphDecoder extends SimplifyingGraphDecoder { + private static final Object CACHED_NULL_VALUE = new Object(); + public static class Options { @Option(help = "Maximum inlining depth during partial evaluation before reporting an infinite recursion")// public static final OptionKey InliningDepthError = new OptionKey<>(1000); @@ -229,11 +244,6 @@ } @Override - public T recursiveAppend(T value) { - throw unimplemented(); - } - - @Override public void push(JavaKind kind, ValueNode value) { throw unimplemented(); } @@ -295,7 +305,7 @@ protected boolean invokeConsumed; public PEAppendGraphBuilderContext(PEMethodScope inlineScope, FixedWithNextNode lastInstr) { - super(inlineScope, inlineScope.invokeData.invoke); + super(inlineScope, inlineScope.invokeData != null ? inlineScope.invokeData.invoke : null); this.lastInstr = lastInstr; } @@ -322,7 +332,7 @@ return v; } try (DebugCloseable position = withNodeSoucePosition()) { - T added = getGraph().addOrUnique(v); + T added = getGraph().addOrUniqueWithInputs(v); if (added == v) { updateLastInstruction(v); } @@ -337,21 +347,6 @@ return null; } - @SuppressWarnings("try") - @Override - public T recursiveAppend(T v) { - if (v.graph() != null) { - return v; - } - try (DebugCloseable position = withNodeSoucePosition()) { - T added = getGraph().addOrUniqueWithInputs(v); - if (added == v) { - updateLastInstruction(v); - } - return added; - } - } - private void updateLastInstruction(T v) { if (v instanceof FixedNode) { FixedNode fixedNode = (FixedNode) v; @@ -380,6 +375,56 @@ } } + /** + * 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 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 TYPE = NodeClass.create(ExceptionPlaceholderNode.class); @@ -389,21 +434,55 @@ } } + protected static class SpecialCallTargetCacheKey { + private final InvokeKind invokeKind; + private final ResolvedJavaMethod targetMethod; + private final ResolvedJavaType contextType; + private final Stamp receiverStamp; + + public SpecialCallTargetCacheKey(InvokeKind invokeKind, ResolvedJavaMethod targetMethod, ResolvedJavaType contextType, Stamp receiverStamp) { + this.invokeKind = invokeKind; + this.targetMethod = targetMethod; + this.contextType = contextType; + this.receiverStamp = receiverStamp; + } + + @Override + public int hashCode() { + return invokeKind.hashCode() ^ targetMethod.hashCode() ^ contextType.hashCode() ^ receiverStamp.hashCode(); + } + + @Override + public boolean equals(Object obj) { + if (obj instanceof SpecialCallTargetCacheKey) { + SpecialCallTargetCacheKey key = (SpecialCallTargetCacheKey) obj; + return key.invokeKind.equals(this.invokeKind) && key.targetMethod.equals(this.targetMethod) && key.contextType.equals(this.contextType) && key.receiverStamp.equals(this.receiverStamp); + } + return false; + } + } + protected final OptionValues options; private final LoopExplosionPlugin loopExplosionPlugin; private final InvocationPlugins invocationPlugins; private final InlineInvokePlugin[] inlineInvokePlugins; private final ParameterPlugin parameterPlugin; + private final NodePlugin[] nodePlugins; + private final EconomicMap specialCallTargetCache; + private final EconomicMap invocationPluginCache; public PEGraphDecoder(Architecture architecture, StructuredGraph graph, MetaAccessProvider metaAccess, ConstantReflectionProvider constantReflection, ConstantFieldProvider constantFieldProvider, StampProvider stampProvider, OptionValues options, LoopExplosionPlugin loopExplosionPlugin, InvocationPlugins invocationPlugins, InlineInvokePlugin[] inlineInvokePlugins, - ParameterPlugin parameterPlugin) { + ParameterPlugin parameterPlugin, NodePlugin[] nodePlugins) { super(architecture, graph, metaAccess, constantReflection, constantFieldProvider, stampProvider, true); this.loopExplosionPlugin = loopExplosionPlugin; this.invocationPlugins = invocationPlugins; this.inlineInvokePlugins = inlineInvokePlugins; this.parameterPlugin = parameterPlugin; this.options = options; + this.nodePlugins = nodePlugins; + this.specialCallTargetCache = EconomicMap.create(Equivalence.DEFAULT); + this.invocationPluginCache = EconomicMap.create(Equivalence.DEFAULT); } protected static LoopExplosionKind loopExplosionKind(ResolvedJavaMethod method, LoopExplosionPlugin loopExplosionPlugin) { @@ -496,7 +575,7 @@ protected LoopScope trySimplifyInvoke(PEMethodScope methodScope, LoopScope loopScope, InvokeData invokeData, MethodCallTargetNode callTarget) { // attempt to devirtualize the call - ResolvedJavaMethod specialCallTarget = MethodCallTargetNode.findSpecialCallTarget(callTarget.invokeKind(), callTarget.receiver(), callTarget.targetMethod(), invokeData.contextType); + ResolvedJavaMethod specialCallTarget = getSpecialCallTarget(invokeData, callTarget); if (specialCallTarget != null) { callTarget.setTargetMethod(specialCallTarget); callTarget.setInvokeKind(InvokeKind.Special); @@ -522,15 +601,39 @@ return null; } + private ResolvedJavaMethod getSpecialCallTarget(InvokeData invokeData, MethodCallTargetNode callTarget) { + if (callTarget.invokeKind().isDirect()) { + return null; + } + + // check for trivial cases (e.g. final methods, nonvirtual methods) + if (callTarget.targetMethod().canBeStaticallyBound()) { + return callTarget.targetMethod(); + } + + SpecialCallTargetCacheKey key = new SpecialCallTargetCacheKey(callTarget.invokeKind(), callTarget.targetMethod(), invokeData.contextType, callTarget.receiver().stamp()); + Object specialCallTarget = specialCallTargetCache.get(key); + if (specialCallTarget == null) { + specialCallTarget = MethodCallTargetNode.devirtualizeCall(key.invokeKind, key.targetMethod, key.contextType, graph.getAssumptions(), + key.receiverStamp); + if (specialCallTarget == null) { + specialCallTarget = CACHED_NULL_VALUE; + } + specialCallTargetCache.put(key, specialCallTarget); + } + + return specialCallTarget == CACHED_NULL_VALUE ? null : (ResolvedJavaMethod) specialCallTarget; + } + protected boolean tryInvocationPlugin(PEMethodScope methodScope, LoopScope loopScope, InvokeData invokeData, MethodCallTargetNode callTarget) { - if (invocationPlugins == null) { + if (invocationPlugins == null || invocationPlugins.size() == 0) { return false; } Invoke invoke = invokeData.invoke; ResolvedJavaMethod targetMethod = callTarget.targetMethod(); - InvocationPlugin invocationPlugin = invocationPlugins.lookupInvocation(targetMethod); + InvocationPlugin invocationPlugin = getInvocationPlugin(targetMethod); if (invocationPlugin == null) { return false; } @@ -570,6 +673,19 @@ } } + private InvocationPlugin getInvocationPlugin(ResolvedJavaMethod targetMethod) { + Object invocationPlugin = invocationPluginCache.get(targetMethod); + if (invocationPlugin == null) { + invocationPlugin = invocationPlugins.lookupInvocation(targetMethod); + if (invocationPlugin == null) { + invocationPlugin = CACHED_NULL_VALUE; + } + invocationPluginCache.put(targetMethod, invocationPlugin); + } + + return invocationPlugin == CACHED_NULL_VALUE ? null : (InvocationPlugin) invocationPlugin; + } + protected LoopScope tryInline(PEMethodScope methodScope, LoopScope loopScope, InvokeData invokeData, MethodCallTargetNode callTarget) { if (!callTarget.invokeKind().isDirect()) { return null; @@ -674,7 +790,7 @@ */ MergeNode unwindMergeNode = graph.add(new MergeNode()); exceptionValue = InliningUtil.mergeValueProducers(unwindMergeNode, getMatchingNodes(returnAndUnwindNodes, returnNodeCount > 0, UnwindNode.class, unwindNodeCount), - unwindNode -> unwindNode.exception()); + null, unwindNode -> unwindNode.exception()); unwindMergeNode.setNext(unwindReplacement); ensureExceptionStateDecoded(inlineScope); @@ -812,28 +928,140 @@ @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) { + if (node instanceof LoadFieldNode) { + PEOnDemandAppendGraphBuilderContext graphBuilderContext = new PEOnDemandAppendGraphBuilderContext(methodScope, node); + LoadFieldNode loadFieldNode = (LoadFieldNode) node; + ResolvedJavaField field = loadFieldNode.field(); + if (loadFieldNode.isStatic()) { + for (NodePlugin nodePlugin : nodePlugins) { + if (nodePlugin.handleLoadStaticField(graphBuilderContext, field)) { + replacedNode = graphBuilderContext.commit(loopScope, nodeOrderId, loadFieldNode); + break; + } + } + } else { + ValueNode object = loadFieldNode.object(); + for (NodePlugin nodePlugin : nodePlugins) { + if (nodePlugin.handleLoadField(graphBuilderContext, object, field)) { + replacedNode = graphBuilderContext.commit(loopScope, nodeOrderId, loadFieldNode); + break; + } + } + } + } else if (node instanceof StoreFieldNode) { + PEOnDemandAppendGraphBuilderContext graphBuilderContext = new PEOnDemandAppendGraphBuilderContext(methodScope, node); + StoreFieldNode storeFieldNode = (StoreFieldNode) node; + 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); + break; + } + } + } else { + ValueNode object = storeFieldNode.object(); + ValueNode value = storeFieldNode.value(); + for (NodePlugin nodePlugin : nodePlugins) { + if (nodePlugin.handleStoreField(graphBuilderContext, object, field, value)) { + replacedNode = graphBuilderContext.commit(loopScope, nodeOrderId, storeFieldNode); + break; + } + } + } + } else if (node instanceof LoadIndexedNode) { + PEOnDemandAppendGraphBuilderContext graphBuilderContext = new PEOnDemandAppendGraphBuilderContext(methodScope, node); + LoadIndexedNode loadIndexedNode = (LoadIndexedNode) node; + 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); + break; + } + } + } else if (node instanceof StoreIndexedNode) { + PEOnDemandAppendGraphBuilderContext graphBuilderContext = new PEOnDemandAppendGraphBuilderContext(methodScope, node); + StoreIndexedNode storeIndexedNode = (StoreIndexedNode) node; + 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); + break; + } + } + } else if (node instanceof NewInstanceNode) { + PEOnDemandAppendGraphBuilderContext graphBuilderContext = new PEOnDemandAppendGraphBuilderContext(methodScope, node); + NewInstanceNode newInstanceNode = (NewInstanceNode) node; + ResolvedJavaType type = newInstanceNode.instanceClass(); + for (NodePlugin nodePlugin : nodePlugins) { + if (nodePlugin.handleNewInstance(graphBuilderContext, type)) { + replacedNode = graphBuilderContext.commit(loopScope, nodeOrderId, newInstanceNode); + break; + } + } + } else if (node instanceof NewArrayNode) { + PEOnDemandAppendGraphBuilderContext graphBuilderContext = new PEOnDemandAppendGraphBuilderContext(methodScope, node); + NewArrayNode newArrayNode = (NewArrayNode) node; + ResolvedJavaType elementType = newArrayNode.elementType(); + ValueNode length = newArrayNode.length(); + for (NodePlugin nodePlugin : nodePlugins) { + if (nodePlugin.handleNewArray(graphBuilderContext, elementType, length)) { + replacedNode = graphBuilderContext.commit(loopScope, nodeOrderId, newArrayNode); + break; + } + } + } else if (node instanceof NewMultiArrayNode) { + PEOnDemandAppendGraphBuilderContext graphBuilderContext = new PEOnDemandAppendGraphBuilderContext(methodScope, node); + NewMultiArrayNode newArrayNode = (NewMultiArrayNode) node; + 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); + break; + } + } + } } - NodeSourcePosition pos = node.getNodeSourcePosition(); + NodeSourcePosition pos = replacedNode.getNodeSourcePosition(); if (pos != null && methodScope.isInlinedMethod()) { NodeSourcePosition newPosition = pos.addCaller(methodScope.getCallerBytecodePosition()); - try (DebugCloseable scope = node.graph().withNodeSourcePosition(newPosition)) { - super.handleFixedNode(s, loopScope, nodeOrderId, node); + try (DebugCloseable scope = replacedNode.graph().withNodeSourcePosition(newPosition)) { + super.handleFixedNode(s, loopScope, nodeOrderId, replacedNode); } - if (node.isAlive()) { - node.setNodeSourcePosition(newPosition); + if (replacedNode.isAlive()) { + replacedNode.setNodeSourcePosition(newPosition); } } else { - super.handleFixedNode(s, loopScope, nodeOrderId, node); + 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(); + } + } + @Override protected Node handleFloatingNodeBeforeAdd(MethodScope s, LoopScope loopScope, Node n) { PEMethodScope methodScope = (PEMethodScope) s; diff -r d5572756efd6 -r ab5b504181d8 hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/SnippetLowerableMemoryNode.java --- a/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/SnippetLowerableMemoryNode.java Tue Apr 18 20:10:55 2017 -0700 +++ b/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/SnippetLowerableMemoryNode.java Wed Apr 19 04:10:56 2017 +0000 @@ -22,6 +22,9 @@ */ package org.graalvm.compiler.replacements; +import static org.graalvm.compiler.nodeinfo.NodeCycles.CYCLES_IGNORED; +import static org.graalvm.compiler.nodeinfo.NodeSize.SIZE_IGNORED; + import org.graalvm.compiler.core.common.LocationIdentity; import org.graalvm.compiler.core.common.type.Stamp; import org.graalvm.compiler.graph.NodeClass; @@ -36,7 +39,7 @@ import org.graalvm.compiler.nodes.spi.Lowerable; import org.graalvm.compiler.nodes.spi.LoweringTool; -@NodeInfo +@NodeInfo(cycles = CYCLES_IGNORED, size = SIZE_IGNORED) public class SnippetLowerableMemoryNode extends FixedWithNextNode implements Lowerable, MemoryAccess { public static final NodeClass TYPE = NodeClass.create(SnippetLowerableMemoryNode.class); diff -r d5572756efd6 -r ab5b504181d8 hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/StandardGraphBuilderPlugins.java --- a/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/StandardGraphBuilderPlugins.java Tue Apr 18 20:10:55 2017 -0700 +++ b/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/StandardGraphBuilderPlugins.java Wed Apr 19 04:10:56 2017 +0000 @@ -284,21 +284,21 @@ r.register1("reverseBytes", type, new InvocationPlugin() { @Override public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver receiver, ValueNode value) { - b.push(kind, b.recursiveAppend(new ReverseBytesNode(value).canonical(null))); + b.push(kind, b.append(new ReverseBytesNode(value).canonical(null))); return true; } }); r.register2("divideUnsigned", type, type, new InvocationPlugin() { @Override public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver receiver, ValueNode dividend, ValueNode divisor) { - b.push(kind, b.recursiveAppend(new UnsignedDivNode(dividend, divisor).canonical(null))); + b.push(kind, b.append(new UnsignedDivNode(dividend, divisor).canonical(null))); return true; } }); r.register2("remainderUnsigned", type, type, new InvocationPlugin() { @Override public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver receiver, ValueNode dividend, ValueNode divisor) { - b.push(kind, b.recursiveAppend(new UnsignedRemNode(dividend, divisor).canonical(null))); + b.push(kind, b.append(new UnsignedRemNode(dividend, divisor).canonical(null))); return true; } }); @@ -313,7 +313,7 @@ ReverseBytesNode reverse = b.add(new ReverseBytesNode(value)); RightShiftNode rightShift = b.add(new RightShiftNode(reverse, b.add(ConstantNode.forInt(16)))); ZeroExtendNode charCast = b.add(new ZeroExtendNode(b.add(new NarrowNode(rightShift, 16)), 32)); - b.push(JavaKind.Char, b.recursiveAppend(charCast.canonical(null))); + b.push(JavaKind.Char, b.append(charCast.canonical(null))); return true; } }); @@ -328,7 +328,7 @@ ReverseBytesNode reverse = b.add(new ReverseBytesNode(value)); RightShiftNode rightShift = b.add(new RightShiftNode(reverse, b.add(ConstantNode.forInt(16)))); SignExtendNode charCast = b.add(new SignExtendNode(b.add(new NarrowNode(rightShift, 16)), 32)); - b.push(JavaKind.Short, b.recursiveAppend(charCast.canonical(null))); + b.push(JavaKind.Short, b.append(charCast.canonical(null))); return true; } }); @@ -339,14 +339,14 @@ r.register1("floatToRawIntBits", float.class, new InvocationPlugin() { @Override public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver receiver, ValueNode value) { - b.push(JavaKind.Int, b.recursiveAppend(new ReinterpretNode(JavaKind.Int, value).canonical(null))); + b.push(JavaKind.Int, b.append(new ReinterpretNode(JavaKind.Int, value).canonical(null))); return true; } }); r.register1("intBitsToFloat", int.class, new InvocationPlugin() { @Override public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver receiver, ValueNode value) { - b.push(JavaKind.Float, b.recursiveAppend(new ReinterpretNode(JavaKind.Float, value).canonical(null))); + b.push(JavaKind.Float, b.append(new ReinterpretNode(JavaKind.Float, value).canonical(null))); return true; } }); @@ -357,14 +357,14 @@ r.register1("doubleToRawLongBits", double.class, new InvocationPlugin() { @Override public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver receiver, ValueNode value) { - b.push(JavaKind.Long, b.recursiveAppend(new ReinterpretNode(JavaKind.Long, value).canonical(null))); + b.push(JavaKind.Long, b.append(new ReinterpretNode(JavaKind.Long, value).canonical(null))); return true; } }); r.register1("longBitsToDouble", long.class, new InvocationPlugin() { @Override public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver receiver, ValueNode value) { - b.push(JavaKind.Double, b.recursiveAppend(new ReinterpretNode(JavaKind.Double, value).canonical(null))); + b.push(JavaKind.Double, b.append(new ReinterpretNode(JavaKind.Double, value).canonical(null))); return true; } }); @@ -402,21 +402,21 @@ @Override public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver receiver, ValueNode value) { - b.push(JavaKind.Float, b.recursiveAppend(new AbsNode(value).canonical(null))); + b.push(JavaKind.Float, b.append(new AbsNode(value).canonical(null))); return true; } }); r.register1("abs", Double.TYPE, new InvocationPlugin() { @Override public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver receiver, ValueNode value) { - b.push(JavaKind.Double, b.recursiveAppend(new AbsNode(value).canonical(null))); + b.push(JavaKind.Double, b.append(new AbsNode(value).canonical(null))); return true; } }); r.register1("sqrt", Double.TYPE, new InvocationPlugin() { @Override public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver receiver, ValueNode value) { - b.push(JavaKind.Double, b.recursiveAppend(new SqrtNode(value).canonical(null))); + b.push(JavaKind.Double, b.append(new SqrtNode(value).canonical(null))); return true; } }); @@ -465,7 +465,7 @@ cond = cond.negate(); } - LogicNode compare = CompareNode.createCompareNode(graph, cond, lhs, rhs, b.getConstantReflection()); + LogicNode compare = CompareNode.createCompareNode(graph, b.getConstantReflection(), b.getMetaAccess(), b.getOptions(), null, cond, lhs, rhs); b.addPush(JavaKind.Boolean, new ConditionalNode(compare, trueValue, falseValue)); return true; } @@ -533,16 +533,16 @@ r.register2("isInstance", Receiver.class, Object.class, new InvocationPlugin() { @Override public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver type, ValueNode object) { - LogicNode condition = b.recursiveAppend(InstanceOfDynamicNode.create(b.getAssumptions(), b.getConstantReflection(), type.get(), object, false)); - b.push(JavaKind.Boolean, b.recursiveAppend(new ConditionalNode(condition).canonical(null))); + LogicNode condition = b.append(InstanceOfDynamicNode.create(b.getAssumptions(), b.getConstantReflection(), type.get(), object, false)); + b.push(JavaKind.Boolean, b.append(new ConditionalNode(condition).canonical(null))); return true; } }); r.register2("isAssignableFrom", Receiver.class, Class.class, new InvocationPlugin() { @Override public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver type, ValueNode otherType) { - ClassIsAssignableFromNode condition = b.recursiveAppend(new ClassIsAssignableFromNode(type.get(), otherType)); - b.push(JavaKind.Boolean, b.recursiveAppend(new ConditionalNode(condition).canonical(null))); + ClassIsAssignableFromNode condition = b.append(new ClassIsAssignableFromNode(type.get(), otherType)); + b.push(JavaKind.Boolean, b.append(new ConditionalNode(condition).canonical(null))); return true; } }); @@ -884,7 +884,8 @@ b.add(new DeoptimizeNode(DeoptimizationAction.InvalidateReprofile, DeoptimizationReason.TransferToInterpreter)); } else if (falseCount == 0 || trueCount == 0) { boolean expected = falseCount == 0; - LogicNode condition = b.addWithInputs(IntegerEqualsNode.create(result, b.add(ConstantNode.forBoolean(!expected)))); + LogicNode condition = b.addWithInputs( + IntegerEqualsNode.create(b.getConstantReflection(), b.getMetaAccess(), b.getOptions(), null, result, b.add(ConstantNode.forBoolean(!expected)))); b.append(new FixedGuardNode(condition, DeoptimizationReason.UnreachedCode, DeoptimizationAction.InvalidateReprofile, true)); newResult = b.add(ConstantNode.forBoolean(expected)); } else { diff -r d5572756efd6 -r ab5b504181d8 hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/StringIndexOfNode.java --- a/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/StringIndexOfNode.java Tue Apr 18 20:10:55 2017 -0700 +++ b/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/StringIndexOfNode.java Wed Apr 19 04:10:56 2017 +0000 @@ -22,11 +22,12 @@ */ package org.graalvm.compiler.replacements; +import static org.graalvm.compiler.nodeinfo.NodeCycles.CYCLES_256; +import static org.graalvm.compiler.nodeinfo.NodeSize.SIZE_64; + import org.graalvm.compiler.core.common.type.StampPair; import org.graalvm.compiler.graph.NodeClass; -import org.graalvm.compiler.nodeinfo.NodeCycles; import org.graalvm.compiler.nodeinfo.NodeInfo; -import org.graalvm.compiler.nodeinfo.NodeSize; import org.graalvm.compiler.nodes.CallTargetNode.InvokeKind; import org.graalvm.compiler.nodes.ValueNode; import org.graalvm.compiler.nodes.spi.LoweringTool; @@ -34,7 +35,7 @@ import jdk.vm.ci.meta.ResolvedJavaMethod; -@NodeInfo(size = NodeSize.SIZE_50, cycles = NodeCycles.CYCLES_200) +@NodeInfo(size = SIZE_64, cycles = CYCLES_256) public class StringIndexOfNode extends MacroStateSplitNode { public static final NodeClass TYPE = NodeClass.create(StringIndexOfNode.class); diff -r d5572756efd6 -r ab5b504181d8 hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/nodes/ArrayEqualsNode.java --- a/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/nodes/ArrayEqualsNode.java Tue Apr 18 20:10:55 2017 -0700 +++ b/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/nodes/ArrayEqualsNode.java Wed Apr 19 04:10:56 2017 +0000 @@ -23,8 +23,8 @@ package org.graalvm.compiler.replacements.nodes; import static org.graalvm.compiler.nodeinfo.InputType.Memory; -import static org.graalvm.compiler.nodeinfo.NodeCycles.CYCLES_100; -import static org.graalvm.compiler.nodeinfo.NodeSize.SIZE_50; +import static org.graalvm.compiler.nodeinfo.NodeCycles.CYCLES_1024; +import static org.graalvm.compiler.nodeinfo.NodeSize.SIZE_1024; import org.graalvm.compiler.core.common.LocationIdentity; import org.graalvm.compiler.core.common.type.StampFactory; @@ -57,7 +57,7 @@ /** * Compares two arrays with the same length. */ -@NodeInfo(cycles = CYCLES_100, size = SIZE_50) +@NodeInfo(cycles = CYCLES_1024, size = SIZE_1024) public final class ArrayEqualsNode extends FixedWithNextNode implements LIRLowerable, Canonicalizable, Virtualizable, MemoryAccess { public static final NodeClass TYPE = NodeClass.create(ArrayEqualsNode.class); diff -r d5572756efd6 -r ab5b504181d8 hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/nodes/BasicArrayCopyNode.java --- a/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/nodes/BasicArrayCopyNode.java Tue Apr 18 20:10:55 2017 -0700 +++ b/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/nodes/BasicArrayCopyNode.java Wed Apr 19 04:10:56 2017 +0000 @@ -25,8 +25,8 @@ import static org.graalvm.compiler.core.common.LocationIdentity.any; import static org.graalvm.compiler.nodeinfo.InputType.Memory; import static org.graalvm.compiler.nodeinfo.InputType.State; -import static org.graalvm.compiler.nodeinfo.NodeCycles.CYCLES_200; -import static org.graalvm.compiler.nodeinfo.NodeSize.SIZE_100; +import static org.graalvm.compiler.nodeinfo.NodeCycles.CYCLES_256; +import static org.graalvm.compiler.nodeinfo.NodeSize.SIZE_64; import org.graalvm.compiler.core.common.LocationIdentity; import org.graalvm.compiler.core.common.type.StampFactory; @@ -55,7 +55,7 @@ import jdk.vm.ci.meta.JavaKind; import jdk.vm.ci.meta.ResolvedJavaType; -@NodeInfo(cycles = CYCLES_200, size = SIZE_100) +@NodeInfo(cycles = CYCLES_256, size = SIZE_64) public class BasicArrayCopyNode extends AbstractMemoryCheckpoint implements Virtualizable, MemoryCheckpoint.Single, MemoryAccess, Lowerable, DeoptimizingNode.DeoptDuring { public static final NodeClass TYPE = NodeClass.create(BasicArrayCopyNode.class); diff -r d5572756efd6 -r ab5b504181d8 hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/nodes/BasicObjectCloneNode.java --- a/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/nodes/BasicObjectCloneNode.java Tue Apr 18 20:10:55 2017 -0700 +++ b/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/nodes/BasicObjectCloneNode.java Wed Apr 19 04:10:56 2017 +0000 @@ -22,6 +22,9 @@ */ package org.graalvm.compiler.replacements.nodes; +import static org.graalvm.compiler.nodeinfo.NodeCycles.CYCLES_8; +import static org.graalvm.compiler.nodeinfo.NodeSize.SIZE_8; + import java.util.Collections; import org.graalvm.compiler.core.common.type.ObjectStamp; @@ -46,7 +49,7 @@ import jdk.vm.ci.meta.ResolvedJavaMethod; import jdk.vm.ci.meta.ResolvedJavaType; -@NodeInfo +@NodeInfo(cycles = CYCLES_8, size = SIZE_8) public abstract class BasicObjectCloneNode extends MacroStateSplitNode implements VirtualizableAllocation, ArrayLengthProvider { public static final NodeClass TYPE = NodeClass.create(BasicObjectCloneNode.class); diff -r d5572756efd6 -r ab5b504181d8 hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/nodes/BitCountNode.java --- a/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/nodes/BitCountNode.java Tue Apr 18 20:10:55 2017 -0700 +++ b/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/nodes/BitCountNode.java Wed Apr 19 04:10:56 2017 +0000 @@ -22,7 +22,7 @@ */ package org.graalvm.compiler.replacements.nodes; -import static org.graalvm.compiler.nodeinfo.NodeCycles.CYCLES_3; +import static org.graalvm.compiler.nodeinfo.NodeCycles.CYCLES_2; import static org.graalvm.compiler.nodeinfo.NodeSize.SIZE_1; import org.graalvm.compiler.core.common.type.IntegerStamp; @@ -42,7 +42,7 @@ import jdk.vm.ci.meta.JavaConstant; import jdk.vm.ci.meta.JavaKind; -@NodeInfo(cycles = CYCLES_3, size = SIZE_1) +@NodeInfo(cycles = CYCLES_2, size = SIZE_1) public final class BitCountNode extends UnaryNode implements ArithmeticLIRLowerable { public static final NodeClass TYPE = NodeClass.create(BitCountNode.class); diff -r d5572756efd6 -r ab5b504181d8 hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/nodes/BitScanForwardNode.java --- a/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/nodes/BitScanForwardNode.java Tue Apr 18 20:10:55 2017 -0700 +++ b/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/nodes/BitScanForwardNode.java Wed Apr 19 04:10:56 2017 +0000 @@ -22,7 +22,7 @@ */ package org.graalvm.compiler.replacements.nodes; -import static org.graalvm.compiler.nodeinfo.NodeCycles.CYCLES_3; +import static org.graalvm.compiler.nodeinfo.NodeCycles.CYCLES_2; import static org.graalvm.compiler.nodeinfo.NodeSize.SIZE_1; import org.graalvm.compiler.core.common.type.IntegerStamp; @@ -47,7 +47,7 @@ * Determines the index of the least significant "1" bit. Note that the result is undefined if the * input is zero. */ -@NodeInfo(cycles = CYCLES_3, size = SIZE_1) +@NodeInfo(cycles = CYCLES_2, size = SIZE_1) public final class BitScanForwardNode extends UnaryNode implements ArithmeticLIRLowerable { public static final NodeClass TYPE = NodeClass.create(BitScanForwardNode.class); diff -r d5572756efd6 -r ab5b504181d8 hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/nodes/BitScanReverseNode.java --- a/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/nodes/BitScanReverseNode.java Tue Apr 18 20:10:55 2017 -0700 +++ b/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/nodes/BitScanReverseNode.java Wed Apr 19 04:10:56 2017 +0000 @@ -22,7 +22,7 @@ */ package org.graalvm.compiler.replacements.nodes; -import static org.graalvm.compiler.nodeinfo.NodeCycles.CYCLES_3; +import static org.graalvm.compiler.nodeinfo.NodeCycles.CYCLES_2; import static org.graalvm.compiler.nodeinfo.NodeSize.SIZE_1; import org.graalvm.compiler.core.common.type.IntegerStamp; @@ -47,7 +47,7 @@ * Determines the index of the most significant "1" bit. Note that the result is undefined if the * input is zero. */ -@NodeInfo(cycles = CYCLES_3, size = SIZE_1) +@NodeInfo(cycles = CYCLES_2, size = SIZE_1) public final class BitScanReverseNode extends UnaryNode implements ArithmeticLIRLowerable { public static final NodeClass TYPE = NodeClass.create(BitScanReverseNode.class); diff -r d5572756efd6 -r ab5b504181d8 hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/nodes/DirectStoreNode.java --- a/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/nodes/DirectStoreNode.java Tue Apr 18 20:10:55 2017 -0700 +++ b/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/nodes/DirectStoreNode.java Wed Apr 19 04:10:56 2017 +0000 @@ -22,7 +22,7 @@ */ package org.graalvm.compiler.replacements.nodes; -import static org.graalvm.compiler.nodeinfo.NodeCycles.CYCLES_3; +import static org.graalvm.compiler.nodeinfo.NodeCycles.CYCLES_2; import static org.graalvm.compiler.nodeinfo.NodeSize.SIZE_1; import org.graalvm.compiler.core.common.LIRKind; @@ -43,7 +43,7 @@ * A special purpose store node that differs from {@link RawStoreNode} in that it is not a * {@link StateSplit} and takes a computed address instead of an object. */ -@NodeInfo(cycles = CYCLES_3, size = SIZE_1) +@NodeInfo(cycles = CYCLES_2, size = SIZE_1) public final class DirectStoreNode extends FixedWithNextNode implements LIRLowerable { public static final NodeClass TYPE = NodeClass.create(DirectStoreNode.class); diff -r d5572756efd6 -r ab5b504181d8 hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/nodes/MacroNode.java --- a/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/nodes/MacroNode.java Tue Apr 18 20:10:55 2017 -0700 +++ b/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/nodes/MacroNode.java Wed Apr 19 04:10:56 2017 +0000 @@ -138,7 +138,7 @@ @SuppressWarnings("try") protected StructuredGraph lowerReplacement(final StructuredGraph replacementGraph, LoweringTool tool) { final PhaseContext c = new PhaseContext(tool.getMetaAccess(), tool.getConstantReflection(), tool.getConstantFieldProvider(), tool.getLowerer(), tool.getReplacements(), - tool.getStampProvider(), tool.getNodeCostProvider()); + tool.getStampProvider()); if (!graph().hasValueProxies()) { new RemoveValueProxyPhase().apply(replacementGraph); } diff -r d5572756efd6 -r ab5b504181d8 hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/nodes/ReadRegisterNode.java --- a/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/nodes/ReadRegisterNode.java Tue Apr 18 20:10:55 2017 -0700 +++ b/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/nodes/ReadRegisterNode.java Wed Apr 19 04:10:56 2017 +0000 @@ -22,8 +22,8 @@ */ package org.graalvm.compiler.replacements.nodes; -import static org.graalvm.compiler.nodeinfo.NodeCycles.CYCLES_1; -import static org.graalvm.compiler.nodeinfo.NodeSize.SIZE_1; +import static org.graalvm.compiler.nodeinfo.NodeCycles.CYCLES_0; +import static org.graalvm.compiler.nodeinfo.NodeSize.SIZE_0; import org.graalvm.compiler.core.common.LIRKind; import org.graalvm.compiler.core.common.type.Stamp; @@ -42,7 +42,7 @@ /** * Access the value of a specific register. */ -@NodeInfo(nameTemplate = "ReadRegister %{p#register}", cycles = CYCLES_1, size = SIZE_1) +@NodeInfo(nameTemplate = "ReadRegister %{p#register}", cycles = CYCLES_0, size = SIZE_0) public final class ReadRegisterNode extends FixedWithNextNode implements LIRLowerable { public static final NodeClass TYPE = NodeClass.create(ReadRegisterNode.class); diff -r d5572756efd6 -r ab5b504181d8 hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/nodes/UnaryMathIntrinsicNode.java --- a/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/nodes/UnaryMathIntrinsicNode.java Tue Apr 18 20:10:55 2017 -0700 +++ b/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/nodes/UnaryMathIntrinsicNode.java Wed Apr 19 04:10:56 2017 +0000 @@ -22,7 +22,7 @@ */ package org.graalvm.compiler.replacements.nodes; -import static org.graalvm.compiler.nodeinfo.NodeCycles.CYCLES_UNKNOWN; +import static org.graalvm.compiler.nodeinfo.NodeCycles.CYCLES_64; import static org.graalvm.compiler.nodeinfo.NodeSize.SIZE_1; import org.graalvm.compiler.core.common.spi.ForeignCallDescriptor; @@ -46,7 +46,7 @@ import jdk.vm.ci.meta.JavaKind; import jdk.vm.ci.meta.Value; -@NodeInfo(nameTemplate = "MathIntrinsic#{p#operation/s}", cycles = CYCLES_UNKNOWN, size = SIZE_1) +@NodeInfo(nameTemplate = "MathIntrinsic#{p#operation/s}", cycles = CYCLES_64, size = SIZE_1) public final class UnaryMathIntrinsicNode extends UnaryNode implements ArithmeticLIRLowerable, Lowerable { public static final NodeClass TYPE = NodeClass.create(UnaryMathIntrinsicNode.class); @@ -197,4 +197,5 @@ @NodeIntrinsic public static native double compute(double value, @ConstantNodeParameter UnaryOperation op); + } diff -r d5572756efd6 -r ab5b504181d8 hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/nodes/WriteRegisterNode.java --- a/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/nodes/WriteRegisterNode.java Tue Apr 18 20:10:55 2017 -0700 +++ b/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/nodes/WriteRegisterNode.java Wed Apr 19 04:10:56 2017 +0000 @@ -22,6 +22,9 @@ */ package org.graalvm.compiler.replacements.nodes; +import static org.graalvm.compiler.nodeinfo.NodeCycles.CYCLES_2; +import static org.graalvm.compiler.nodeinfo.NodeSize.SIZE_1; + import org.graalvm.compiler.core.common.type.StampFactory; import org.graalvm.compiler.graph.NodeClass; import org.graalvm.compiler.nodeinfo.NodeInfo; @@ -37,7 +40,7 @@ /** * Changes the value of a specific register. */ -@NodeInfo(nameTemplate = "WriteRegister %{p#register}") +@NodeInfo(nameTemplate = "WriteRegister %{p#register}", cycles = CYCLES_2, size = SIZE_1) public final class WriteRegisterNode extends FixedWithNextNode implements LIRLowerable { public static final NodeClass TYPE = NodeClass.create(WriteRegisterNode.class); diff -r d5572756efd6 -r ab5b504181d8 hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/nodes/arithmetic/IntegerMulExactSplitNode.java --- a/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/nodes/arithmetic/IntegerMulExactSplitNode.java Tue Apr 18 20:10:55 2017 -0700 +++ b/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/nodes/arithmetic/IntegerMulExactSplitNode.java Wed Apr 19 04:10:56 2017 +0000 @@ -22,6 +22,8 @@ */ package org.graalvm.compiler.replacements.nodes.arithmetic; +import static org.graalvm.compiler.nodeinfo.NodeCycles.CYCLES_4; + import org.graalvm.compiler.core.common.type.IntegerStamp; import org.graalvm.compiler.core.common.type.Stamp; import org.graalvm.compiler.graph.NodeClass; @@ -34,7 +36,7 @@ import jdk.vm.ci.meta.Value; -@NodeInfo +@NodeInfo(cycles = CYCLES_4, cyclesRationale = "mul + cmp") public final class IntegerMulExactSplitNode extends IntegerExactArithmeticSplitNode { public static final NodeClass TYPE = NodeClass.create(IntegerMulExactSplitNode.class); diff -r d5572756efd6 -r ab5b504181d8 hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/nodes/arithmetic/UnsignedMulHighNode.java --- a/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/nodes/arithmetic/UnsignedMulHighNode.java Tue Apr 18 20:10:55 2017 -0700 +++ b/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/nodes/arithmetic/UnsignedMulHighNode.java Wed Apr 19 04:10:56 2017 +0000 @@ -22,8 +22,8 @@ */ package org.graalvm.compiler.replacements.nodes.arithmetic; -import static org.graalvm.compiler.nodeinfo.NodeCycles.CYCLES_4; -import static org.graalvm.compiler.nodeinfo.NodeSize.SIZE_4; +import static org.graalvm.compiler.nodeinfo.NodeCycles.CYCLES_2; +import static org.graalvm.compiler.nodeinfo.NodeSize.SIZE_2; import java.util.function.BiFunction; @@ -43,7 +43,7 @@ import jdk.vm.ci.meta.JavaKind; import jdk.vm.ci.meta.Value; -@NodeInfo(shortName = "|*H|", cycles = CYCLES_4, cyclesRationale = "mul + mov", size = SIZE_4) +@NodeInfo(shortName = "|*H|", cycles = CYCLES_2, size = SIZE_2) public final class UnsignedMulHighNode extends BinaryNode implements ArithmeticLIRLowerable { public static final NodeClass TYPE = NodeClass.create(UnsignedMulHighNode.class); diff -r d5572756efd6 -r ab5b504181d8 hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.virtual/src/org/graalvm/compiler/virtual/phases/ea/VirtualizerToolImpl.java --- a/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.virtual/src/org/graalvm/compiler/virtual/phases/ea/VirtualizerToolImpl.java Tue Apr 18 20:10:55 2017 -0700 +++ b/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.virtual/src/org/graalvm/compiler/virtual/phases/ea/VirtualizerToolImpl.java Wed Apr 19 04:10:56 2017 +0000 @@ -258,11 +258,11 @@ } @Override - public boolean supportSubwordCompare(int bits) { + public Integer smallestCompareWidth() { if (loweringProvider != null) { - return loweringProvider.supportSubwordCompare(bits); + return loweringProvider.smallestCompareWidth(); } else { - return false; + return null; } } }