mirror of
https://github.com/openjdk/jdk.git
synced 2026-02-12 11:28:35 +00:00
Merge
This commit is contained in:
commit
f7c823802a
@ -199,6 +199,7 @@ suite = {
|
||||
"dependencies" : [
|
||||
"org.graalvm.compiler.api.runtime",
|
||||
"org.graalvm.compiler.replacements",
|
||||
"org.graalvm.compiler.printer",
|
||||
"org.graalvm.compiler.runtime",
|
||||
],
|
||||
"imports" : [
|
||||
@ -929,6 +930,7 @@ suite = {
|
||||
"subDir" : "share/classes",
|
||||
"sourceDirs" : ["src"],
|
||||
"dependencies" : [
|
||||
"org.graalvm.util",
|
||||
"mx:JUNIT",
|
||||
],
|
||||
"checkstyle" : "org.graalvm.compiler.graph",
|
||||
|
||||
@ -286,7 +286,7 @@ public final class AArch64Address extends AbstractAddress {
|
||||
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.
|
||||
|
||||
@ -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<Object[]> data() {
|
||||
ArrayList<Object[]> 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);
|
||||
}
|
||||
}
|
||||
@ -57,6 +57,7 @@ import org.graalvm.compiler.debug.DebugConfigScope;
|
||||
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.OptimisticOptimizations;
|
||||
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 @@ public class CheckGraalInvariants extends GraalCompilerTest {
|
||||
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;
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@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 @@ public class CheckGraalInvariants extends GraalCompilerTest {
|
||||
|
||||
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<String> 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<? extends ZipEntry> entry = zipFile.entries(); entry.hasMoreElements();) {
|
||||
@ -200,7 +232,7 @@ public class CheckGraalInvariants extends GraalCompilerTest {
|
||||
// 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<Class<?>> classes = initializeClasses(classNames);
|
||||
List<Class<?>> classes = initializeClasses(tool, classNames);
|
||||
for (Class<?> c : classes) {
|
||||
String className = c.getName();
|
||||
executor.execute(() -> {
|
||||
@ -234,7 +266,11 @@ public class CheckGraalInvariants extends GraalCompilerTest {
|
||||
// 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 @@ public class CheckGraalInvariants extends GraalCompilerTest {
|
||||
}
|
||||
}
|
||||
|
||||
private static List<Class<?>> initializeClasses(List<String> classNames) {
|
||||
private static List<Class<?>> initializeClasses(InvariantsTool tool, List<String> classNames) {
|
||||
List<Class<?>> 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 @@ public class CheckGraalInvariants extends GraalCompilerTest {
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -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.java.ComputeLoopFrequenciesClosure;
|
||||
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 class NodePropertiesTest extends GraalCompilerTest {
|
||||
}
|
||||
|
||||
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 @@ public class NodePropertiesTest extends GraalCompilerTest {
|
||||
@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 @@ public class NodePropertiesTest extends GraalCompilerTest {
|
||||
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 @@ public class NodePropertiesTest extends GraalCompilerTest {
|
||||
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 @@ public class NodePropertiesTest extends GraalCompilerTest {
|
||||
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 @@ public class NodePropertiesTest extends GraalCompilerTest {
|
||||
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 @@ public class NodePropertiesTest extends GraalCompilerTest {
|
||||
Canonicalizable.Binary<ValueNode> bc = (Canonicalizable.Binary<ValueNode>) 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 @@ public class NodePropertiesTest extends GraalCompilerTest {
|
||||
|
||||
@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);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -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<String, String> extractEntries(Properties properties, String prefix, boolean stripPrefix) {
|
||||
EconomicMap<String, String> matches = EconomicMap.create();
|
||||
for (Map.Entry<Object, Object> 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<String, OptionDescriptor> 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<String, String> fieldsAndHelp) {
|
||||
MapCursor<String, String> 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<OptionDescriptor> iterator() {
|
||||
return descriptors.getValues().iterator();
|
||||
}
|
||||
|
||||
@Override
|
||||
public OptionDescriptor get(String value) {
|
||||
return descriptors.get(value);
|
||||
}
|
||||
}
|
||||
@ -205,7 +205,7 @@ public class VerifyDebugUsageTest {
|
||||
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());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -298,18 +298,10 @@ public class GraalCompiler {
|
||||
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 @@ public class GraalCompiler {
|
||||
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 @@ public class GraalCompiler {
|
||||
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;
|
||||
}
|
||||
|
||||
@ -127,6 +127,9 @@ public class Debug {
|
||||
*
|
||||
* 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 @@ public class Debug {
|
||||
* 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 @@ public class Debug {
|
||||
* 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 @@ public class Debug {
|
||||
* 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 @@ public class Debug {
|
||||
* 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;
|
||||
|
||||
|
||||
@ -117,6 +117,7 @@ public class GraalDebugConfig implements DebugConfig {
|
||||
public static final OptionKey<Integer> PrintBinaryGraphPort = new OptionKey<>(4445);
|
||||
@Option(help = "Schedule graphs as they are dumped.", type = OptionType.Debug)
|
||||
public static final OptionKey<Boolean> PrintGraphWithSchedule = new OptionKey<>(false);
|
||||
|
||||
@Option(help = "Enable dumping Truffle ASTs to the IdealGraphVisualizer.", type = OptionType.Debug)
|
||||
public static final OptionKey<Boolean> PrintTruffleTrees = new OptionKey<>(true);
|
||||
|
||||
|
||||
@ -53,6 +53,21 @@ public class GraalError extends Error {
|
||||
throw new GraalError(cause);
|
||||
}
|
||||
|
||||
/**
|
||||
* 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
|
||||
*/
|
||||
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
|
||||
@ -62,8 +77,58 @@ public class GraalError extends Error {
|
||||
* @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 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 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);
|
||||
|
||||
@ -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 @@ public class Graph {
|
||||
}
|
||||
|
||||
// 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<PlaceHolderNode> TYPE = NodeClass.create(PlaceHolderNode.class);
|
||||
|
||||
@ -52,7 +52,9 @@ import org.graalvm.compiler.graph.iterators.NodePredicate;
|
||||
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 @@ public abstract class Node implements Cloneable, Formattable, NodeInterface {
|
||||
}
|
||||
|
||||
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 @@ public abstract class Node implements Cloneable, Formattable, NodeInterface {
|
||||
}
|
||||
|
||||
protected void replaceAtAllUsages(Node other, Node toBeDeleted) {
|
||||
assert checkReplaceWith(other);
|
||||
checkReplaceWith(other);
|
||||
if (usage0 == null) {
|
||||
return;
|
||||
}
|
||||
@ -679,12 +689,14 @@ public abstract class Node implements Cloneable, Formattable, NodeInterface {
|
||||
}
|
||||
|
||||
private void replaceAtMatchingUsages(Node other, Predicate<Node> 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 abstract class Node implements Cloneable, Formattable, NodeInterface {
|
||||
}
|
||||
|
||||
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 abstract class Node implements Cloneable, Formattable, NodeInterface {
|
||||
}
|
||||
|
||||
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 abstract class Node implements Cloneable, Formattable, NodeInterface {
|
||||
public final void pushInputs(NodeStack stack) {
|
||||
getNodeClass().pushInputs(this, stack);
|
||||
}
|
||||
|
||||
public NodeSize estimatedNodeSize() {
|
||||
return nodeClass.size();
|
||||
}
|
||||
|
||||
public NodeCycles estimatedNodeCycles() {
|
||||
return nodeClass.cycles();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -941,6 +941,10 @@ public final class NodeClass<T> extends FieldIntrospection<T> {
|
||||
return this.leafId;
|
||||
}
|
||||
|
||||
public NodeClass<? super T> getSuperNodeClass() {
|
||||
return superNodeClass;
|
||||
}
|
||||
|
||||
public long inputsIteration() {
|
||||
return inputsIteration;
|
||||
}
|
||||
|
||||
@ -50,10 +50,10 @@ public interface CanonicalizerTool {
|
||||
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();
|
||||
}
|
||||
|
||||
@ -46,10 +46,8 @@ import org.graalvm.compiler.hotspot.meta.HotSpotRegistersProvider;
|
||||
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 @@ public class AArch64HotSpotBackendFactory implements HotSpotBackendFactory {
|
||||
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 @@ public class AArch64HotSpotBackendFactory implements HotSpotBackendFactory {
|
||||
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 @@ public class AArch64HotSpotBackendFactory implements HotSpotBackendFactory {
|
||||
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 @@ public class AArch64HotSpotBackendFactory implements HotSpotBackendFactory {
|
||||
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();
|
||||
|
||||
@ -24,6 +24,7 @@ package org.graalvm.compiler.hotspot.aarch64;
|
||||
|
||||
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 class AArch64HotSpotMove {
|
||||
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 class AArch64HotSpotMove {
|
||||
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());
|
||||
|
||||
@ -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.MetaAccessProvider;
|
||||
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<AArch64RawNativeCallNode> TYPE = NodeClass.create(AArch64RawNativeCallNode.class);
|
||||
|
||||
|
||||
@ -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);
|
||||
}
|
||||
}
|
||||
@ -46,10 +46,8 @@ import org.graalvm.compiler.hotspot.meta.HotSpotRegistersProvider;
|
||||
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 @@ public class AMD64HotSpotBackendFactory implements HotSpotBackendFactory {
|
||||
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 @@ public class AMD64HotSpotBackendFactory implements HotSpotBackendFactory {
|
||||
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 @@ public class AMD64HotSpotBackendFactory implements HotSpotBackendFactory {
|
||||
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 @@ public class AMD64HotSpotBackendFactory implements HotSpotBackendFactory {
|
||||
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<Register> callerSave = new ArrayList<>(regConfig.getAllocatableRegisters().asList());
|
||||
if (config.windowsOs) {
|
||||
|
||||
@ -120,7 +120,7 @@ public class AMD64HotSpotLoweringProvider extends DefaultHotSpotLoweringProvider
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean supportSubwordCompare(int bits) {
|
||||
return true;
|
||||
public Integer smallestCompareWidth() {
|
||||
return 8;
|
||||
}
|
||||
}
|
||||
|
||||
@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
@ -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.core.common.type.StampFactory;
|
||||
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.MetaAccessProvider;
|
||||
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<AMD64RawNativeCallNode> TYPE = NodeClass.create(AMD64RawNativeCallNode.class);
|
||||
|
||||
|
||||
@ -44,11 +44,9 @@ import org.graalvm.compiler.hotspot.meta.HotSpotRegistersProvider;
|
||||
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 @@ public class SPARCHotSpotBackendFactory implements HotSpotBackendFactory {
|
||||
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 @@ public class SPARCHotSpotBackendFactory implements HotSpotBackendFactory {
|
||||
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<Register> callerSavedRegisters = new HashSet<>();
|
||||
|
||||
@ -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);
|
||||
}
|
||||
}
|
||||
@ -20,19 +20,15 @@
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
package org.graalvm.compiler.hotspot;
|
||||
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.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 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;
|
||||
@ -41,21 +37,19 @@ 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.ByteBuffer;
|
||||
import java.nio.ByteOrder;
|
||||
import java.nio.channels.FileChannel;
|
||||
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.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.Collections;
|
||||
import java.util.Enumeration;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
@ -76,17 +70,24 @@ 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;
|
||||
@ -106,11 +107,17 @@ 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
|
||||
* <java.home>/lib/modules} are compiled.
|
||||
* 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 = "<jrt>";
|
||||
|
||||
/**
|
||||
* @param options a space separated set of option value settings with each option setting in a
|
||||
* {@code -Dgraal.<name>=<value>} format but without the leading {@code -Dgraal.}.
|
||||
@ -137,21 +144,21 @@ public final class CompileTheWorld {
|
||||
/**
|
||||
* Class path denoting classes to compile.
|
||||
*
|
||||
* @see CompileTheWorldOptions#CompileTheWorldClasspath
|
||||
* @see Options#Classpath
|
||||
*/
|
||||
private final String inputClassPath;
|
||||
|
||||
/**
|
||||
* Class index to start compilation at.
|
||||
*
|
||||
* @see CompileTheWorldOptions#CompileTheWorldStartAt
|
||||
* @see Options#StartAt
|
||||
*/
|
||||
private final int startAt;
|
||||
|
||||
/**
|
||||
* Class index to stop compilation at.
|
||||
*
|
||||
* @see CompileTheWorldOptions#CompileTheWorldStopAt
|
||||
* @see Options#StopAt
|
||||
*/
|
||||
private final int stopAt;
|
||||
|
||||
@ -216,19 +223,19 @@ public final class CompileTheWorld {
|
||||
}
|
||||
|
||||
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),
|
||||
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(CompileTheWorldConfig.getValue(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 class path is used.
|
||||
* equals {@link #SUN_BOOT_CLASS_PATH} the boot classes are used.
|
||||
*/
|
||||
public void compile() throws Throwable {
|
||||
if (SUN_BOOT_CLASS_PATH.equals(inputClassPath)) {
|
||||
@ -238,13 +245,15 @@ public final class CompileTheWorld {
|
||||
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;
|
||||
}
|
||||
}
|
||||
if (bcpEntry == null) {
|
||||
throw new GraalError("Could not find rt.jar on boot class path %s", System.getProperty(SUN_BOOT_CLASS_PATH));
|
||||
}
|
||||
} else {
|
||||
bcpEntry = System.getProperty("java.home") + "/lib/modules".replace('/', File.separatorChar);
|
||||
bcpEntry = JRT_CLASS_PATH_ENTRY;
|
||||
}
|
||||
compile(bcpEntry);
|
||||
} else {
|
||||
@ -394,92 +403,70 @@ public final class CompileTheWorld {
|
||||
}
|
||||
|
||||
/**
|
||||
* Name of the property that limits the set of modules processed by CompileTheWorld.
|
||||
* A class path entry representing the {@code jrt:/} file system.
|
||||
*/
|
||||
public static final String LIMITMODS_PROPERTY_NAME = "CompileTheWorld.limitmods";
|
||||
static class JRTClassPathEntry extends ClassPathEntry {
|
||||
|
||||
/**
|
||||
* A class path entry that is a jimage file.
|
||||
*/
|
||||
static class ImageClassPathEntry extends ClassPathEntry {
|
||||
private final String limitModules;
|
||||
|
||||
private final File jimage;
|
||||
|
||||
ImageClassPathEntry(String name) {
|
||||
JRTClassPathEntry(String name, String limitModules) {
|
||||
super(name);
|
||||
jimage = new File(name);
|
||||
assert jimage.isFile();
|
||||
this.limitModules = limitModules;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ClassLoader createClassLoader() throws IOException {
|
||||
URL url = jimage.toURI().toURL();
|
||||
URL url = URI.create("jrt:/").toURL();
|
||||
return new URLClassLoader(new URL[]{url});
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> getClassNames() throws IOException {
|
||||
String prop = System.getProperty(LIMITMODS_PROPERTY_NAME);
|
||||
Set<String> limitmods = prop == null ? null : new HashSet<>(Arrays.asList(prop.split(",")));
|
||||
List<String> 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;
|
||||
}
|
||||
Set<String> negative = new HashSet<>();
|
||||
Set<String> 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);
|
||||
}
|
||||
// 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);
|
||||
}
|
||||
}
|
||||
List<String> 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 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) {
|
||||
private boolean isClassIncluded(String className) {
|
||||
if (methodFilters != null && !MethodFilter.matchesClassName(methodFilters, className)) {
|
||||
return false;
|
||||
}
|
||||
return false;
|
||||
if (excludeMethodFilters != null && MethodFilter.matchesClassName(excludeMethodFilters, className)) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -512,8 +499,8 @@ public final class CompileTheWorld {
|
||||
* DebugValueThreadFilter to filter on the thread names.
|
||||
*/
|
||||
int threadCount = 1;
|
||||
if (CompileTheWorldOptions.CompileTheWorldMultiThreaded.getValue(currentOptions)) {
|
||||
threadCount = CompileTheWorldOptions.CompileTheWorldThreads.getValue(currentOptions);
|
||||
if (Options.MultiThreaded.getValue(currentOptions)) {
|
||||
threadCount = Options.Threads.getValue(currentOptions);
|
||||
if (threadCount == 0) {
|
||||
threadCount = Runtime.getRuntime().availableProcessors();
|
||||
}
|
||||
@ -538,9 +525,8 @@ public final class CompileTheWorld {
|
||||
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 (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);
|
||||
@ -590,17 +576,17 @@ public final class CompileTheWorld {
|
||||
}
|
||||
} catch (Throwable t) {
|
||||
// If something went wrong during pre-loading we just ignore it.
|
||||
println("Preloading failed for (%d) %s: %s", classFileCounter, className, t);
|
||||
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 (methodFilters != null && !MethodFilter.matchesClassName(methodFilters, className)) {
|
||||
continue;
|
||||
}
|
||||
if (excludeMethodFilters != null && MethodFilter.matchesClassName(excludeMethodFilters, className)) {
|
||||
if (!isClassIncluded(className)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
@ -630,8 +616,10 @@ public final class CompileTheWorld {
|
||||
}
|
||||
}
|
||||
} catch (Throwable t) {
|
||||
println("CompileTheWorld (%d) : Skipping %s %s", classFileCounter, className, t.toString());
|
||||
printStackTrace(t);
|
||||
if (isClassIncluded(className)) {
|
||||
println("CompileTheWorld (%d) : Skipping %s %s", classFileCounter, className, t.toString());
|
||||
printStackTrace(t);
|
||||
}
|
||||
}
|
||||
}
|
||||
cpe.close();
|
||||
@ -659,7 +647,7 @@ public final class CompileTheWorld {
|
||||
long elapsedTime = System.currentTimeMillis() - start;
|
||||
|
||||
println();
|
||||
if (CompileTheWorldOptions.CompileTheWorldMultiThreaded.getValue(currentOptions)) {
|
||||
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 {
|
||||
@ -769,9 +757,73 @@ public final class CompileTheWorld {
|
||||
return true;
|
||||
}
|
||||
|
||||
static class Options {
|
||||
// @formatter:off
|
||||
public static final OptionKey<Boolean> Help = new OptionKey<>(false);
|
||||
public static final OptionKey<String> Classpath = new OptionKey<>(CompileTheWorld.SUN_BOOT_CLASS_PATH);
|
||||
public static final OptionKey<Boolean> Verbose = new OptionKey<>(true);
|
||||
/**
|
||||
* Ignore Graal classes by default to avoid problems associated with compiling
|
||||
* snippets and method substitutions.
|
||||
*/
|
||||
public static final OptionKey<String> LimitModules = new OptionKey<>("~jdk.internal.vm.compiler");
|
||||
public static final OptionKey<Integer> Iterations = new OptionKey<>(1);
|
||||
public static final OptionKey<String> MethodFilter = new OptionKey<>(null);
|
||||
public static final OptionKey<String> ExcludeMethodFilter = new OptionKey<>(null);
|
||||
public static final OptionKey<Integer> StartAt = new OptionKey<>(1);
|
||||
public static final OptionKey<Integer> StopAt = new OptionKey<>(Integer.MAX_VALUE);
|
||||
public static final OptionKey<String> Config = new OptionKey<>(null);
|
||||
public static final OptionKey<Boolean> MultiThreaded = new OptionKey<>(false);
|
||||
public static final OptionKey<Integer> 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<OptionKey<?>, Object> values = OptionValues.newOptionMap();
|
||||
List<OptionDescriptors> 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);
|
||||
HotSpotGraalCompiler compiler = (HotSpotGraalCompiler) HotSpotJVMCIRuntime.runtime().getCompiler();
|
||||
compiler.compileTheWorld();
|
||||
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);
|
||||
}
|
||||
}
|
||||
@ -24,7 +24,6 @@ package org.graalvm.compiler.hotspot.test;
|
||||
|
||||
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 @@ public class CompileTheWorldTest extends GraalCompilerTest {
|
||||
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<OptionKey<?>, 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();
|
||||
|
||||
@ -28,10 +28,9 @@ import org.graalvm.compiler.api.test.Graal;
|
||||
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 @@ import jdk.vm.ci.runtime.JVMCICompiler;
|
||||
* Memory analysis for a {@link CompileTheWorld} execution can also be performed. For example:
|
||||
*
|
||||
* <pre>
|
||||
* 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
|
||||
* </pre>
|
||||
*/
|
||||
public class MemoryUsageBenchmark extends HotSpotGraalCompilerTest {
|
||||
@ -181,9 +180,10 @@ public class MemoryUsageBenchmark extends HotSpotGraalCompilerTest {
|
||||
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) {
|
||||
|
||||
@ -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<String> 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<String> 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();
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -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
|
||||
* <a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=477597">Eclipse bug 477597</a>.
|
||||
*/
|
||||
public class CompileTheWorldOptions {
|
||||
// @formatter:off
|
||||
@Option(help = "Class path denoting methods to compile", type = OptionType.Debug)
|
||||
public static final OptionKey<String> CompileTheWorldClasspath = new OptionKey<>(CompileTheWorld.SUN_BOOT_CLASS_PATH);
|
||||
@Option(help = "Verbose CompileTheWorld operation", type = OptionType.Debug)
|
||||
public static final OptionKey<Boolean> CompileTheWorldVerbose = new OptionKey<>(true);
|
||||
@Option(help = "The number of CompileTheWorld iterations to perform", type = OptionType.Debug)
|
||||
public static final OptionKey<Integer> CompileTheWorldIterations = new OptionKey<>(1);
|
||||
@Option(help = "Only compile methods matching this filter", type = OptionType.Debug)
|
||||
public static final OptionKey<String> CompileTheWorldMethodFilter = new OptionKey<>(null);
|
||||
@Option(help = "Exclude methods matching this filter from compilation", type = OptionType.Debug)
|
||||
public static final OptionKey<String> CompileTheWorldExcludeMethodFilter = new OptionKey<>(null);
|
||||
@Option(help = "First class to consider when using -XX:+CompileTheWorld", type = OptionType.Debug)
|
||||
public static final OptionKey<Integer> CompileTheWorldStartAt = new OptionKey<>(1);
|
||||
@Option(help = "Last class to consider when using -XX:+CompileTheWorld", type = OptionType.Debug)
|
||||
public static final OptionKey<Integer> 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<String> 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<Boolean> 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<Integer> CompileTheWorldThreads = new OptionKey<>(0);
|
||||
// @formatter:on
|
||||
}
|
||||
@ -39,7 +39,6 @@ import org.graalvm.compiler.debug.Debug;
|
||||
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 org.graalvm.compiler.phases.tiers.Suites;
|
||||
|
||||
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 class HotSpotGraalCompiler implements GraalJVMCICompiler {
|
||||
}
|
||||
}
|
||||
|
||||
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();
|
||||
|
||||
@ -39,7 +39,6 @@ import org.graalvm.compiler.options.OptionValuesAccess;
|
||||
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 @@ public class HotSpotGraalOptionValues implements OptionValuesAccess {
|
||||
Properties props = new Properties();
|
||||
props.load(fr);
|
||||
EconomicMap<String, String> optionSettings = EconomicMap.create();
|
||||
MapCursor<String, String> cursor = optionSettings.getEntries();
|
||||
while (cursor.advance()) {
|
||||
optionSettings.put(cursor.getKey(), cursor.getValue());
|
||||
for (Map.Entry<Object, Object> e : props.entrySet()) {
|
||||
optionSettings.put((String) e.getKey(), (String) e.getValue());
|
||||
}
|
||||
try {
|
||||
OptionsParser.parseOptions(optionSettings, values, loader);
|
||||
|
||||
@ -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 @@ public abstract class HotSpotHostBackend extends HotSpotBackend {
|
||||
// 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;
|
||||
|
||||
@ -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<Class<?>> classes = new HashSet<>();
|
||||
try {
|
||||
Set<String> 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<Class<?>> 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<NodeClass<?>> 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<Class<?>> classes) {
|
||||
try {
|
||||
Files.walkFileTree(root, new SimpleFileVisitor<Path>() {
|
||||
@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));
|
||||
}
|
||||
|
||||
}
|
||||
@ -252,7 +252,7 @@ public class HotSpotGraphBuilderPlugins {
|
||||
@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 {
|
||||
|
||||
@ -27,7 +27,6 @@ import org.graalvm.compiler.core.common.spi.ConstantFieldProvider;
|
||||
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 @@ public class HotSpotProviders extends Providers {
|
||||
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;
|
||||
|
||||
@ -117,7 +117,7 @@ class HotSpotWordOperationPlugin extends WordOperationPlugin {
|
||||
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;
|
||||
|
||||
|
||||
@ -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 @@ import jdk.vm.ci.meta.JavaKind;
|
||||
* 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<ComputeObjectAddressNode> TYPE = NodeClass.create(ComputeObjectAddressNode.class);
|
||||
|
||||
|
||||
@ -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 @@ import jdk.vm.ci.meta.DeoptimizationReason;
|
||||
/**
|
||||
* 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<DeoptimizeCallerNode> TYPE = NodeClass.create(DeoptimizeCallerNode.class);
|
||||
|
||||
@ -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<G1ArrayRangePostWriteBarrier> TYPE = NodeClass.create(G1ArrayRangePostWriteBarrier.class);
|
||||
|
||||
|
||||
@ -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<G1ArrayRangePreWriteBarrier> TYPE = NodeClass.create(G1ArrayRangePreWriteBarrier.class);
|
||||
|
||||
|
||||
@ -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<G1PostWriteBarrier> TYPE = NodeClass.create(G1PostWriteBarrier.class);
|
||||
|
||||
@ -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.FrameState;
|
||||
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<G1PreWriteBarrier> TYPE = NodeClass.create(G1PreWriteBarrier.class);
|
||||
|
||||
@ -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 @@ import org.graalvm.compiler.nodes.memory.address.AddressNode;
|
||||
* {@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<G1ReferentFieldReadBarrier> TYPE = NodeClass.create(G1ReferentFieldReadBarrier.class);
|
||||
|
||||
|
||||
@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
@ -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 @@ import org.graalvm.compiler.word.Word;
|
||||
* 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<JumpToExceptionHandlerInCallerNode> TYPE = NodeClass.create(JumpToExceptionHandlerInCallerNode.class);
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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<SerialArrayRangeWriteBarrier> TYPE = NodeClass.create(SerialArrayRangeWriteBarrier.class);
|
||||
|
||||
@ -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<SerialWriteBarrier> TYPE = NodeClass.create(SerialWriteBarrier.class);
|
||||
|
||||
@ -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 org.graalvm.compiler.word.Word;
|
||||
|
||||
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<EncodedSymbolNode> TYPE = NodeClass.create(EncodedSymbolNode.class);
|
||||
|
||||
@ -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.ValueNode;
|
||||
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<InitializeKlassNode> TYPE = NodeClass.create(InitializeKlassNode.class);
|
||||
|
||||
|
||||
@ -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 @@ import jdk.vm.ci.meta.Value;
|
||||
/**
|
||||
* 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<InitializeKlassStubCall> TYPE = NodeClass.create(InitializeKlassStubCall.class);
|
||||
|
||||
|
||||
@ -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.hotspot.HotSpotObjectConstant;
|
||||
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<LoadConstantIndirectlyFixedNode> TYPE = NodeClass.create(LoadConstantIndirectlyFixedNode.class);
|
||||
|
||||
@ -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.hotspot.HotSpotObjectConstant;
|
||||
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<LoadConstantIndirectlyNode> TYPE = NodeClass.create(LoadConstantIndirectlyNode.class);
|
||||
|
||||
@ -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.hotspot.HotSpotMetaspaceConstant;
|
||||
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<LoadMethodCountersIndirectlyNode> TYPE = NodeClass.create(LoadMethodCountersIndirectlyNode.class);
|
||||
|
||||
@ -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.calc.FloatingNode;
|
||||
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<LoadMethodCountersNode> TYPE = NodeClass.create(LoadMethodCountersNode.class);
|
||||
|
||||
|
||||
@ -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.calc.FloatingNode;
|
||||
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<ResolveConstantNode> TYPE = NodeClass.create(ResolveConstantNode.class);
|
||||
|
||||
|
||||
@ -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 @@ 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 ResolveConstantStubCall extends DeoptimizingStubCall implements Canonicalizable, LIRLowerable {
|
||||
public static final NodeClass<ResolveConstantStubCall> TYPE = NodeClass.create(ResolveConstantStubCall.class);
|
||||
|
||||
|
||||
@ -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.calc.FloatingNode;
|
||||
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<ResolveMethodAndLoadCountersNode> TYPE = NodeClass.create(ResolveMethodAndLoadCountersNode.class);
|
||||
|
||||
|
||||
@ -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.LIRLowerable;
|
||||
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<ResolveMethodAndLoadCountersStubCall> TYPE = NodeClass.create(ResolveMethodAndLoadCountersStubCall.class);
|
||||
|
||||
|
||||
@ -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 org.graalvm.compiler.options.OptionType;
|
||||
|
||||
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)//
|
||||
|
||||
@ -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<ProfileWithNotificationNode> TYPE = NodeClass.create(ProfileWithNotificationNode.class);
|
||||
|
||||
|
||||
@ -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 @@ import jdk.vm.ci.meta.ResolvedJavaType;
|
||||
* 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<ClassGetHubNode> TYPE = NodeClass.create(ClassGetHubNode.class);
|
||||
@Input protected ValueNode clazz;
|
||||
@ -80,7 +80,7 @@ public final class ClassGetHubNode extends FloatingNode implements Lowerable, Ca
|
||||
@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;
|
||||
}
|
||||
|
||||
|
||||
@ -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 @@ import jdk.vm.ci.meta.ResolvedJavaType;
|
||||
* 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<HubGetClassNode> TYPE = NodeClass.create(HubGetClassNode.class);
|
||||
@Input protected ValueNode hub;
|
||||
|
||||
@ -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 @@ import jdk.vm.ci.meta.ResolvedJavaType;
|
||||
* 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<KlassLayoutHelperNode> TYPE = NodeClass.create(KlassLayoutHelperNode.class);
|
||||
@ -75,7 +75,7 @@ public final class KlassLayoutHelperNode extends FloatingNode implements Canonic
|
||||
@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;
|
||||
}
|
||||
|
||||
|
||||
@ -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.ConstantReflectionProvider;
|
||||
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<ReflectionGetCallerClassNode> TYPE = NodeClass.create(ReflectionGetCallerClassNode.class);
|
||||
|
||||
@ -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 org.graalvm.compiler.replacements.SnippetTemplate.Arguments;
|
||||
|
||||
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<UnsafeArrayCopyNode> TYPE = NodeClass.create(UnsafeArrayCopyNode.class);
|
||||
|
||||
@ -437,8 +437,6 @@ public final class BciBlockMapping {
|
||||
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 @@ public final class BciBlockMapping {
|
||||
return this.blocks;
|
||||
}
|
||||
|
||||
public int getReturnCount() {
|
||||
return this.returnCount;
|
||||
}
|
||||
|
||||
/**
|
||||
* Builds the block map and conservative CFG and numbers blocks.
|
||||
*/
|
||||
@ -533,9 +527,7 @@ public final class BciBlockMapping {
|
||||
case DRETURN: // fall through
|
||||
case ARETURN: // fall through
|
||||
case RETURN: {
|
||||
returnCount++;
|
||||
current = null;
|
||||
returnBci = bci;
|
||||
break;
|
||||
}
|
||||
case ATHROW: {
|
||||
@ -832,7 +824,7 @@ public final class BciBlockMapping {
|
||||
|
||||
// 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 @@ public final class BciBlockMapping {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 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 @@ public final class BciBlockMapping {
|
||||
return startBlock;
|
||||
}
|
||||
|
||||
public BciBlock getReturnBlock() {
|
||||
return blocks[blocks.length - 2];
|
||||
}
|
||||
|
||||
public ExceptionDispatchBlock getUnwindBlock() {
|
||||
return (ExceptionDispatchBlock) blocks[blocks.length - 1];
|
||||
}
|
||||
|
||||
@ -251,6 +251,8 @@ import static org.graalvm.compiler.java.BytecodeParserOptions.TraceBytecodeParse
|
||||
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.type.StampTool;
|
||||
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 @@ public class BytecodeParser implements GraphBuilderContext {
|
||||
}
|
||||
}
|
||||
|
||||
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 @@ public class BytecodeParser implements GraphBuilderContext {
|
||||
|
||||
private ValueNode methodSynchronizedObject;
|
||||
|
||||
private ValueNode returnValue;
|
||||
private FixedWithNextNode beforeReturnNode;
|
||||
private List<ReturnToCallerData> returnDataList;
|
||||
private ValueNode unwindValue;
|
||||
private FixedWithNextNode beforeUnwindNode;
|
||||
|
||||
@ -641,14 +653,6 @@ public class BytecodeParser implements GraphBuilderContext {
|
||||
return graphBuilderInstance;
|
||||
}
|
||||
|
||||
public ValueNode getReturnValue() {
|
||||
return returnValue;
|
||||
}
|
||||
|
||||
public FixedWithNextNode getBeforeReturnNode() {
|
||||
return this.beforeReturnNode;
|
||||
}
|
||||
|
||||
public ValueNode getUnwindValue() {
|
||||
return unwindValue;
|
||||
}
|
||||
@ -1114,15 +1118,15 @@ public class BytecodeParser implements GraphBuilderContext {
|
||||
}
|
||||
|
||||
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 @@ public class BytecodeParser implements GraphBuilderContext {
|
||||
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 @@ public class BytecodeParser implements GraphBuilderContext {
|
||||
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 @@ public class BytecodeParser implements GraphBuilderContext {
|
||||
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 @@ public class BytecodeParser implements GraphBuilderContext {
|
||||
|
||||
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 @@ public class BytecodeParser implements GraphBuilderContext {
|
||||
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 @@ public class BytecodeParser implements GraphBuilderContext {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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 @@ public class BytecodeParser implements GraphBuilderContext {
|
||||
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())) {
|
||||
@ -2179,18 +2191,6 @@ public class BytecodeParser implements GraphBuilderContext {
|
||||
|
||||
@Override
|
||||
public <T extends ValueNode> T append(T v) {
|
||||
if (v.graph() != null) {
|
||||
return v;
|
||||
}
|
||||
T added = graph.addOrUnique(v);
|
||||
if (added == v) {
|
||||
updateLastInstruction(v);
|
||||
}
|
||||
return added;
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T extends ValueNode> T recursiveAppend(T v) {
|
||||
if (v.graph() != null) {
|
||||
return v;
|
||||
}
|
||||
@ -2429,9 +2429,7 @@ public class BytecodeParser implements GraphBuilderContext {
|
||||
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 @@ public class BytecodeParser implements GraphBuilderContext {
|
||||
}
|
||||
}
|
||||
|
||||
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 @@ public class BytecodeParser implements GraphBuilderContext {
|
||||
default:
|
||||
throw shouldNotReachHere();
|
||||
}
|
||||
frameState.push(kind, recursiveAppend(v));
|
||||
frameState.push(kind, append(v));
|
||||
}
|
||||
|
||||
private void genIntegerDivOp(JavaKind kind, int opcode) {
|
||||
@ -3191,7 +3180,7 @@ public class BytecodeParser implements GraphBuilderContext {
|
||||
default:
|
||||
throw shouldNotReachHere();
|
||||
}
|
||||
frameState.push(kind, recursiveAppend(v));
|
||||
frameState.push(kind, append(v));
|
||||
}
|
||||
|
||||
private void genLogicOp(JavaKind kind, int opcode) {
|
||||
@ -3214,7 +3203,7 @@ public class BytecodeParser implements GraphBuilderContext {
|
||||
default:
|
||||
throw shouldNotReachHere();
|
||||
}
|
||||
frameState.push(kind, recursiveAppend(v));
|
||||
frameState.push(kind, append(v));
|
||||
}
|
||||
|
||||
private void genCompareOp(JavaKind kind, boolean isUnorderedLess) {
|
||||
@ -3233,7 +3222,7 @@ public class BytecodeParser implements GraphBuilderContext {
|
||||
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 @@ public class BytecodeParser implements GraphBuilderContext {
|
||||
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) {
|
||||
|
||||
@ -376,7 +376,7 @@ public final class RedundantMoveElimination extends PostAllocationOptimizationPh
|
||||
@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
|
||||
|
||||
@ -750,11 +750,7 @@ public class LinearScan {
|
||||
}
|
||||
}
|
||||
}
|
||||
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() {
|
||||
|
||||
@ -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);
|
||||
|
||||
}
|
||||
@ -46,7 +46,7 @@ import org.graalvm.compiler.lir.StandardOp.MoveOp;
|
||||
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 @@ import jdk.vm.ci.meta.Value;
|
||||
/**
|
||||
* Phase 7: Assign register numbers back to LIR.
|
||||
*/
|
||||
public class LinearScanAssignLocationsPhase extends AllocationPhase {
|
||||
public class LinearScanAssignLocationsPhase extends LinearScanAllocationPhase {
|
||||
|
||||
protected final LinearScan allocator;
|
||||
|
||||
|
||||
@ -41,7 +41,7 @@ import org.graalvm.compiler.lir.StandardOp.ValueMoveOp;
|
||||
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 org.graalvm.compiler.options.OptionType;
|
||||
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
|
||||
|
||||
@ -36,8 +36,8 @@ import java.util.ArrayList;
|
||||
import java.util.BitSet;
|
||||
import java.util.EnumSet;
|
||||
|
||||
import org.graalvm.compiler.core.common.PermanentBailoutException;
|
||||
import org.graalvm.compiler.core.common.LIRKind;
|
||||
import org.graalvm.compiler.core.common.PermanentBailoutException;
|
||||
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.RegisterPriority;
|
||||
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.JavaConstant;
|
||||
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 @@ public class LinearScanLifetimeAnalysisPhase extends AllocationPhase {
|
||||
@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()));
|
||||
|
||||
@ -27,6 +27,7 @@ import static org.graalvm.compiler.core.common.cfg.AbstractControlFlowGraph.domi
|
||||
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;
|
||||
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");
|
||||
|
||||
@ -25,12 +25,12 @@ package org.graalvm.compiler.lir.alloc.lsra;
|
||||
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;
|
||||
|
||||
|
||||
@ -31,7 +31,7 @@ import org.graalvm.compiler.debug.Indent;
|
||||
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 @@ import jdk.vm.ci.code.TargetDescription;
|
||||
*
|
||||
* 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;
|
||||
|
||||
|
||||
@ -112,13 +112,13 @@ public abstract class TraceAllocationPhase<C extends TraceAllocationPhase.TraceA
|
||||
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) {
|
||||
|
||||
@ -64,9 +64,6 @@ public class TraceBuilderPhase extends AllocationPhase {
|
||||
// @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 @@ public class TraceBuilderPhase extends AllocationPhase {
|
||||
|
||||
final TraceBuilderResult traceBuilderResult = getTraceBuilderResult(lir, startBlock, linearScanOrder);
|
||||
|
||||
if (Debug.isLogEnabled(TRACE_LOG_LEVEL)) {
|
||||
if (Debug.isLogEnabled(Debug.BASIC_LEVEL)) {
|
||||
ArrayList<Trace> 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 @@ public class TraceBuilderPhase extends AllocationPhase {
|
||||
|
||||
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);
|
||||
|
||||
@ -45,7 +45,6 @@ import org.graalvm.compiler.lir.StandardOp.LabelOp;
|
||||
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.code.TargetDescription;
|
||||
import jdk.vm.ci.meta.AllocatableValue;
|
||||
import jdk.vm.ci.meta.Value;
|
||||
|
||||
public final class TraceGlobalMoveResolutionPhase extends LIRPhase<TraceAllocationPhase.TraceAllocationContext> {
|
||||
public final class TraceGlobalMoveResolutionPhase {
|
||||
|
||||
private TraceGlobalMoveResolutionPhase() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Abstract move resolver interface for testing.
|
||||
@ -63,8 +65,8 @@ public final class TraceGlobalMoveResolutionPhase extends LIRPhase<TraceAllocati
|
||||
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 @@ public final class TraceGlobalMoveResolutionPhase extends LIRPhase<TraceAllocati
|
||||
moveResolver.addMapping(from, to, fromStack);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -31,7 +31,6 @@ import org.graalvm.compiler.debug.Debug.Scope;
|
||||
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 @@ public final class TraceRegisterAllocationPhase extends AllocationPhase {
|
||||
// @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 @@ public final class TraceRegisterAllocationPhase extends AllocationPhase {
|
||||
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 @@ public final class TraceRegisterAllocationPhase extends AllocationPhase {
|
||||
} 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 @@ public final class TraceRegisterAllocationPhase extends AllocationPhase {
|
||||
}
|
||||
}
|
||||
|
||||
private static void unnumberInstructions(LIR lir) {
|
||||
for (AbstractBlockBase<?> block : lir.getControlFlowGraph().getBlocks()) {
|
||||
for (LIRInstruction op : lir.getLIRforBlock(block)) {
|
||||
op.setId(-1);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -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;
|
||||
|
||||
abstract class TraceLinearScanAllocationPhase extends TraceAllocationPhase<TraceLinearScanAllocationPhase.TraceLinearScanAllocationContext> {
|
||||
import jdk.vm.ci.code.TargetDescription;
|
||||
|
||||
static final class TraceLinearScanAllocationContext extends TraceAllocationPhase.TraceAllocationContext {
|
||||
public final TraceLinearScan allocator;
|
||||
abstract class TraceLinearScanAllocationPhase {
|
||||
|
||||
TraceLinearScanAllocationContext(MoveFactory spillMoveFactory, RegisterAllocationConfig registerAllocationConfig, TraceBuilderResult traceBuilderResult, TraceLinearScan allocator) {
|
||||
super(spillMoveFactory, registerAllocationConfig, traceBuilderResult, allocator.getGlobalLivenessInfo());
|
||||
this.allocator = allocator;
|
||||
final CharSequence getName() {
|
||||
return LIRPhase.createName(getClass());
|
||||
}
|
||||
|
||||
@Override
|
||||
public final String toString() {
|
||||
return getName().toString();
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
}
|
||||
|
||||
@ -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.ArrayList;
|
||||
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 @@ import jdk.vm.ci.meta.Value;
|
||||
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();
|
||||
}
|
||||
|
||||
|
||||
@ -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 static org.graalvm.compiler.lir.LIRValueUtil.isVariable;
|
||||
|
||||
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.TraceInterval.SpillState;
|
||||
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 @@ final class TraceLinearScanEliminateSpillMovePhase extends TraceLinearScanAlloca
|
||||
};
|
||||
|
||||
@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);
|
||||
}
|
||||
|
||||
@ -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.ArrayList;
|
||||
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 @@ import jdk.vm.ci.meta.Value;
|
||||
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 @@ public final class TraceLinearScanLifetimeAnalysisPhase extends TraceLinearScanA
|
||||
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
|
||||
|
||||
@ -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.VirtualStackSlot;
|
||||
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 @@ public final class TraceLinearScanPhase extends TraceAllocationPhase<TraceAlloca
|
||||
|
||||
@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 final class TraceLinearScanPhase extends TraceAllocationPhase<TraceAlloca
|
||||
}
|
||||
}
|
||||
|
||||
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 @@ public final class TraceLinearScanPhase extends TraceAllocationPhase<TraceAlloca
|
||||
|
||||
@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 @@ public final class TraceLinearScanPhase extends TraceAllocationPhase<TraceAlloca
|
||||
}
|
||||
}
|
||||
}
|
||||
Debug.dump(Debug.INFO_LEVEL, this, label);
|
||||
Debug.dump(Debug.DETAILED_LEVEL, this, "%s (Trace%d)", label, trace.getId());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -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);
|
||||
}
|
||||
|
||||
|
||||
@ -31,6 +31,7 @@ import static org.graalvm.compiler.lir.LIRValueUtil.isVirtualStackSlot;
|
||||
|
||||
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.StandardOp.LabelOp;
|
||||
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 @@ import jdk.vm.ci.meta.Value;
|
||||
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());
|
||||
}
|
||||
|
||||
|
||||
@ -113,8 +113,8 @@ public abstract class LIRPhase<C> {
|
||||
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 @@ public abstract class LIRPhase<C> {
|
||||
}
|
||||
}
|
||||
|
||||
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) {
|
||||
|
||||
@ -103,6 +103,7 @@ public final class LSStackSlotAllocator extends AllocationPhase {
|
||||
}
|
||||
|
||||
private static final class Allocator {
|
||||
|
||||
private final LIR lir;
|
||||
private final FrameMapBuilderTool frameMapBuilder;
|
||||
private final StackInterval[] stackSlotMap;
|
||||
@ -131,7 +132,7 @@ public final class LSStackSlotAllocator extends AllocationPhase {
|
||||
|
||||
@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<LIRInstruction> usePos;
|
||||
@ -145,14 +146,14 @@ public final class LSStackSlotAllocator extends AllocationPhase {
|
||||
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 @@ public final class LSStackSlotAllocator extends AllocationPhase {
|
||||
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 @@ public final class LSStackSlotAllocator extends AllocationPhase {
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -69,8 +69,9 @@ import org.graalvm.compiler.nodes.cfg.ControlFlowGraph;
|
||||
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.Equivalence;
|
||||
import org.graalvm.util.EconomicMap;
|
||||
import org.graalvm.util.EconomicSet;
|
||||
import org.graalvm.util.Equivalence;
|
||||
|
||||
import jdk.vm.ci.code.BytecodeFrame;
|
||||
|
||||
@ -296,7 +297,7 @@ public class LoopEx {
|
||||
}
|
||||
|
||||
public void nodesInLoopBranch(NodeBitMap branchNodes, AbstractBeginNode branch) {
|
||||
Collection<AbstractBeginNode> blocks = new LinkedList<>();
|
||||
EconomicSet<AbstractBeginNode> blocks = EconomicSet.create();
|
||||
Collection<LoopExitNode> exits = new LinkedList<>();
|
||||
Queue<Block> work = new LinkedList<>();
|
||||
ControlFlowGraph cfg = loopsData().getCFG();
|
||||
@ -304,9 +305,9 @@ public class LoopEx {
|
||||
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)) {
|
||||
|
||||
@ -52,28 +52,58 @@ public enum NodeCycles {
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
@ -47,31 +47,65 @@ public enum NodeSize {
|
||||
*/
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
@ -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 @@ import org.graalvm.compiler.nodes.spi.NodeLIRBuilderTool;
|
||||
* 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<BreakpointNode> TYPE = NodeClass.create(BreakpointNode.class);
|
||||
|
||||
@ -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 final class FrameState extends VirtualState implements IterableNodeType {
|
||||
*/
|
||||
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<TwoSlotMarker> TYPE = NodeClass.create(TwoSlotMarker.class);
|
||||
|
||||
|
||||
@ -573,7 +573,7 @@ public class GraphDecoder {
|
||||
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);
|
||||
|
||||
@ -427,8 +427,8 @@ public class GraphEncoder {
|
||||
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;
|
||||
}
|
||||
|
||||
@ -25,7 +25,13 @@ package org.graalvm.compiler.nodes;
|
||||
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.core.common.type.Stamp;
|
||||
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 final class InvokeNode extends AbstractMemoryCheckpoint implements Invoke
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -24,13 +24,16 @@ package org.graalvm.compiler.nodes;
|
||||
|
||||
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 final class LoopEndNode extends AbstractEndNode {
|
||||
public Iterable<? extends Node> 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();
|
||||
}
|
||||
}
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user