This commit is contained in:
Igor Veresov 2017-04-19 04:10:56 +00:00
commit f7c823802a
208 changed files with 3015 additions and 1902 deletions

View File

@ -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",

View File

@ -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.

View File

@ -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);
}
}

View File

@ -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);
}
}

View File

@ -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);
}
}

View File

@ -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);
}
}

View File

@ -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());
}
}

View File

@ -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;
}

View File

@ -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;

View File

@ -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);

View File

@ -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);

View File

@ -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);

View File

@ -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();
}
}

View File

@ -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;
}

View File

@ -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();
}

View File

@ -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();

View File

@ -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());

View File

@ -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);

View File

@ -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);
}
}

View File

@ -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) {

View File

@ -120,7 +120,7 @@ public class AMD64HotSpotLoweringProvider extends DefaultHotSpotLoweringProvider
}
@Override
public boolean supportSubwordCompare(int bits) {
return true;
public Integer smallestCompareWidth() {
return 8;
}
}

View File

@ -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);
}
}

View File

@ -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);

View File

@ -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<>();

View File

@ -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);
}
}

View File

@ -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);
}
}

View File

@ -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();

View File

@ -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) {

View File

@ -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();
}
}
}

View File

@ -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
}

View File

@ -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();

View File

@ -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);

View File

@ -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;

View File

@ -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));
}
}

View File

@ -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 {

View File

@ -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;

View File

@ -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;

View File

@ -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);

View File

@ -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);

View File

@ -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);

View File

@ -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);

View File

@ -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);

View File

@ -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);

View File

@ -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);

View File

@ -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);
}
}

View File

@ -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);

View File

@ -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

View File

@ -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);

View File

@ -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);

View File

@ -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);

View File

@ -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);

View File

@ -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);

View File

@ -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);

View File

@ -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);

View File

@ -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);

View File

@ -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);

View File

@ -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);

View File

@ -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);

View File

@ -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);

View File

@ -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);

View File

@ -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)//

View File

@ -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);

View File

@ -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;
}

View File

@ -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;

View File

@ -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;
}

View File

@ -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);

View File

@ -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);

View File

@ -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];
}

View File

@ -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) {

View File

@ -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

View File

@ -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() {

View File

@ -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);
}

View File

@ -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;

View File

@ -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

View File

@ -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()));

View File

@ -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");

View File

@ -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;

View File

@ -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;

View File

@ -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) {

View File

@ -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);

View File

@ -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);
}
}
}

View File

@ -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);
}
}
}
}

View File

@ -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);
}

View File

@ -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();
}

View File

@ -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);
}

View File

@ -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

View File

@ -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());
}
}

View File

@ -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);
}

View File

@ -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());
}

View File

@ -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) {

View File

@ -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);
}
}

View File

@ -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)) {

View File

@ -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);
}
}

View File

@ -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);
}
}

View File

@ -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);

View File

@ -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);

View File

@ -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);

View File

@ -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;
}

View File

@ -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;
}
}
}

View File

@ -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