# HG changeset patch # User Michael Van De Vanter # Date 1423096689 28800 # Node ID f10ca512eb40df3f9bc165e65ca7eaafb0f24aec # Parent 64e6c7b835159b3c8e314b26daf6dc9b7ad03192# Parent cd49455040c1d57d8ab74473b3786ecc4f663060 Merge with cd49455040c1d57d8ab74473b3786ecc4f663060 diff -r 64e6c7b83515 -r f10ca512eb40 graal/com.oracle.graal.compiler.amd64/src/com/oracle/graal/compiler/amd64/AMD64LIRGenerator.java --- a/graal/com.oracle.graal.compiler.amd64/src/com/oracle/graal/compiler/amd64/AMD64LIRGenerator.java Wed Feb 04 16:34:07 2015 -0800 +++ b/graal/com.oracle.graal.compiler.amd64/src/com/oracle/graal/compiler/amd64/AMD64LIRGenerator.java Wed Feb 04 16:38:09 2015 -0800 @@ -998,7 +998,7 @@ } @Override - public Value emitBitCount(Value value) { + public Variable emitBitCount(Value value) { Variable result = newVariable(LIRKind.derive(value).changeType(Kind.Int)); if (value.getKind().getStackKind() == Kind.Int) { append(new AMD64BitManipulationOp(IPOPCNT, result, asAllocatable(value))); @@ -1009,14 +1009,14 @@ } @Override - public Value emitBitScanForward(Value value) { + public Variable emitBitScanForward(Value value) { Variable result = newVariable(LIRKind.derive(value).changeType(Kind.Int)); append(new AMD64BitManipulationOp(BSF, result, asAllocatable(value))); return result; } @Override - public Value emitBitScanReverse(Value value) { + public Variable emitBitScanReverse(Value value) { Variable result = newVariable(LIRKind.derive(value).changeType(Kind.Int)); if (value.getKind().getStackKind() == Kind.Int) { append(new AMD64BitManipulationOp(IBSR, result, asAllocatable(value))); @@ -1098,14 +1098,14 @@ } @Override - public Value emitByteSwap(Value input) { + public Variable emitByteSwap(Value input) { Variable result = newVariable(LIRKind.derive(input)); append(new AMD64ByteSwapOp(result, input)); return result; } @Override - public Value emitArrayEquals(Kind kind, Value array1, Value array2, Value length) { + public Variable emitArrayEquals(Kind kind, Value array1, Value array2, Value length) { Variable result = newVariable(LIRKind.value(Kind.Int)); append(new AMD64ArrayEqualsOp(this, kind, result, array1, array2, asAllocatable(length))); return result; diff -r 64e6c7b83515 -r f10ca512eb40 graal/com.oracle.graal.compiler.sparc/src/com/oracle/graal/compiler/sparc/SPARCLIRGenerator.java --- a/graal/com.oracle.graal.compiler.sparc/src/com/oracle/graal/compiler/sparc/SPARCLIRGenerator.java Wed Feb 04 16:34:07 2015 -0800 +++ b/graal/com.oracle.graal.compiler.sparc/src/com/oracle/graal/compiler/sparc/SPARCLIRGenerator.java Wed Feb 04 16:38:09 2015 -0800 @@ -189,7 +189,7 @@ } @Override - public Value emitAddress(StackSlotValue address) { + public Variable emitAddress(StackSlotValue address) { Variable result = newVariable(LIRKind.value(target().wordKind)); append(new StackLoadAddressOp(result, address)); return result; @@ -422,7 +422,7 @@ } @Override - public Value emitBitCount(Value operand) { + public Variable emitBitCount(Value operand) { Variable result = newVariable(LIRKind.derive(operand).changeType(Kind.Int)); if (operand.getKind().getStackKind() == Kind.Int) { append(new SPARCBitManipulationOp(IPOPCNT, result, asAllocatable(operand), this)); @@ -433,14 +433,14 @@ } @Override - public Value emitBitScanForward(Value operand) { + public Variable emitBitScanForward(Value operand) { Variable result = newVariable(LIRKind.derive(operand).changeType(Kind.Int)); append(new SPARCBitManipulationOp(BSF, result, asAllocatable(operand), this)); return result; } @Override - public Value emitBitScanReverse(Value operand) { + public Variable emitBitScanReverse(Value operand) { Variable result = newVariable(LIRKind.derive(operand).changeType(Kind.Int)); if (operand.getKind().getStackKind() == Kind.Int) { append(new SPARCBitManipulationOp(IBSR, result, asAllocatable(operand), this)); @@ -493,14 +493,14 @@ } @Override - public Value emitByteSwap(Value input) { + public Variable emitByteSwap(Value input) { Variable result = newVariable(LIRKind.derive(input)); append(new SPARCByteSwapOp(this, result, input)); return result; } @Override - public Value emitArrayEquals(Kind kind, Value array1, Value array2, Value length) { + public Variable emitArrayEquals(Kind kind, Value array1, Value array2, Value length) { Variable result = newVariable(LIRKind.value(Kind.Int)); append(new SPARCArrayEqualsOp(this, kind, result, load(array1), load(array2), asAllocatable(length))); return result; diff -r 64e6c7b83515 -r f10ca512eb40 graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/FinalizableSubclassTest.java --- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/FinalizableSubclassTest.java Wed Feb 04 16:34:07 2015 -0800 +++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/FinalizableSubclassTest.java Wed Feb 04 16:38:09 2015 -0800 @@ -67,7 +67,7 @@ StructuredGraph graph = new StructuredGraph(javaMethod); GraphBuilderConfiguration conf = GraphBuilderConfiguration.getSnippetDefault(); - new GraphBuilderPhase.Instance(getMetaAccess(), getProviders().getStampProvider(), assumptions, conf, OptimisticOptimizations.ALL).apply(graph); + new GraphBuilderPhase.Instance(getMetaAccess(), getProviders().getStampProvider(), assumptions, getProviders().getConstantReflection(), conf, OptimisticOptimizations.ALL).apply(graph); HighTierContext context = new HighTierContext(getProviders(), assumptions, null, getDefaultGraphBuilderSuite(), OptimisticOptimizations.ALL); new InliningPhase(new CanonicalizerPhase(true)).apply(graph, context); new CanonicalizerPhase(true).apply(graph, context); diff -r 64e6c7b83515 -r f10ca512eb40 graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/GraalCompilerTest.java --- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/GraalCompilerTest.java Wed Feb 04 16:34:07 2015 -0800 +++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/GraalCompilerTest.java Wed Feb 04 16:38:09 2015 -0800 @@ -839,8 +839,9 @@ protected PhaseSuite getCustomGraphBuilderSuite(GraphBuilderConfiguration gbConf) { PhaseSuite suite = getDefaultGraphBuilderSuite().copy(); ListIterator> iterator = suite.findPhase(GraphBuilderPhase.class); + GraphBuilderPhase graphBuilderPhase = (GraphBuilderPhase) iterator.previous(); iterator.remove(); - iterator.add(new GraphBuilderPhase(gbConf)); + iterator.add(new GraphBuilderPhase(gbConf, graphBuilderPhase.getGraphBuilderPlugins())); return suite; } diff -r 64e6c7b83515 -r f10ca512eb40 graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ea/EATestBase.java --- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ea/EATestBase.java Wed Feb 04 16:34:07 2015 -0800 +++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ea/EATestBase.java Wed Feb 04 16:38:09 2015 -0800 @@ -152,7 +152,8 @@ graph = new StructuredGraph(method); try (Scope s = Debug.scope(getClass(), graph, method, getCodeCache())) { Assumptions assumptions = new Assumptions(false); - new GraphBuilderPhase.Instance(getMetaAccess(), getProviders().getStampProvider(), assumptions, GraphBuilderConfiguration.getEagerDefault(), OptimisticOptimizations.ALL).apply(graph); + new GraphBuilderPhase.Instance(getMetaAccess(), getProviders().getStampProvider(), assumptions, getProviders().getConstantReflection(), GraphBuilderConfiguration.getEagerDefault(), + OptimisticOptimizations.ALL).apply(graph); context = new HighTierContext(getProviders(), assumptions, null, getDefaultGraphBuilderSuite(), OptimisticOptimizations.ALL); new InliningPhase(new CanonicalizerPhase(true)).apply(graph, context); new DeadCodeEliminationPhase().apply(graph); diff -r 64e6c7b83515 -r f10ca512eb40 graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/tutorial/StaticAnalysis.java --- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/tutorial/StaticAnalysis.java Wed Feb 04 16:34:07 2015 -0800 +++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/tutorial/StaticAnalysis.java Wed Feb 04 16:38:09 2015 -0800 @@ -238,7 +238,7 @@ OptimisticOptimizations optimisticOpts = OptimisticOptimizations.NONE; Assumptions assumptions = new Assumptions(false); - GraphBuilderPhase.Instance graphBuilder = new GraphBuilderPhase.Instance(metaAccess, stampProvider, assumptions, graphBuilderConfig, optimisticOpts); + GraphBuilderPhase.Instance graphBuilder = new GraphBuilderPhase.Instance(metaAccess, stampProvider, assumptions, null, graphBuilderConfig, optimisticOpts); graphBuilder.apply(graph); } catch (Throwable ex) { Debug.handle(ex); diff -r 64e6c7b83515 -r f10ca512eb40 graal/com.oracle.graal.graph/src/com/oracle/graal/graph/NodeClass.java --- a/graal/com.oracle.graal.graph/src/com/oracle/graal/graph/NodeClass.java Wed Feb 04 16:34:07 2015 -0800 +++ b/graal/com.oracle.graal.graph/src/com/oracle/graal/graph/NodeClass.java Wed Feb 04 16:38:09 2015 -0800 @@ -166,7 +166,7 @@ isLeafNode = inputs.getCount() + successors.getCount() == 0; canGVN = Node.ValueNumberable.class.isAssignableFrom(clazz); - startGVNNumber = clazz.hashCode(); + startGVNNumber = clazz.getName().hashCode(); NodeInfo info = getAnnotationTimed(clazz, NodeInfo.class); assert info != null : "Missing NodeInfo annotation on " + clazz; diff -r 64e6c7b83515 -r f10ca512eb40 graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotLIRGenerator.java --- a/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotLIRGenerator.java Wed Feb 04 16:34:07 2015 -0800 +++ b/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotLIRGenerator.java Wed Feb 04 16:38:09 2015 -0800 @@ -527,7 +527,7 @@ } } - public Value emitCompareAndSwap(Value address, Value expectedValue, Value newValue, Value trueValue, Value falseValue) { + public Variable emitCompareAndSwap(Value address, Value expectedValue, Value newValue, Value trueValue, Value falseValue) { LIRKind kind = newValue.getLIRKind(); assert kind.equals(expectedValue.getLIRKind()); Kind memKind = (Kind) kind.getPlatformKind(); diff -r 64e6c7b83515 -r f10ca512eb40 graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotLIRGenerator.java --- a/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotLIRGenerator.java Wed Feb 04 16:34:07 2015 -0800 +++ b/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotLIRGenerator.java Wed Feb 04 16:38:09 2015 -0800 @@ -220,7 +220,7 @@ append(new StoreOp((Kind) kind.getPlatformKind(), storeAddress, input, state)); } - public Value emitCompareAndSwap(Value address, Value expectedValue, Value newValue, Value trueValue, Value falseValue) { + public Variable emitCompareAndSwap(Value address, Value expectedValue, Value newValue, Value trueValue, Value falseValue) { Variable newValueTemp = newVariable(newValue.getLIRKind()); emitMove(newValueTemp, newValue); diff -r 64e6c7b83515 -r f10ca512eb40 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/CurrentLockNode.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/CurrentLockNode.java Wed Feb 04 16:34:07 2015 -0800 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/CurrentLockNode.java Wed Feb 04 16:38:09 2015 -0800 @@ -49,7 +49,7 @@ HotSpotLIRGenerator hsGen = (HotSpotLIRGenerator) gen.getLIRGeneratorTool(); StackSlotValue slot = hsGen.getLockSlot(lockDepth); // The register allocator cannot handle stack -> register moves so we use an LEA here - Value result = gen.getLIRGeneratorTool().emitMove(gen.getLIRGeneratorTool().emitAddress(slot)); + Value result = gen.getLIRGeneratorTool().emitAddress(slot); gen.setResult(this, result); } diff -r 64e6c7b83515 -r f10ca512eb40 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/HotSpotGraphBuilderPluginsProvider.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/HotSpotGraphBuilderPluginsProvider.java Wed Feb 04 16:34:07 2015 -0800 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/HotSpotGraphBuilderPluginsProvider.java Wed Feb 04 16:38:09 2015 -0800 @@ -25,6 +25,9 @@ import com.oracle.graal.api.meta.*; import com.oracle.graal.api.runtime.*; import com.oracle.graal.java.*; +import com.oracle.graal.java.GraphBuilderPlugins.InvocationPlugin; +import com.oracle.graal.java.GraphBuilderPlugins.Registration; +import com.oracle.graal.java.GraphBuilderPlugins.Registration.Receiver; import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.extended.*; import com.oracle.graal.nodes.spi.*; @@ -35,17 +38,9 @@ @ServiceProvider(GraphBuilderPluginsProvider.class) public class HotSpotGraphBuilderPluginsProvider implements GraphBuilderPluginsProvider { public void registerPlugins(MetaAccessProvider metaAccess, GraphBuilderPlugins plugins) { - plugins.register(metaAccess, ObjectPlugin.class); - } - - /** - * HotSpot specific plugins for {@link Object}. - */ - enum ObjectPlugin implements GraphBuilderPlugin { - getClass() { - public boolean handleInvocation(GraphBuilderContext builder, ValueNode[] args) { - assert args.length == 1; - ValueNode rcvr = args[0]; + Registration r = new Registration(plugins, metaAccess, Object.class); + r.register1("getClass", Receiver.class, new InvocationPlugin() { + public boolean apply(GraphBuilderContext builder, ValueNode rcvr) { GuardingPiNode pi = builder.append(new GuardingPiNode(rcvr)); StampProvider stampProvider = builder.getStampProvider(); LoadHubNode hub = builder.append(new LoadHubNode(stampProvider, pi)); @@ -53,10 +48,6 @@ builder.push(Kind.Object, mirror); return true; } - }; - - public ResolvedJavaMethod getInvocationTarget(MetaAccessProvider metaAccess) { - return GraphBuilderPlugin.resolveTarget(metaAccess, Object.class, name()); - } + }); } } diff -r 64e6c7b83515 -r f10ca512eb40 graal/com.oracle.graal.java/src/com/oracle/graal/java/AbstractBytecodeParser.java --- a/graal/com.oracle.graal.java/src/com/oracle/graal/java/AbstractBytecodeParser.java Wed Feb 04 16:34:07 2015 -0800 +++ b/graal/com.oracle.graal.java/src/com/oracle/graal/java/AbstractBytecodeParser.java Wed Feb 04 16:38:09 2015 -0800 @@ -36,6 +36,7 @@ import com.oracle.graal.compiler.common.calc.*; import com.oracle.graal.debug.*; import com.oracle.graal.java.BciBlockMapping.BciBlock; +import com.oracle.graal.nodes.*; import com.oracle.graal.options.*; import com.oracle.graal.phases.*; @@ -687,7 +688,10 @@ Kind kind = field.getKind(); T receiver = frameState.apop(); if ((field instanceof ResolvedJavaField) && ((ResolvedJavaField) field).getDeclaringClass().isInitialized()) { - appendOptimizedLoadField(kind, genLoadField(receiver, (ResolvedJavaField) field)); + GraphBuilderPlugins.LoadFieldPlugin loadFieldPlugin = this.graphBuilderConfig.getLoadFieldPlugin(); + if (loadFieldPlugin == null || !loadFieldPlugin.apply((GraphBuilderContext) this, (ValueNode) receiver, (ResolvedJavaField) field)) { + appendOptimizedLoadField(kind, genLoadField(receiver, (ResolvedJavaField) field)); + } } else { handleUnresolvedLoadField(field, receiver); } diff -r 64e6c7b83515 -r f10ca512eb40 graal/com.oracle.graal.java/src/com/oracle/graal/java/DefaultGraphBuilderPlugins.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.java/src/com/oracle/graal/java/DefaultGraphBuilderPlugins.java Wed Feb 04 16:38:09 2015 -0800 @@ -0,0 +1,62 @@ +/* + * 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 com.oracle.graal.java; + +import java.util.*; +import java.util.stream.*; + +import com.oracle.graal.api.meta.*; + +/** + * Default implementation of {@link GraphBuilderPlugins} that uses a map. + */ +public class DefaultGraphBuilderPlugins implements GraphBuilderPlugins { + + private final Map plugins = new HashMap<>(); + + /** + * Registers an invocation plugin for a given method. There must be no plugin currently + * registered for {@code method}. + */ + public void register(ResolvedJavaMethod method, InvocationPlugin plugin) { + assert InvocationPluginChecker.check(method, plugin); + GraphBuilderPlugin oldValue = plugins.put(method, plugin); + // System.out.println("registered: " + plugin); + assert oldValue == null; + } + + /** + * Gets the plugin for a given method. + * + * @param method the method to lookup + * @return the plugin associated with {@code method} or {@code null} if none exists + */ + public InvocationPlugin lookupInvocation(ResolvedJavaMethod method) { + return plugins.get(method); + } + + @Override + public String toString() { + return plugins.keySet().stream().map(m -> m.format("%H.%n(%p)")).collect(Collectors.joining(", ")); + } +} diff -r 64e6c7b83515 -r f10ca512eb40 graal/com.oracle.graal.java/src/com/oracle/graal/java/DefaultGraphBuilderPluginsProvider.java --- a/graal/com.oracle.graal.java/src/com/oracle/graal/java/DefaultGraphBuilderPluginsProvider.java Wed Feb 04 16:34:07 2015 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,110 +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 com.oracle.graal.java; - -import com.oracle.graal.api.meta.*; -import com.oracle.graal.api.runtime.*; -import com.oracle.graal.nodes.*; -import com.oracle.graal.nodes.extended.*; -import com.oracle.graal.nodes.java.*; - -/** - * Provider of non-runtime specific {@link GraphBuilderPlugin}s. - */ -@ServiceProvider(GraphBuilderPluginsProvider.class) -public class DefaultGraphBuilderPluginsProvider implements GraphBuilderPluginsProvider { - public void registerPlugins(MetaAccessProvider metaAccess, GraphBuilderPlugins plugins) { - plugins.register(metaAccess, ObjectPlugin.class); - plugins.register(metaAccess, BoxingPlugin.class); - } - - /** - * Plugins for {@link Object}. - */ - enum ObjectPlugin implements GraphBuilderPlugin { - init() { - public boolean handleInvocation(GraphBuilderContext builder, ValueNode[] args) { - ValueNode object = args[0]; - if (RegisterFinalizerNode.mayHaveFinalizer(object, builder.getAssumptions())) { - builder.append(new RegisterFinalizerNode(object)); - } - return true; - } - - public ResolvedJavaMethod getInvocationTarget(MetaAccessProvider metaAccess) { - return GraphBuilderPlugin.resolveTarget(metaAccess, Object.class, ""); - } - }; - - @Override - public String toString() { - return Object.class.getName() + "." + name() + "()"; - } - } - - /** - * Plugins for the standard primitive box classes (e.g., {@link Integer} and friends). - */ - enum BoxingPlugin implements GraphBuilderPlugin { - valueOf$Boolean(Kind.Boolean), - booleanValue$Boolean(Kind.Boolean), - valueOf$Byte(Kind.Byte), - byteValue$Byte(Kind.Byte), - valueOf$Short(Kind.Short), - shortValue$Short(Kind.Short), - valueOf$Char(Kind.Char), - charValue$Char(Kind.Char), - valueOf$Int(Kind.Int), - intValue$Int(Kind.Int), - valueOf$Long(Kind.Long), - longValue$Long(Kind.Long), - valueOf$Float(Kind.Float), - floatValue$Float(Kind.Float), - valueOf$Double(Kind.Double), - doubleValue$Double(Kind.Double); - - BoxingPlugin(Kind kind) { - assert name().startsWith("valueOf$") || name().startsWith(kind.getJavaName() + "Value$"); - this.kind = kind; - this.box = name().charAt(0) == 'v'; - } - - private final Kind kind; - private final boolean box; - - public final boolean handleInvocation(GraphBuilderContext builder, ValueNode[] args) { - if (box) { - ResolvedJavaType resultType = builder.getMetaAccess().lookupJavaType(kind.toBoxedJavaClass()); - builder.push(Kind.Object, builder.append(new BoxNode(args[0], resultType, kind))); - } else { - builder.push(kind, builder.append(new UnboxNode(args[0], kind))); - } - return true; - } - - public ResolvedJavaMethod getInvocationTarget(MetaAccessProvider metaAccess) { - Class[] parameterTypes = box ? new Class[]{kind.toJavaClass()} : new Class[0]; - return GraphBuilderPlugin.resolveTarget(metaAccess, kind.toBoxedJavaClass(), name(), parameterTypes); - } - } -} diff -r 64e6c7b83515 -r f10ca512eb40 graal/com.oracle.graal.java/src/com/oracle/graal/java/GraalDirectivePlugins.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.java/src/com/oracle/graal/java/GraalDirectivePlugins.java Wed Feb 04 16:38:09 2015 -0800 @@ -0,0 +1,106 @@ +/* + * Copyright (c) 2015, 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 com.oracle.graal.java; + +import com.oracle.graal.api.directives.*; +import com.oracle.graal.api.meta.*; +import com.oracle.graal.java.GraphBuilderPlugins.InvocationPlugin; +import com.oracle.graal.java.GraphBuilderPlugins.Registration; +import com.oracle.graal.nodes.*; +import com.oracle.graal.nodes.debug.*; +import com.oracle.graal.nodes.extended.*; + +public class GraalDirectivePlugins { + + private static ResolvedJavaMethod lookup(MetaAccessProvider metaAccess, String name, Class... parameterTypes) { + return Registration.resolve(metaAccess, GraalDirectives.class, name, parameterTypes); + } + + public static void registerPlugins(MetaAccessProvider metaAccess, GraphBuilderPlugins plugins) { + plugins.register(lookup(metaAccess, "deoptimize"), new InvocationPlugin() { + public boolean apply(GraphBuilderContext builder) { + builder.append(new DeoptimizeNode(DeoptimizationAction.None, DeoptimizationReason.TransferToInterpreter)); + return true; + } + }); + + plugins.register(lookup(metaAccess, "deoptimizeAndInvalidate"), new InvocationPlugin() { + public boolean apply(GraphBuilderContext builder) { + builder.append(new DeoptimizeNode(DeoptimizationAction.InvalidateReprofile, DeoptimizationReason.TransferToInterpreter)); + return true; + } + }); + + plugins.register(lookup(metaAccess, "inCompiledCode"), new InvocationPlugin() { + public boolean apply(GraphBuilderContext builder) { + builder.push(Kind.Int, builder.append(ConstantNode.forInt(1))); + return true; + } + }); + + plugins.register(lookup(metaAccess, "controlFlowAnchor"), new InvocationPlugin() { + public boolean apply(GraphBuilderContext builder) { + builder.append(new ControlFlowAnchorNode()); + return true; + } + }); + + plugins.register(lookup(metaAccess, "injectBranchProbability", double.class, boolean.class), new InvocationPlugin() { + public boolean apply(GraphBuilderContext builder, ValueNode probability, ValueNode condition) { + builder.push(Kind.Int, builder.append(new BranchProbabilityNode(probability, condition))); + return true; + } + }); + + InvocationPlugin blackholePlugin = new InvocationPlugin() { + public boolean apply(GraphBuilderContext builder, ValueNode value) { + builder.append(new BlackholeNode(value)); + return true; + } + }; + + for (Kind kind : Kind.values()) { + Class cls = null; + switch (kind) { + case Object: + cls = Object.class; + break; + case Void: + case Illegal: + continue; + default: + cls = kind.toJavaClass(); + } + + plugins.register(lookup(metaAccess, "blackhole", cls), blackholePlugin); + + final Kind stackKind = kind.getStackKind(); + plugins.register(lookup(metaAccess, "opaque", cls), new InvocationPlugin() { + public boolean apply(GraphBuilderContext builder, ValueNode value) { + builder.push(stackKind, builder.append(new OpaqueNode(value))); + return true; + } + }); + } + } +} diff -r 64e6c7b83515 -r f10ca512eb40 graal/com.oracle.graal.java/src/com/oracle/graal/java/GraphBuilderConfiguration.java --- a/graal/com.oracle.graal.java/src/com/oracle/graal/java/GraphBuilderConfiguration.java Wed Feb 04 16:34:07 2015 -0800 +++ b/graal/com.oracle.graal.java/src/com/oracle/graal/java/GraphBuilderConfiguration.java Wed Feb 04 16:38:09 2015 -0800 @@ -37,6 +37,8 @@ private final DebugInfoMode debugInfoMode; private final boolean doLivenessAnalysis; private final boolean inlineTrivial; + private GraphBuilderPlugins.LoadFieldPlugin loadFieldPlugin; + private GraphBuilderPlugins.ParameterPlugin parameterPlugin; public static enum DebugInfoMode { SafePointsOnly, @@ -72,6 +74,12 @@ this.inlineTrivial = inlineTrivial; } + public GraphBuilderConfiguration copy() { + GraphBuilderConfiguration result = new GraphBuilderConfiguration(eagerResolving, omitAllExceptionEdges, debugInfoMode, skippedExceptionTypes, doLivenessAnalysis, inlineTrivial); + result.loadFieldPlugin = loadFieldPlugin; + return result; + } + public GraphBuilderConfiguration withSkippedExceptionTypes(ResolvedJavaType[] newSkippedExceptionTypes) { return new GraphBuilderConfiguration(eagerResolving, omitAllExceptionEdges, debugInfoMode, newSkippedExceptionTypes, doLivenessAnalysis, inlineTrivial); } @@ -93,6 +101,14 @@ return new GraphBuilderConfiguration(eagerResolving, omitAllExceptionEdges, debugInfoMode, skippedExceptionTypes, doLivenessAnalysis, newInlineTrivial); } + public GraphBuilderPlugins.LoadFieldPlugin getLoadFieldPlugin() { + return loadFieldPlugin; + } + + public void setLoadFieldPlugin(GraphBuilderPlugins.LoadFieldPlugin loadFieldPlugin) { + this.loadFieldPlugin = loadFieldPlugin; + } + public ResolvedJavaType[] getSkippedExceptionTypes() { return skippedExceptionTypes; } @@ -145,4 +161,12 @@ public boolean shouldInlineTrivial() { return inlineTrivial; } + + public GraphBuilderPlugins.ParameterPlugin getParameterPlugin() { + return parameterPlugin; + } + + public void setParameterPlugin(GraphBuilderPlugins.ParameterPlugin parameterPlugin) { + this.parameterPlugin = parameterPlugin; + } } diff -r 64e6c7b83515 -r f10ca512eb40 graal/com.oracle.graal.java/src/com/oracle/graal/java/GraphBuilderPhase.java --- a/graal/com.oracle.graal.java/src/com/oracle/graal/java/GraphBuilderPhase.java Wed Feb 04 16:34:07 2015 -0800 +++ b/graal/com.oracle.graal.java/src/com/oracle/graal/java/GraphBuilderPhase.java Wed Feb 04 16:38:09 2015 -0800 @@ -42,6 +42,7 @@ import com.oracle.graal.java.BciBlockMapping.BciBlock; import com.oracle.graal.java.BciBlockMapping.ExceptionDispatchBlock; import com.oracle.graal.java.BciBlockMapping.LocalLiveness; +import com.oracle.graal.java.GraphBuilderPlugins.InvocationPlugin; import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.CallTargetNode.InvokeKind; import com.oracle.graal.nodes.calc.*; @@ -62,13 +63,18 @@ private final GraphBuilderPlugins graphBuilderPlugins; public GraphBuilderPhase(GraphBuilderConfiguration config) { + this(config, new DefaultGraphBuilderPlugins()); + } + + public GraphBuilderPhase(GraphBuilderConfiguration config, GraphBuilderPlugins graphBuilderPlugins) { this.graphBuilderConfig = config; - this.graphBuilderPlugins = new GraphBuilderPlugins(); + this.graphBuilderPlugins = graphBuilderPlugins; } @Override protected void run(StructuredGraph graph, HighTierContext context) { - new Instance(context.getMetaAccess(), context.getStampProvider(), context.getAssumptions(), graphBuilderConfig, graphBuilderPlugins, context.getOptimisticOptimizations()).run(graph); + new Instance(context.getMetaAccess(), context.getStampProvider(), context.getAssumptions(), context.getConstantReflection(), graphBuilderConfig, graphBuilderPlugins, + context.getOptimisticOptimizations()).run(graph); } public GraphBuilderConfiguration getGraphBuilderConfig() { @@ -92,6 +98,7 @@ private final OptimisticOptimizations optimisticOpts; private final StampProvider stampProvider; private final Assumptions assumptions; + private final ConstantReflectionProvider constantReflectionProvider; /** * Gets the graph being processed by this builder. @@ -100,19 +107,21 @@ return currentGraph; } - public Instance(MetaAccessProvider metaAccess, StampProvider stampProvider, Assumptions assumptions, GraphBuilderConfiguration graphBuilderConfig, GraphBuilderPlugins graphBuilderPlugins, - OptimisticOptimizations optimisticOpts) { + public Instance(MetaAccessProvider metaAccess, StampProvider stampProvider, Assumptions assumptions, ConstantReflectionProvider constantReflectionProvider, + GraphBuilderConfiguration graphBuilderConfig, GraphBuilderPlugins graphBuilderPlugins, OptimisticOptimizations optimisticOpts) { this.graphBuilderConfig = graphBuilderConfig; this.optimisticOpts = optimisticOpts; this.metaAccess = metaAccess; this.stampProvider = stampProvider; this.assumptions = assumptions; this.graphBuilderPlugins = graphBuilderPlugins; + this.constantReflectionProvider = constantReflectionProvider; assert metaAccess != null; } - public Instance(MetaAccessProvider metaAccess, StampProvider stampProvider, Assumptions assumptions, GraphBuilderConfiguration graphBuilderConfig, OptimisticOptimizations optimisticOpts) { - this(metaAccess, stampProvider, assumptions, graphBuilderConfig, null, optimisticOpts); + public Instance(MetaAccessProvider metaAccess, StampProvider stampProvider, Assumptions assumptions, ConstantReflectionProvider constantReflectionProvider, + GraphBuilderConfiguration graphBuilderConfig, OptimisticOptimizations optimisticOpts) { + this(metaAccess, stampProvider, assumptions, constantReflectionProvider, graphBuilderConfig, null, optimisticOpts); } @Override @@ -123,7 +132,7 @@ assert method.getCode() != null : "method must contain bytecodes: " + method; this.currentGraph = graph; HIRFrameStateBuilder frameState = new HIRFrameStateBuilder(method, graph, null); - frameState.initializeForMethodStart(graphBuilderConfig.eagerResolving()); + frameState.initializeForMethodStart(graphBuilderConfig.eagerResolving(), this.graphBuilderConfig.getParameterPlugin()); TTY.Filter filter = new TTY.Filter(PrintFilter.getValue(), method); try { BytecodeParser parser = new BytecodeParser(metaAccess, method, graphBuilderConfig, optimisticOpts, entryBCI); @@ -557,7 +566,7 @@ @Override protected ValueNode genObjectEquals(ValueNode x, ValueNode y) { - return new ObjectEqualsNode(x, y); + return ObjectEqualsNode.create(x, y, constantReflectionProvider); } @Override @@ -773,11 +782,10 @@ if (GraalOptions.InlineDuringParsing.getValue() && invokeKind.isDirect()) { if (graphBuilderPlugins != null) { - GraphBuilderPlugin plugin = graphBuilderPlugins.getPlugin(targetMethod); + InvocationPlugin plugin = graphBuilderPlugins.lookupInvocation(targetMethod); if (plugin != null) { int beforeStackSize = frameState.stackSize; - if (plugin.handleInvocation(this, args)) { - // System.out.println("used plugin: " + plugin); + if (plugin.apply(this, args)) { assert beforeStackSize + resultType.getSlotCount() == frameState.stackSize; return; } @@ -998,7 +1006,6 @@ } public T append(T v) { - assert !(v instanceof ConstantNode); T added = currentGraph.unique(v); return added; } @@ -1482,11 +1489,24 @@ } condition = genUnique(condition); - ValueNode trueSuccessor = createBlockTarget(probability, trueBlock, frameState); - ValueNode falseSuccessor = createBlockTarget(1 - probability, falseBlock, frameState); + if (condition instanceof LogicConstantNode) { + LogicConstantNode constantLogicNode = (LogicConstantNode) condition; + boolean value = constantLogicNode.getValue(); + if (negate) { + value = !value; + } + BciBlock nextBlock = falseBlock; + if (value) { + nextBlock = trueBlock; + } + appendGoto(createTarget(nextBlock, frameState)); + } else { + ValueNode trueSuccessor = createBlockTarget(probability, trueBlock, frameState); + ValueNode falseSuccessor = createBlockTarget(1 - probability, falseBlock, frameState); - ValueNode ifNode = negate ? genIfNode(condition, falseSuccessor, trueSuccessor, 1 - probability) : genIfNode(condition, trueSuccessor, falseSuccessor, probability); - append(ifNode); + ValueNode ifNode = negate ? genIfNode(condition, falseSuccessor, trueSuccessor, 1 - probability) : genIfNode(condition, trueSuccessor, falseSuccessor, probability); + append(ifNode); + } } public StampProvider getStampProvider() { diff -r 64e6c7b83515 -r f10ca512eb40 graal/com.oracle.graal.java/src/com/oracle/graal/java/GraphBuilderPlugin.java --- a/graal/com.oracle.graal.java/src/com/oracle/graal/java/GraphBuilderPlugin.java Wed Feb 04 16:34:07 2015 -0800 +++ b/graal/com.oracle.graal.java/src/com/oracle/graal/java/GraphBuilderPlugin.java Wed Feb 04 16:38:09 2015 -0800 @@ -22,43 +22,14 @@ */ package com.oracle.graal.java; -import com.oracle.graal.api.meta.*; -import com.oracle.graal.compiler.common.*; -import com.oracle.graal.nodes.*; - /** - * Extensions for handling certain bytecode instructions while building a - * {@linkplain StructuredGraph graph} from a bytecode stream. + * Marker interface for graph builder plugins. + * + * Concrete plugins implement one of the sub-interfaces of this interface. + * + * @see GraphBuilderPluginsProvider + * @see GraphBuilderPlugins + * @see GraphBuilderPlugins.Registration */ public interface GraphBuilderPlugin { - - /** - * Processes an invocation parsed in a bytecode stream and add nodes to a graph being - * constructed that implement the semantics of the invocation. - * - * @param builder object being used to build a graph - * @param args the arguments to the invocation - */ - boolean handleInvocation(GraphBuilderContext builder, ValueNode[] args); - - /** - * Gets the method handled by {@link #handleInvocation(GraphBuilderContext, ValueNode[])} . - */ - ResolvedJavaMethod getInvocationTarget(MetaAccessProvider metaAccess); - - /** - * Looks up a {@link ResolvedJavaMethod}. - * - * @param methodNameBase the name of the method is the prefix of this value up to the first '$' - * character - */ - static ResolvedJavaMethod resolveTarget(MetaAccessProvider metaAccess, Class declaringClass, String methodNameBase, Class... parameterTypes) { - int index = methodNameBase.indexOf('$'); - String methodName = index == -1 ? methodNameBase : methodNameBase.substring(0, index); - try { - return metaAccess.lookupJavaMethod(methodName.equals("") ? declaringClass.getDeclaredConstructor(parameterTypes) : declaringClass.getDeclaredMethod(methodName, parameterTypes)); - } catch (NoSuchMethodException | SecurityException e) { - throw new GraalInternalError(e); - } - } } diff -r 64e6c7b83515 -r f10ca512eb40 graal/com.oracle.graal.java/src/com/oracle/graal/java/GraphBuilderPlugins.java --- a/graal/com.oracle.graal.java/src/com/oracle/graal/java/GraphBuilderPlugins.java Wed Feb 04 16:34:07 2015 -0800 +++ b/graal/com.oracle.graal.java/src/com/oracle/graal/java/GraphBuilderPlugins.java Wed Feb 04 16:38:09 2015 -0800 @@ -22,45 +22,225 @@ */ package com.oracle.graal.java; +import static java.lang.String.*; + +import java.lang.reflect.*; import java.util.*; -import java.util.stream.*; import com.oracle.graal.api.meta.*; +import com.oracle.graal.compiler.common.*; +import com.oracle.graal.nodes.*; +import com.oracle.graal.nodes.calc.*; /** - * A repository of {@link GraphBuilderPlugin}s. + * Interface for managing a set of graph builder {@link GraphBuilderPlugin}s. */ -public class GraphBuilderPlugins { +public interface GraphBuilderPlugins { - private final Map map = new HashMap<>(); + public interface LoadFieldPlugin extends GraphBuilderPlugin { + boolean apply(GraphBuilderContext builder, ValueNode receiver, ResolvedJavaField field); + } + + public interface ParameterPlugin extends GraphBuilderPlugin { + FloatingNode interceptParameter(int index); + } /** - * Registers all the constants of an enum that implements {@link GraphBuilderPlugin}. + * Plugin for handling a method invocation. */ - public & GraphBuilderPlugin> void register(MetaAccessProvider metaAccess, Class enumClass) { - assert Enum.class.isAssignableFrom(enumClass); - Object[] enumConstants = enumClass.getEnumConstants(); - for (Object o : enumConstants) { - GraphBuilderPlugin gbp = (GraphBuilderPlugin) o; - ResolvedJavaMethod target = gbp.getInvocationTarget(metaAccess); - GraphBuilderPlugin oldValue = map.put(target, gbp); - // System.out.println("registered: " + gbp); - assert oldValue == null; + public interface InvocationPlugin extends GraphBuilderPlugin { + /** + * Tries to handle an invocation to a method with no arguments. + * + * @return {@code true} this plugin handled the invocation + */ + default boolean apply(GraphBuilderContext builder) { + throw invalidHandler(builder); + } + + /** + * Tries to handle an invocation to a method with one argument. + * + * @return {@code true} this plugin handled the invocation + */ + default boolean apply(GraphBuilderContext builder, ValueNode arg) { + throw invalidHandler(builder, arg); + } + + /** + * Tries to handle an invocation to a method with two arguments. + * + * @return {@code true} this plugin handled the invocation + */ + default boolean apply(GraphBuilderContext builder, ValueNode arg1, ValueNode arg2) { + throw invalidHandler(builder, arg1, arg2); + } + + /** + * Tries to handle an invocation to a method with three arguments. + * + * @return {@code true} this plugin handled the invocation + */ + default boolean apply(GraphBuilderContext builder, ValueNode arg1, ValueNode arg2, ValueNode arg3) { + throw invalidHandler(builder, arg1, arg2, arg3); + } + + default boolean apply(GraphBuilderContext builder, ValueNode[] args) { + if (args.length == 0) { + return apply(builder); + } else if (args.length == 1) { + return apply(builder, args[0]); + } else if (args.length == 2) { + return apply(builder, args[0], args[1]); + } else if (args.length == 3) { + return apply(builder, args[0], args[1], args[2]); + } else { + throw invalidHandler(builder, args); + } + } + + default Error invalidHandler(@SuppressWarnings("unused") GraphBuilderContext builder, ValueNode... args) { + return new GraalInternalError("Invocation plugin %s does not handle invocations with %d arguments", getClass().getSimpleName(), args.length); } } /** - * Gets the plugin for a given method registered in the object. + * Utility for {@linkplain GraphBuilderPlugins#register(ResolvedJavaMethod, InvocationPlugin) + * registration} of plugins. + */ + public static class Registration { + + /** + * Sentinel class for use with {@link Registration#register1}, + * {@link Registration#register2} or {@link Registration#register3} to denote the receiver + * argument for a non-static method. + */ + public static final class Receiver { + private Receiver() { + throw GraalInternalError.shouldNotReachHere(); + } + } + + private final GraphBuilderPlugins plugins; + private final MetaAccessProvider metaAccess; + private final Class declaringClass; + + /** + * Creates an object for registering plugins for methods declared by a given class. + * + * @param plugins where to register the plugins + * @param metaAccess used to resolve classes and methods + * @param declaringClass the class declaring the methods for which plugins will be + * registered via this object + */ + public Registration(GraphBuilderPlugins plugins, MetaAccessProvider metaAccess, Class declaringClass) { + this.plugins = plugins; + this.metaAccess = metaAccess; + this.declaringClass = declaringClass; + } + + /** + * Registers a plugin for a method with no arguments. + * + * @param name the name of the method + * @param plugin the plugin to be registered + */ + public void register0(String name, InvocationPlugin plugin) { + plugins.register(resolve(metaAccess, declaringClass, name), plugin); + } + + /** + * Registers a plugin for a method with 1 argument. + * + * @param name the name of the method + * @param plugin the plugin to be registered + */ + public void register1(String name, Class arg, InvocationPlugin plugin) { + ResolvedJavaMethod method = arg == Receiver.class ? resolve(metaAccess, declaringClass, name) : resolve(metaAccess, declaringClass, name, arg); + plugins.register(method, plugin); + } + + /** + * Registers a plugin for a method with 2 arguments. + * + * @param name the name of the method + * @param plugin the plugin to be registered + */ + public void register2(String name, Class arg1, Class arg2, InvocationPlugin plugin) { + ResolvedJavaMethod method = arg1 == Receiver.class ? resolve(metaAccess, declaringClass, name, arg2) : resolve(metaAccess, declaringClass, name, arg1, arg2); + plugins.register(method, plugin); + } + + /** + * Registers a plugin for a method with 3 arguments. + * + * @param name the name of the method + * @param plugin the plugin to be registered + */ + public void register3(String name, Class arg1, Class arg2, Class arg3, InvocationPlugin plugin) { + ResolvedJavaMethod method = arg1 == Receiver.class ? resolve(metaAccess, declaringClass, name, arg2, arg3) : resolve(metaAccess, declaringClass, name, arg1, arg2, arg3); + plugins.register(method, plugin); + } + + /** + * Resolves a method given a declaring class, name and parameter types. + */ + public static ResolvedJavaMethod resolve(MetaAccessProvider metaAccess, Class declaringClass, String name, Class... parameterTypes) { + try { + return metaAccess.lookupJavaMethod(name.equals("") ? declaringClass.getDeclaredConstructor(parameterTypes) : declaringClass.getDeclaredMethod(name, parameterTypes)); + } catch (NoSuchMethodException | SecurityException e) { + throw new GraalInternalError(e); + } + } + } + + public static class InvocationPluginChecker { + static final Class[] APPLY0 = {GraphBuilderContext.class}; + static final Class[] APPLY1 = {GraphBuilderContext.class, ValueNode.class}; + static final Class[] APPLY2 = {GraphBuilderContext.class, ValueNode.class, ValueNode.class}; + static final Class[] APPLY3 = {GraphBuilderContext.class, ValueNode.class, ValueNode.class, ValueNode.class}; + static final Class[][] SIGS = {APPLY0, APPLY1, APPLY2, APPLY3}; + + public static boolean check(ResolvedJavaMethod method, InvocationPlugin plugin) { + int arguments = method.getSignature().getParameterCount(!method.isStatic()); + assert arguments < SIGS.length : format("need to extend %s to support method with %d arguments: %s", InvocationPlugin.class.getSimpleName(), arguments, method.format("%H.%n(%p)")); + Method expected = null; + for (Method m : plugin.getClass().getDeclaredMethods()) { + if (m.getName().equals("apply")) { + Class[] parameterTypes = m.getParameterTypes(); + assert Arrays.equals(SIGS[arguments], parameterTypes) : format("graph builder plugin for %s has wrong signature%nexpected: (%s)%n actual: (%s)", method.format("%H.%n(%p)"), + sigString(SIGS[arguments]), sigString(m.getParameterTypes())); + expected = m; + } + } + assert expected != null : format("graph builder plugin %s must define exactly one \"apply\" method, none found", plugin); + return true; + } + + protected static String sigString(Class... sig) { + StringBuilder sb = new StringBuilder(); + for (Class t : sig) { + if (sb.length() != 0) { + sb.append(", "); + } + sb.append(t.getSimpleName()); + } + return sb.toString(); + } + + } + + /** + * Registers an {@link InvocationPlugin} for a given method. There must be no plugin currently + * registered for {@code method}. + */ + void register(ResolvedJavaMethod method, InvocationPlugin plugin); + + /** + * Gets the {@link InvocationPlugin} for a given method. * * @param method the method to lookup * @return the plugin associated with {@code method} or {@code null} if none exists */ - public GraphBuilderPlugin getPlugin(ResolvedJavaMethod method) { - return map.get(method); - } - - @Override - public String toString() { - return map.keySet().stream().map(m -> m.format("%H.%n(%p)")).collect(Collectors.joining(", ")); - } + InvocationPlugin lookupInvocation(ResolvedJavaMethod method); } diff -r 64e6c7b83515 -r f10ca512eb40 graal/com.oracle.graal.java/src/com/oracle/graal/java/GraphBuilderPluginsProvider.java --- a/graal/com.oracle.graal.java/src/com/oracle/graal/java/GraphBuilderPluginsProvider.java Wed Feb 04 16:34:07 2015 -0800 +++ b/graal/com.oracle.graal.java/src/com/oracle/graal/java/GraphBuilderPluginsProvider.java Wed Feb 04 16:38:09 2015 -0800 @@ -30,9 +30,7 @@ */ public interface GraphBuilderPluginsProvider extends Service { /** - * Registers the plugins provided by this object with a plugins registry. - * - * @param plugins registry of plugins + * Registers the plugins provided by this object. */ void registerPlugins(MetaAccessProvider metaAccess, GraphBuilderPlugins plugins); } diff -r 64e6c7b83515 -r f10ca512eb40 graal/com.oracle.graal.java/src/com/oracle/graal/java/HIRFrameStateBuilder.java --- a/graal/com.oracle.graal.java/src/com/oracle/graal/java/HIRFrameStateBuilder.java Wed Feb 04 16:34:07 2015 -0800 +++ b/graal/com.oracle.graal.java/src/com/oracle/graal/java/HIRFrameStateBuilder.java Wed Feb 04 16:38:09 2015 -0800 @@ -31,6 +31,7 @@ import com.oracle.graal.api.meta.*; import com.oracle.graal.compiler.common.type.*; import com.oracle.graal.debug.*; +import com.oracle.graal.java.GraphBuilderPlugins.ParameterPlugin; import com.oracle.graal.nodeinfo.*; import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.calc.*; @@ -81,14 +82,20 @@ } } - public final void initializeForMethodStart(boolean eagerResolve) { + public final void initializeForMethodStart(boolean eagerResolve, ParameterPlugin parameterPlugin) { int javaIndex = 0; int index = 0; if (!method.isStatic()) { // add the receiver - ParameterNode receiver = graph.unique(new ParameterNode(javaIndex, StampFactory.declaredNonNull(method.getDeclaringClass()))); - storeLocal(javaIndex, receiver); + FloatingNode receiver = null; + if (parameterPlugin != null) { + receiver = parameterPlugin.interceptParameter(index); + } + if (receiver == null) { + receiver = new ParameterNode(javaIndex, StampFactory.declaredNonNull(method.getDeclaringClass())); + } + storeLocal(javaIndex, graph.unique(receiver)); javaIndex = 1; index = 1; } @@ -107,8 +114,14 @@ } else { stamp = StampFactory.forKind(kind); } - ParameterNode param = graph.unique(new ParameterNode(index, stamp)); - storeLocal(javaIndex, param); + FloatingNode param = null; + if (parameterPlugin != null) { + param = parameterPlugin.interceptParameter(index); + } + if (param == null) { + param = new ParameterNode(index, stamp); + } + storeLocal(javaIndex, graph.unique(param)); javaIndex += kind.getSlotCount(); index++; } diff -r 64e6c7b83515 -r f10ca512eb40 graal/com.oracle.graal.java/src/com/oracle/graal/java/StandardGraphBuilderPluginsProvider.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.java/src/com/oracle/graal/java/StandardGraphBuilderPluginsProvider.java Wed Feb 04 16:38:09 2015 -0800 @@ -0,0 +1,99 @@ +/* + * 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 com.oracle.graal.java; + +import com.oracle.graal.api.meta.*; +import com.oracle.graal.api.runtime.*; +import com.oracle.graal.java.GraphBuilderPlugins.InvocationPlugin; +import com.oracle.graal.java.GraphBuilderPlugins.Registration; +import com.oracle.graal.java.GraphBuilderPlugins.Registration.Receiver; +import com.oracle.graal.nodes.*; +import com.oracle.graal.nodes.extended.*; +import com.oracle.graal.nodes.java.*; + +/** + * Provider of non-runtime specific {@link GraphBuilderPlugin}s. + */ +@ServiceProvider(GraphBuilderPluginsProvider.class) +public class StandardGraphBuilderPluginsProvider implements GraphBuilderPluginsProvider { + public void registerPlugins(MetaAccessProvider metaAccess, GraphBuilderPlugins plugins) { + Registration r = new Registration(plugins, metaAccess, Object.class); + r.register1("", Receiver.class, new InvocationPlugin() { + public boolean apply(GraphBuilderContext builder, ValueNode object) { + if (RegisterFinalizerNode.mayHaveFinalizer(object, builder.getAssumptions())) { + builder.append(new RegisterFinalizerNode(object)); + } + return true; + } + }); + + for (Kind kind : Kind.values()) { + if (kind.isPrimitive() && kind != Kind.Void) { + new BoxPlugin(kind).register(metaAccess, plugins); + new UnboxPlugin(kind).register(metaAccess, plugins); + } + } + + GraalDirectivePlugins.registerPlugins(metaAccess, plugins); + } + + static class BoxPlugin implements InvocationPlugin { + + private final Kind kind; + + BoxPlugin(Kind kind) { + this.kind = kind; + } + + public boolean apply(GraphBuilderContext builder, ValueNode value) { + ResolvedJavaType resultType = builder.getMetaAccess().lookupJavaType(kind.toBoxedJavaClass()); + builder.push(Kind.Object, builder.append(new BoxNode(value, resultType, kind))); + return true; + } + + void register(MetaAccessProvider metaAccess, GraphBuilderPlugins plugins) { + ResolvedJavaMethod method = Registration.resolve(metaAccess, kind.toBoxedJavaClass(), "valueOf", kind.toJavaClass()); + plugins.register(method, this); + } + } + + static class UnboxPlugin implements InvocationPlugin { + + private final Kind kind; + + UnboxPlugin(Kind kind) { + this.kind = kind; + } + + public boolean apply(GraphBuilderContext builder, ValueNode value) { + builder.push(kind, builder.append(new UnboxNode(value, kind))); + return true; + } + + void register(MetaAccessProvider metaAccess, GraphBuilderPlugins plugins) { + String name = kind.toJavaClass().getSimpleName() + "Value"; + ResolvedJavaMethod method = Registration.resolve(metaAccess, kind.toBoxedJavaClass(), name); + plugins.register(method, this); + } + } +} diff -r 64e6c7b83515 -r f10ca512eb40 graal/com.oracle.graal.lir/src/com/oracle/graal/lir/framemap/FrameMapBuilderImpl.java --- a/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/framemap/FrameMapBuilderImpl.java Wed Feb 04 16:34:07 2015 -0800 +++ b/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/framemap/FrameMapBuilderImpl.java Wed Feb 04 16:38:09 2015 -0800 @@ -22,13 +22,19 @@ */ package com.oracle.graal.lir.framemap; +import static com.oracle.graal.api.code.ValueUtil.*; + import java.util.*; import com.oracle.graal.api.code.*; import com.oracle.graal.api.meta.*; import com.oracle.graal.compiler.common.*; +import com.oracle.graal.compiler.common.cfg.*; import com.oracle.graal.debug.*; import com.oracle.graal.debug.Debug.Scope; +import com.oracle.graal.lir.*; +import com.oracle.graal.lir.LIRInstruction.OperandFlag; +import com.oracle.graal.lir.LIRInstruction.OperandMode; import com.oracle.graal.lir.gen.*; import com.oracle.graal.lir.stackslotalloc.*; @@ -95,6 +101,9 @@ public FrameMap buildFrameMap(LIRGenerationResult res, StackSlotAllocator allocator) { try (Scope s = Debug.scope("StackSlotAllocation")) { allocator.allocateStackSlots(this, res); + if (Debug.isEnabled()) { + verifyStackSlotAllocation(res); + } } for (CallingConvention cc : calls) { frameMap.callsMethod(cc); @@ -103,6 +112,23 @@ return frameMap; } + private static void verifyStackSlotAllocation(LIRGenerationResult res) { + LIR lir = res.getLIR(); + InstructionValueConsumer verifySlots = (LIRInstruction op, Value value, OperandMode mode, EnumSet flags) -> { + assert !isVirtualStackSlot(value) : String.format("Instruction %s contains a virtual stack slot %s", op, value); + }; + for (AbstractBlock block : lir.getControlFlowGraph().getBlocks()) { + lir.getLIRforBlock(block).forEach(op -> { + op.visitEachInput(verifySlots); + op.visitEachAlive(verifySlots); + op.visitEachState(verifySlots); + + op.visitEachTemp(verifySlots); + op.visitEachOutput(verifySlots); + }); + } + } + public List getStackSlots() { return stackSlots; } diff -r 64e6c7b83515 -r f10ca512eb40 graal/com.oracle.graal.lir/src/com/oracle/graal/lir/gen/LIRGenerator.java --- a/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/gen/LIRGenerator.java Wed Feb 04 16:34:07 2015 -0800 +++ b/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/gen/LIRGenerator.java Wed Feb 04 16:38:09 2015 -0800 @@ -119,6 +119,7 @@ @Override public Variable emitMove(Value input) { + assert !(input instanceof Variable) : "Creating a copy of a variable via this method is not supported (and potentially a bug): " + input; Variable result = newVariable(input.getLIRKind()); emitMove(result, input); return result; diff -r 64e6c7b83515 -r f10ca512eb40 graal/com.oracle.graal.lir/src/com/oracle/graal/lir/gen/LIRGeneratorTool.java --- a/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/gen/LIRGeneratorTool.java Wed Feb 04 16:34:07 2015 -0800 +++ b/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/gen/LIRGeneratorTool.java Wed Feb 04 16:38:09 2015 -0800 @@ -54,13 +54,13 @@ Value emitLoadConstant(LIRKind kind, Constant constant); - Value emitLoad(LIRKind kind, Value address, LIRFrameState state); + Variable emitLoad(LIRKind kind, Value address, LIRFrameState state); void emitStore(LIRKind kind, Value address, Value input, LIRFrameState state); void emitNullCheck(Value address, LIRFrameState state); - Value emitCompareAndSwap(Value address, Value expectedValue, Value newValue, Value trueValue, Value falseValue); + Variable emitCompareAndSwap(Value address, Value expectedValue, Value newValue, Value trueValue, Value falseValue); /** * Emit an atomic read-and-add instruction. @@ -112,7 +112,7 @@ Value emitAddress(Value base, long displacement, Value index, int scale); - Value emitAddress(StackSlotValue slot); + Variable emitAddress(StackSlotValue slot); void emitMembar(int barriers); @@ -179,15 +179,15 @@ CallingConvention getCallingConvention(); - Value emitBitCount(Value operand); + Variable emitBitCount(Value operand); - Value emitBitScanForward(Value operand); + Variable emitBitScanForward(Value operand); - Value emitBitScanReverse(Value operand); + Variable emitBitScanReverse(Value operand); - Value emitByteSwap(Value operand); + Variable emitByteSwap(Value operand); - Value emitArrayEquals(Kind kind, Value array1, Value array2, Value length); + Variable emitArrayEquals(Kind kind, Value array1, Value array2, Value length); void emitBlackhole(Value operand); diff -r 64e6c7b83515 -r f10ca512eb40 graal/com.oracle.graal.lir/src/com/oracle/graal/lir/stackslotalloc/FixPointIntervalBuilder.java --- a/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/stackslotalloc/FixPointIntervalBuilder.java Wed Feb 04 16:34:07 2015 -0800 +++ b/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/stackslotalloc/FixPointIntervalBuilder.java Wed Feb 04 16:38:09 2015 -0800 @@ -43,6 +43,7 @@ private final LIR lir; private final int maxOpId; private final StackInterval[] stackSlotMap; + private final HashSet usePos; /** * The number of allocated stack slots. @@ -55,9 +56,15 @@ this.maxOpId = maxOpId; liveInMap = new BlockMap<>(lir.getControlFlowGraph()); liveOutMap = new BlockMap<>(lir.getControlFlowGraph()); + this.usePos = new HashSet<>(); } - void build() { + /** + * Builds the lifetime intervals for {@link VirtualStackSlot virtual stack slots}, sets up + * {@link #stackSlotMap} and returns a set of use positions, i.e. instructions that contain + * virtual stack slots. + */ + Set build() { Deque> worklist = new ArrayDeque<>(); for (int i = lir.getControlFlowGraph().getBlocks().size() - 1; i >= 0; i--) { worklist.add(lir.getControlFlowGraph().getBlocks().get(i)); @@ -69,6 +76,7 @@ AbstractBlock block = worklist.poll(); processBlock(block, worklist); } + return usePos; } /** @@ -188,6 +196,7 @@ if (isVirtualStackSlot(operand)) { VirtualStackSlot vslot = asVirtualStackSlot(operand); addUse(vslot, inst, flags); + usePos.add(inst); Debug.log("set operand: %s", operand); currentSet.set(vslot.getId()); } @@ -206,6 +215,7 @@ if (isVirtualStackSlot(operand)) { VirtualStackSlot vslot = asVirtualStackSlot(operand); addDef(vslot, inst); + usePos.add(inst); Debug.log("clear operand: %s", operand); currentSet.clear(vslot.getId()); } diff -r 64e6c7b83515 -r f10ca512eb40 graal/com.oracle.graal.lir/src/com/oracle/graal/lir/stackslotalloc/LSStackSlotAllocator.java --- a/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/stackslotalloc/LSStackSlotAllocator.java Wed Feb 04 16:34:07 2015 -0800 +++ b/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/stackslotalloc/LSStackSlotAllocator.java Wed Feb 04 16:38:09 2015 -0800 @@ -32,6 +32,7 @@ import com.oracle.graal.compiler.common.cfg.*; import com.oracle.graal.debug.*; import com.oracle.graal.debug.Debug.Scope; +import com.oracle.graal.debug.internal.*; import com.oracle.graal.lir.*; import com.oracle.graal.lir.LIRInstruction.OperandFlag; import com.oracle.graal.lir.LIRInstruction.OperandMode; @@ -58,8 +59,17 @@ // @formatter:on } + private static final DebugTimer MainTimer = Debug.timer("LSStackSlotAllocator"); + private static final DebugTimer NumInstTimer = Debug.timer("LSStackSlotAllocator[NumberInstruction]"); + private static final DebugTimer BuildIntervalsTimer = Debug.timer("LSStackSlotAllocator[BuildIntervals]"); + private static final DebugTimer VerifyIntervalsTimer = Debug.timer("LSStackSlotAllocator[VerifyIntervals]"); + private static final DebugTimer AllocateSlotsTimer = Debug.timer("LSStackSlotAllocator[AllocateSlots]"); + private static final DebugTimer AssignSlotsTimer = Debug.timer("LSStackSlotAllocator[AssignSlots]"); + public void allocateStackSlots(FrameMapBuilderTool builder, LIRGenerationResult res) { - new Allocator(res.getLIR(), builder).allocate(); + try (TimerCloseable t = MainTimer.start()) { + new Allocator(res.getLIR(), builder).allocate(); + } } private static final class Allocator { @@ -82,33 +92,42 @@ // insert by to this.active = new PriorityQueue<>((a, b) -> a.to() - b.to()); - // step 1: number instructions - this.maxOpId = numberInstructions(lir, sortedBlocks); + try (TimerCloseable t = NumInstTimer.start()) { + // step 1: number instructions + this.maxOpId = numberInstructions(lir, sortedBlocks); + } } private void allocate() { Debug.dump(lir, "After StackSlot numbering"); long currentFrameSize = Debug.isMeterEnabled() ? frameMapBuilder.getFrameMap().currentFrameSize() : 0; + Set usePos; // step 2: build intervals - try (Scope s = Debug.scope("StackSlotAllocationBuildIntervals"); Indent indent = Debug.logAndIndent("BuildIntervals")) { - buildIntervals(); + try (Scope s = Debug.scope("StackSlotAllocationBuildIntervals"); Indent indent = Debug.logAndIndent("BuildIntervals"); TimerCloseable t = BuildIntervalsTimer.start()) { + usePos = buildIntervals(); } // step 3: verify intervals if (Debug.isEnabled()) { - verifyIntervals(); + try (TimerCloseable t = VerifyIntervalsTimer.start()) { + verifyIntervals(); + } } if (Debug.isDumpEnabled()) { dumpIntervals("Before stack slot allocation"); } // step 4: allocate stack slots - allocateStackSlots(); + try (TimerCloseable t = AllocateSlotsTimer.start()) { + allocateStackSlots(); + } if (Debug.isDumpEnabled()) { dumpIntervals("After stack slot allocation"); } // step 5: assign stack slots - assignStackSlots(); + try (TimerCloseable t = AssignSlotsTimer.start()) { + assignStackSlots(usePos); + } Debug.dump(lir, "After StackSlot assignment"); if (Debug.isMeterEnabled()) { StackSlotAllocator.allocatedFramesize.add(frameMapBuilder.getFrameMap().currentFrameSize() - currentFrameSize); @@ -148,8 +167,8 @@ // step 2: build intervals // ==================== - private void buildIntervals() { - new FixPointIntervalBuilder(lir, stackSlotMap, maxOpId()).build(); + private Set buildIntervals() { + return new FixPointIntervalBuilder(lir, stackSlotMap, maxOpId()).build(); } // ==================== @@ -335,16 +354,14 @@ // step 5: assign stack slots // ==================== - private void assignStackSlots() { - for (AbstractBlock block : sortedBlocks) { - lir.getLIRforBlock(block).forEach(op -> { - op.forEachInput(this::assignSlot); - op.forEachAlive(this::assignSlot); - op.forEachState(this::assignSlot); + private void assignStackSlots(Set usePos) { + for (LIRInstruction op : usePos) { + op.forEachInput(this::assignSlot); + op.forEachAlive(this::assignSlot); + op.forEachState(this::assignSlot); - op.forEachTemp(this::assignSlot); - op.forEachOutput(this::assignSlot); - }); + op.forEachTemp(this::assignSlot); + op.forEachOutput(this::assignSlot); } } diff -r 64e6c7b83515 -r f10ca512eb40 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/CompareNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/CompareNode.java Wed Feb 04 16:34:07 2015 -0800 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/CompareNode.java Wed Feb 04 16:38:09 2015 -0800 @@ -39,14 +39,19 @@ @NodeInfo public abstract class CompareNode extends BinaryOpLogicNode { + protected final Condition condition; + protected final boolean unorderedIsTrue; + /** * Constructs a new Compare instruction. * * @param x the instruction producing the first input to the instruction * @param y the instruction that produces the second input to this instruction */ - public CompareNode(ValueNode x, ValueNode y) { + public CompareNode(Condition condition, boolean unorderedIsTrue, ValueNode x, ValueNode y) { super(x, y); + this.condition = condition; + this.unorderedIsTrue = unorderedIsTrue; } /** @@ -54,14 +59,18 @@ * * @return the condition */ - public abstract Condition condition(); + public final Condition condition() { + return condition; + } /** * Checks whether unordered inputs mean true or false (only applies to float operations). * * @return {@code true} if unordered inputs produce true */ - public abstract boolean unorderedIsTrue(); + public final boolean unorderedIsTrue() { + return this.unorderedIsTrue; + } private ValueNode optimizeConditional(Constant constant, ConditionalNode conditionalNode, ConstantReflectionProvider constantReflection, Condition cond) { Constant trueConstant = conditionalNode.trueValue().asConstant(); @@ -93,8 +102,10 @@ @Override public ValueNode canonical(CanonicalizerTool tool, ValueNode forX, ValueNode forY) { - if (forX.isConstant() && forY.isConstant()) { - return LogicConstantNode.forBoolean(condition().foldCondition(forX.asConstant(), forY.asConstant(), tool.getConstantReflection(), unorderedIsTrue())); + ConstantReflectionProvider constantReflection = tool.getConstantReflection(); + LogicNode constantCondition = tryConstantFold(condition(), forX, forY, constantReflection, unorderedIsTrue()); + if (constantCondition != null) { + return constantCondition; } ValueNode result; if (forX.isConstant()) { @@ -115,7 +126,14 @@ return this; } - protected abstract CompareNode duplicateModified(ValueNode newX, ValueNode newY); + public static LogicNode tryConstantFold(Condition condition, ValueNode forX, ValueNode forY, ConstantReflectionProvider constantReflection, boolean unorderedIsTrue) { + if (forX.isConstant() && forY.isConstant() && constantReflection != null) { + return LogicConstantNode.forBoolean(condition.foldCondition(forX.asConstant(), forY.asConstant(), constantReflection, unorderedIsTrue)); + } + return null; + } + + protected abstract LogicNode duplicateModified(ValueNode newX, ValueNode newY); protected ValueNode canonicalizeSymmetricConstant(CanonicalizerTool tool, Constant constant, ValueNode nonConstant, boolean mirrored) { if (nonConstant instanceof ConditionalNode) { diff -r 64e6c7b83515 -r f10ca512eb40 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/FloatEqualsNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/FloatEqualsNode.java Wed Feb 04 16:34:07 2015 -0800 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/FloatEqualsNode.java Wed Feb 04 16:38:09 2015 -0800 @@ -22,6 +22,7 @@ */ package com.oracle.graal.nodes.calc; +import com.oracle.graal.api.meta.*; import com.oracle.graal.compiler.common.*; import com.oracle.graal.compiler.common.calc.*; import com.oracle.graal.compiler.common.type.*; @@ -31,22 +32,21 @@ import com.oracle.graal.nodes.util.*; @NodeInfo(shortName = "==") -public class FloatEqualsNode extends CompareNode { +public final class FloatEqualsNode extends CompareNode { public FloatEqualsNode(ValueNode x, ValueNode y) { - super(x, y); + super(Condition.EQ, false, x, y); assert x.stamp() instanceof FloatStamp && y.stamp() instanceof FloatStamp : x.stamp() + " " + y.stamp(); assert x.stamp().isCompatible(y.stamp()); } - @Override - public Condition condition() { - return Condition.EQ; - } - - @Override - public boolean unorderedIsTrue() { - return false; + public static LogicNode create(ValueNode x, ValueNode y, ConstantReflectionProvider constantReflection) { + LogicNode result = CompareNode.tryConstantFold(Condition.EQ, x, y, constantReflection, false); + if (result != null) { + return result; + } else { + return new FloatEqualsNode(x, y); + } } @Override diff -r 64e6c7b83515 -r f10ca512eb40 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/FloatLessThanNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/FloatLessThanNode.java Wed Feb 04 16:34:07 2015 -0800 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/FloatLessThanNode.java Wed Feb 04 16:38:09 2015 -0800 @@ -33,23 +33,10 @@ @NodeInfo(shortName = "<") public class FloatLessThanNode extends CompareNode { - protected final boolean unorderedIsTrue; - public FloatLessThanNode(ValueNode x, ValueNode y, boolean unorderedIsTrue) { - super(x, y); + super(Condition.LT, unorderedIsTrue, x, y); assert x.stamp() instanceof FloatStamp && y.stamp() instanceof FloatStamp; assert x.stamp().isCompatible(y.stamp()); - this.unorderedIsTrue = unorderedIsTrue; - } - - @Override - public Condition condition() { - return Condition.LT; - } - - @Override - public boolean unorderedIsTrue() { - return unorderedIsTrue; } @Override diff -r 64e6c7b83515 -r f10ca512eb40 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/IntegerBelowNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/IntegerBelowNode.java Wed Feb 04 16:34:07 2015 -0800 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/IntegerBelowNode.java Wed Feb 04 16:38:09 2015 -0800 @@ -33,22 +33,12 @@ public class IntegerBelowNode extends CompareNode { public IntegerBelowNode(ValueNode x, ValueNode y) { - super(x, y); + super(Condition.BT, false, x, y); assert x.stamp() instanceof IntegerStamp; assert y.stamp() instanceof IntegerStamp; } @Override - public Condition condition() { - return Condition.BT; - } - - @Override - public boolean unorderedIsTrue() { - return false; - } - - @Override public ValueNode canonical(CanonicalizerTool tool, ValueNode forX, ValueNode forY) { ValueNode result = super.canonical(tool, forX, forY); if (result != this) { diff -r 64e6c7b83515 -r f10ca512eb40 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/IntegerEqualsNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/IntegerEqualsNode.java Wed Feb 04 16:34:07 2015 -0800 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/IntegerEqualsNode.java Wed Feb 04 16:38:09 2015 -0800 @@ -35,22 +35,12 @@ public class IntegerEqualsNode extends CompareNode { public IntegerEqualsNode(ValueNode x, ValueNode y) { - super(x, y); + super(Condition.EQ, false, x, y); assert !x.getKind().isNumericFloat() && x.getKind() != Kind.Object; assert !y.getKind().isNumericFloat() && y.getKind() != Kind.Object; } @Override - public Condition condition() { - return Condition.EQ; - } - - @Override - public boolean unorderedIsTrue() { - return false; - } - - @Override protected ValueNode optimizeNormalizeCmp(Constant constant, NormalizeCompareNode normalizeNode, boolean mirrored) { PrimitiveConstant primitive = (PrimitiveConstant) constant; if (primitive.getKind() == Kind.Int && primitive.asInt() == 0) { diff -r 64e6c7b83515 -r f10ca512eb40 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/IntegerLessThanNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/IntegerLessThanNode.java Wed Feb 04 16:34:07 2015 -0800 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/IntegerLessThanNode.java Wed Feb 04 16:38:09 2015 -0800 @@ -35,22 +35,12 @@ public class IntegerLessThanNode extends CompareNode { public IntegerLessThanNode(ValueNode x, ValueNode y) { - super(x, y); + super(Condition.LT, false, x, y); assert !x.getKind().isNumericFloat() && x.getKind() != Kind.Object; assert !y.getKind().isNumericFloat() && y.getKind() != Kind.Object; } @Override - public Condition condition() { - return Condition.LT; - } - - @Override - public boolean unorderedIsTrue() { - return false; - } - - @Override protected ValueNode optimizeNormalizeCmp(Constant constant, NormalizeCompareNode normalizeNode, boolean mirrored) { PrimitiveConstant primitive = (PrimitiveConstant) constant; assert condition() == Condition.LT; diff -r 64e6c7b83515 -r f10ca512eb40 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/NormalizeCompareNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/NormalizeCompareNode.java Wed Feb 04 16:34:07 2015 -0800 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/NormalizeCompareNode.java Wed Feb 04 16:38:09 2015 -0800 @@ -55,7 +55,7 @@ LogicNode equalComp; LogicNode lessComp; if (getX().stamp() instanceof FloatStamp) { - equalComp = graph().unique(new FloatEqualsNode(getX(), getY())); + equalComp = graph().unique(FloatEqualsNode.create(getX(), getY(), tool.getConstantReflection())); lessComp = graph().unique(new FloatLessThanNode(getX(), getY(), isUnorderedLess)); } else { equalComp = graph().unique(new IntegerEqualsNode(getX(), getY())); diff -r 64e6c7b83515 -r f10ca512eb40 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/ObjectEqualsNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/ObjectEqualsNode.java Wed Feb 04 16:34:07 2015 -0800 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/ObjectEqualsNode.java Wed Feb 04 16:38:09 2015 -0800 @@ -24,6 +24,7 @@ import com.oracle.graal.api.meta.*; import com.oracle.graal.compiler.common.*; +import com.oracle.graal.compiler.common.calc.*; import com.oracle.graal.compiler.common.type.*; import com.oracle.graal.nodeinfo.*; import com.oracle.graal.nodes.*; @@ -38,6 +39,15 @@ assert y.stamp() instanceof AbstractObjectStamp; } + public static LogicNode create(ValueNode x, ValueNode y, ConstantReflectionProvider constantReflection) { + LogicNode result = CompareNode.tryConstantFold(Condition.EQ, x, y, constantReflection, false); + if (result != null) { + return result; + } else { + return new ObjectEqualsNode(x, y); + } + } + private void virtualizeNonVirtualComparison(State state, ValueNode other, VirtualizerTool tool) { if (!state.getVirtualObject().hasIdentity() && state.getVirtualObject().entryKind(0) == Kind.Boolean) { if (other.isConstant()) { @@ -75,7 +85,7 @@ /* * One of the two objects has identity, the other doesn't. In code, this looks like * "Integer.valueOf(a) == new Integer(b)", which is always false. - * + * * In other words: an object created via valueOf can never be equal to one created * by new in the same compilation unit. */ diff -r 64e6c7b83515 -r f10ca512eb40 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/PointerEqualsNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/PointerEqualsNode.java Wed Feb 04 16:34:07 2015 -0800 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/PointerEqualsNode.java Wed Feb 04 16:38:09 2015 -0800 @@ -33,22 +33,12 @@ public class PointerEqualsNode extends CompareNode { public PointerEqualsNode(ValueNode x, ValueNode y) { - super(x, y); + super(Condition.EQ, false, x, y); assert x.stamp() instanceof AbstractPointerStamp; assert y.stamp() instanceof AbstractPointerStamp; } @Override - public Condition condition() { - return Condition.EQ; - } - - @Override - public boolean unorderedIsTrue() { - return false; - } - - @Override public ValueNode canonical(CanonicalizerTool tool, ValueNode forX, ValueNode forY) { if (GraphUtil.unproxify(forX) == GraphUtil.unproxify(forY)) { return LogicConstantNode.tautology(); diff -r 64e6c7b83515 -r f10ca512eb40 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/debug/BlackholeNode.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/debug/BlackholeNode.java Wed Feb 04 16:38:09 2015 -0800 @@ -0,0 +1,71 @@ +/* + * Copyright (c) 2015, 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 com.oracle.graal.nodes.debug; + +import com.oracle.graal.compiler.common.type.*; +import com.oracle.graal.nodeinfo.*; +import com.oracle.graal.nodes.*; +import com.oracle.graal.nodes.spi.*; + +@NodeInfo +public final class BlackholeNode extends FixedWithNextNode implements LIRLowerable { + + @Input ValueNode value; + + public BlackholeNode(ValueNode value) { + super(StampFactory.forVoid()); + this.value = value; + } + + @Override + public void generate(NodeLIRBuilderTool gen) { + gen.getLIRGeneratorTool().emitBlackhole(gen.operand(value)); + } + + @NodeIntrinsic + public static native void consume(boolean v); + + @NodeIntrinsic + public static native void consume(byte v); + + @NodeIntrinsic + public static native void consume(short v); + + @NodeIntrinsic + public static native void consume(char v); + + @NodeIntrinsic + public static native void consume(int v); + + @NodeIntrinsic + public static native void consume(long v); + + @NodeIntrinsic + public static native void consume(float v); + + @NodeIntrinsic + public static native void consume(double v); + + @NodeIntrinsic + public static native void consume(Object v); +} diff -r 64e6c7b83515 -r f10ca512eb40 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/debug/ControlFlowAnchorNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/debug/ControlFlowAnchorNode.java Wed Feb 04 16:34:07 2015 -0800 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/debug/ControlFlowAnchorNode.java Wed Feb 04 16:38:09 2015 -0800 @@ -40,11 +40,18 @@ protected Unique unique; - public ControlFlowAnchorNode(@SuppressWarnings("unused") Invoke invoke) { + public ControlFlowAnchorNode() { super(StampFactory.forVoid()); this.unique = new Unique(); } + /** + * Used by MacroSubstitution. + */ + public ControlFlowAnchorNode(@SuppressWarnings("unused") Invoke invoke) { + this(); + } + public void generate(NodeLIRBuilderTool generator) { // do nothing } diff -r 64e6c7b83515 -r f10ca512eb40 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/debug/OpaqueNode.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/debug/OpaqueNode.java Wed Feb 04 16:38:09 2015 -0800 @@ -0,0 +1,71 @@ +/* + * Copyright (c) 2015, 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 com.oracle.graal.nodes.debug; + +import com.oracle.graal.nodeinfo.*; +import com.oracle.graal.nodes.*; +import com.oracle.graal.nodes.calc.*; +import com.oracle.graal.nodes.spi.*; + +@NodeInfo +public class OpaqueNode extends FloatingNode implements LIRLowerable { + + @Input ValueNode value; + + public OpaqueNode(ValueNode value) { + super(value.stamp().unrestricted()); + this.value = value; + } + + @Override + public void generate(NodeLIRBuilderTool gen) { + gen.setResult(this, gen.operand(value)); + } + + @NodeIntrinsic + public static native boolean opaque(boolean v); + + @NodeIntrinsic + public static native byte opaque(byte v); + + @NodeIntrinsic + public static native short opaque(short v); + + @NodeIntrinsic + public static native char opaque(char v); + + @NodeIntrinsic + public static native int opaque(int v); + + @NodeIntrinsic + public static native long opaque(long v); + + @NodeIntrinsic + public static native float opaque(float v); + + @NodeIntrinsic + public static native double opaque(double v); + + @NodeIntrinsic + public static native T opaque(T v); +} diff -r 64e6c7b83515 -r f10ca512eb40 graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/BlackholeSubstitutions.java --- a/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/BlackholeSubstitutions.java Wed Feb 04 16:34:07 2015 -0800 +++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/BlackholeSubstitutions.java Wed Feb 04 16:38:09 2015 -0800 @@ -23,7 +23,7 @@ package com.oracle.graal.replacements; import com.oracle.graal.api.replacements.*; -import com.oracle.graal.replacements.nodes.*; +import com.oracle.graal.nodes.debug.*; /** * Substitutions for both the old and new versions of JMH Blackhole helper classes. diff -r 64e6c7b83515 -r f10ca512eb40 graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/GraalDirectivesSubstitutions.java --- a/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/GraalDirectivesSubstitutions.java Wed Feb 04 16:34:07 2015 -0800 +++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/GraalDirectivesSubstitutions.java Wed Feb 04 16:38:09 2015 -0800 @@ -29,7 +29,6 @@ import com.oracle.graal.nodes.debug.*; import com.oracle.graal.nodes.extended.*; import com.oracle.graal.nodes.spi.*; -import com.oracle.graal.replacements.nodes.*; @ClassSubstitution(GraalDirectives.class) public class GraalDirectivesSubstitutions { diff -r 64e6c7b83515 -r f10ca512eb40 graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/ReplacementsImpl.java --- a/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/ReplacementsImpl.java Wed Feb 04 16:34:07 2015 -0800 +++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/ReplacementsImpl.java Wed Feb 04 16:38:09 2015 -0800 @@ -619,8 +619,8 @@ if (MethodsElidedInSnippets != null && methodToParse.getSignature().getReturnKind() == Kind.Void && MethodFilter.matches(MethodsElidedInSnippets, methodToParse)) { graph.addAfterFixed(graph.start(), graph.add(new ReturnNode(null))); } else { - createGraphBuilder(metaAccess, replacements.providers.getStampProvider(), replacements.assumptions, GraphBuilderConfiguration.getSnippetDefault(), OptimisticOptimizations.NONE).apply( - graph); + createGraphBuilder(metaAccess, replacements.providers.getStampProvider(), replacements.assumptions, replacements.providers.getConstantReflection(), + GraphBuilderConfiguration.getSnippetDefault(), OptimisticOptimizations.NONE).apply(graph); } afterParsing(graph); @@ -633,9 +633,9 @@ return graph; } - protected Instance createGraphBuilder(MetaAccessProvider metaAccess, StampProvider stampProvider, Assumptions assumptions, GraphBuilderConfiguration graphBuilderConfig, - OptimisticOptimizations optimisticOpts) { - return new GraphBuilderPhase.Instance(metaAccess, stampProvider, assumptions, graphBuilderConfig, optimisticOpts); + protected Instance createGraphBuilder(MetaAccessProvider metaAccess, StampProvider stampProvider, Assumptions assumptions, ConstantReflectionProvider constantReflectionProvider, + GraphBuilderConfiguration graphBuilderConfig, OptimisticOptimizations optimisticOpts) { + return new GraphBuilderPhase.Instance(metaAccess, stampProvider, assumptions, constantReflectionProvider, graphBuilderConfig, optimisticOpts); } protected void afterParsing(StructuredGraph graph) { diff -r 64e6c7b83515 -r f10ca512eb40 graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/nodes/BlackholeNode.java --- a/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/nodes/BlackholeNode.java Wed Feb 04 16:34:07 2015 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,71 +0,0 @@ -/* - * Copyright (c) 2015, 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 com.oracle.graal.replacements.nodes; - -import com.oracle.graal.compiler.common.type.*; -import com.oracle.graal.nodeinfo.*; -import com.oracle.graal.nodes.*; -import com.oracle.graal.nodes.spi.*; - -@NodeInfo -public final class BlackholeNode extends FixedWithNextNode implements LIRLowerable { - - @Input ValueNode value; - - public BlackholeNode(ValueNode value) { - super(StampFactory.forVoid()); - this.value = value; - } - - @Override - public void generate(NodeLIRBuilderTool gen) { - gen.getLIRGeneratorTool().emitBlackhole(gen.operand(value)); - } - - @NodeIntrinsic - public static native void consume(boolean v); - - @NodeIntrinsic - public static native void consume(byte v); - - @NodeIntrinsic - public static native void consume(short v); - - @NodeIntrinsic - public static native void consume(char v); - - @NodeIntrinsic - public static native void consume(int v); - - @NodeIntrinsic - public static native void consume(long v); - - @NodeIntrinsic - public static native void consume(float v); - - @NodeIntrinsic - public static native void consume(double v); - - @NodeIntrinsic - public static native void consume(Object v); -} diff -r 64e6c7b83515 -r f10ca512eb40 graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/nodes/OpaqueNode.java --- a/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/nodes/OpaqueNode.java Wed Feb 04 16:34:07 2015 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,71 +0,0 @@ -/* - * Copyright (c) 2015, 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 com.oracle.graal.replacements.nodes; - -import com.oracle.graal.nodeinfo.*; -import com.oracle.graal.nodes.*; -import com.oracle.graal.nodes.calc.*; -import com.oracle.graal.nodes.spi.*; - -@NodeInfo -public class OpaqueNode extends FloatingNode implements LIRLowerable { - - @Input ValueNode value; - - public OpaqueNode(ValueNode value) { - super(value.stamp().unrestricted()); - this.value = value; - } - - @Override - public void generate(NodeLIRBuilderTool gen) { - gen.setResult(this, gen.operand(value)); - } - - @NodeIntrinsic - public static native boolean opaque(boolean v); - - @NodeIntrinsic - public static native byte opaque(byte v); - - @NodeIntrinsic - public static native short opaque(short v); - - @NodeIntrinsic - public static native char opaque(char v); - - @NodeIntrinsic - public static native int opaque(int v); - - @NodeIntrinsic - public static native long opaque(long v); - - @NodeIntrinsic - public static native float opaque(float v); - - @NodeIntrinsic - public static native double opaque(double v); - - @NodeIntrinsic - public static native T opaque(T v); -} diff -r 64e6c7b83515 -r f10ca512eb40 graal/com.oracle.graal.truffle.hotspot/src/com/oracle/graal/truffle/hotspot/HotSpotTruffleRuntime.java --- a/graal/com.oracle.graal.truffle.hotspot/src/com/oracle/graal/truffle/hotspot/HotSpotTruffleRuntime.java Wed Feb 04 16:34:07 2015 -0800 +++ b/graal/com.oracle.graal.truffle.hotspot/src/com/oracle/graal/truffle/hotspot/HotSpotTruffleRuntime.java Wed Feb 04 16:38:09 2015 -0800 @@ -177,7 +177,8 @@ Suites suites = suitesProvider.createSuites(); removeInliningPhase(suites); StructuredGraph graph = new StructuredGraph(javaMethod); - new GraphBuilderPhase.Instance(metaAccess, providers.getStampProvider(), new Assumptions(false), GraphBuilderConfiguration.getEagerDefault(), OptimisticOptimizations.ALL).apply(graph); + new GraphBuilderPhase.Instance(metaAccess, providers.getStampProvider(), new Assumptions(false), providers.getConstantReflection(), GraphBuilderConfiguration.getEagerDefault(), + OptimisticOptimizations.ALL).apply(graph); PhaseSuite graphBuilderSuite = getGraphBuilderSuite(suitesProvider); CallingConvention cc = getCallingConvention(providers.getCodeCache(), Type.JavaCallee, graph.method(), false); Backend backend = Graal.getRequiredCapability(RuntimeProvider.class).getHostBackend(); diff -r 64e6c7b83515 -r f10ca512eb40 graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/PartialEvaluator.java --- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/PartialEvaluator.java Wed Feb 04 16:34:07 2015 -0800 +++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/PartialEvaluator.java Wed Feb 04 16:38:09 2015 -0800 @@ -36,9 +36,11 @@ import com.oracle.graal.graph.Graph.Mark; import com.oracle.graal.graph.*; import com.oracle.graal.graph.Node; +import com.oracle.graal.java.*; import com.oracle.graal.loop.*; import com.oracle.graal.nodes.CallTargetNode.InvokeKind; import com.oracle.graal.nodes.*; +import com.oracle.graal.nodes.calc.*; import com.oracle.graal.nodes.java.*; import com.oracle.graal.nodes.spi.*; import com.oracle.graal.nodes.util.*; @@ -70,15 +72,26 @@ private final TruffleCache truffleCache; private final SnippetReflectionProvider snippetReflection; private final ResolvedJavaMethod callDirectMethod; + private final ResolvedJavaMethod callInlinedMethod; private final ResolvedJavaMethod callSiteProxyMethod; + protected final ResolvedJavaMethod callRootMethod; + private final GraphBuilderConfiguration configForRoot; - public PartialEvaluator(Providers providers, TruffleCache truffleCache, SnippetReflectionProvider snippetReflection) { + public PartialEvaluator(Providers providers, GraphBuilderConfiguration configForRoot, TruffleCache truffleCache, SnippetReflectionProvider snippetReflection) { this.providers = providers; this.canonicalizer = new CanonicalizerPhase(!ImmutableCode.getValue()); this.snippetReflection = snippetReflection; this.truffleCache = truffleCache; this.callDirectMethod = providers.getMetaAccess().lookupJavaMethod(OptimizedCallTarget.getCallDirectMethod()); + this.callInlinedMethod = providers.getMetaAccess().lookupJavaMethod(OptimizedCallTarget.getCallInlinedMethod()); this.callSiteProxyMethod = providers.getMetaAccess().lookupJavaMethod(GraalFrameInstance.CallNodeFrame.METHOD); + this.configForRoot = configForRoot; + + try { + callRootMethod = providers.getMetaAccess().lookupJavaMethod(OptimizedCallTarget.class.getDeclaredMethod("callRoot", Object[].class)); + } catch (NoSuchMethodException ex) { + throw new RuntimeException(ex); + } } public StructuredGraph createGraph(final OptimizedCallTarget callTarget, final Assumptions assumptions) { @@ -91,65 +104,34 @@ } catch (Throwable e) { throw Debug.handle(e); } - final StructuredGraph graph = truffleCache.createRootGraph(callTarget.toString()); + + final StructuredGraph graph = new StructuredGraph(callTarget.toString(), callRootMethod); assert graph != null : "no graph for root method"; try (Scope s = Debug.scope("CreateGraph", graph); Indent indent = Debug.logAndIndent("createGraph %s", graph)) { - // Canonicalize / constant propagate. - PhaseContext baseContext = new PhaseContext(providers, assumptions); - - injectConstantCallTarget(graph, callTarget, baseContext); - - Debug.dump(graph, "Before expansion"); - - TruffleExpansionLogger expansionLogger = null; - if (TraceTruffleExpansion.getValue()) { - expansionLogger = new TruffleExpansionLogger(providers, graph); - } - expandTree(graph, assumptions, expansionLogger); + Map graphCache = null; + if (CacheGraphs.getValue()) { + graphCache = new HashMap<>(); + } + PhaseContext baseContext = new PhaseContext(providers, assumptions); + HighTierContext tierContext = new HighTierContext(providers, assumptions, graphCache, new PhaseSuite(), OptimisticOptimizations.NONE); - TruffleInliningCache inliningCache = null; - if (TruffleFunctionInlining.getValue()) { - callTarget.setInlining(new TruffleInlining(callTarget, new DefaultInliningPolicy())); - if (TruffleFunctionInliningCache.getValue()) { - inliningCache = new TruffleInliningCache(); - } + if (TruffleCompilerOptions.FastPE.getValue()) { + fastPartialEvaluation(callTarget, assumptions, graph, baseContext, tierContext); + } else { + createRootGraph(graph); + partialEvaluation(callTarget, assumptions, graph, baseContext, tierContext); } - expandDirectCalls(graph, assumptions, expansionLogger, callTarget.getInlining(), inliningCache); - if (Thread.currentThread().isInterrupted()) { return null; } new VerifyFrameDoesNotEscapePhase().apply(graph, false); - if (TraceTruffleCompilationHistogram.getValue() && constantReceivers != null) { createHistogram(); } - - canonicalizer.apply(graph, baseContext); - Map graphCache = null; - if (CacheGraphs.getValue()) { - graphCache = new HashMap<>(); - } - HighTierContext tierContext = new HighTierContext(providers, assumptions, graphCache, new PhaseSuite(), OptimisticOptimizations.NONE); - - // EA frame and clean up. - do { - try (Scope pe = Debug.scope("TrufflePartialEscape", graph)) { - new PartialEscapePhase(true, canonicalizer).apply(graph, tierContext); - new IncrementalCanonicalizerPhase<>(canonicalizer, new ConditionalEliminationPhase()).apply(graph, tierContext); - } catch (Throwable t) { - Debug.handle(t); - } - } while (expandTree(graph, assumptions, expansionLogger)); - - if (expansionLogger != null) { - expansionLogger.print(callTarget); - } - postPartialEvaluation(graph); } catch (Throwable e) { @@ -159,6 +141,104 @@ return graph; } + private class InterceptLoadFieldPlugin implements GraphBuilderPlugins.LoadFieldPlugin { + + public boolean apply(GraphBuilderContext builder, ValueNode receiver, ResolvedJavaField field) { + System.out.println("Load field plugin called for receiver: " + receiver + " and field " + field); + + if (receiver.isConstant()) { + JavaConstant asJavaConstant = receiver.asJavaConstant(); + JavaConstant result = providers.getConstantReflection().readConstantFieldValue(field, asJavaConstant); + if (result != null) { + ConstantNode constantNode = builder.append(ConstantNode.forConstant(result, providers.getMetaAccess())); + builder.push(constantNode.getKind(), constantNode); + return true; + } + } + return false; + } + } + + private class InterceptReceiverPlugin implements GraphBuilderPlugins.ParameterPlugin { + + private final Object receiver; + + public InterceptReceiverPlugin(Object receiver) { + this.receiver = receiver; + } + + public FloatingNode interceptParameter(int index) { + if (index == 0) { + return ConstantNode.forConstant(snippetReflection.forObject(receiver), providers.getMetaAccess()); + } + return null; + } + } + + @SuppressWarnings("unused") + private void fastPartialEvaluation(OptimizedCallTarget callTarget, Assumptions assumptions, StructuredGraph graph, PhaseContext baseContext, HighTierContext tierContext) { + GraphBuilderConfiguration newConfig = configForRoot.copy(); + newConfig.setLoadFieldPlugin(new InterceptLoadFieldPlugin()); + newConfig.setParameterPlugin(new InterceptReceiverPlugin(callTarget)); + new GraphBuilderPhase.Instance(providers.getMetaAccess(), providers.getStampProvider(), new Assumptions(false), providers.getConstantReflection(), newConfig, TruffleCompilerImpl.Optimizations).apply(graph); + Debug.dump(graph, "After FastPE"); + } + + private void partialEvaluation(final OptimizedCallTarget callTarget, final Assumptions assumptions, final StructuredGraph graph, PhaseContext baseContext, HighTierContext tierContext) { + injectConstantCallTarget(graph, callTarget, baseContext); + + Debug.dump(graph, "Before expansion"); + + TruffleExpansionLogger expansionLogger = null; + if (TraceTruffleExpansion.getValue()) { + expansionLogger = new TruffleExpansionLogger(providers, graph); + } + + expandTree(graph, assumptions, expansionLogger); + + TruffleInliningCache inliningCache = null; + if (TruffleFunctionInlining.getValue()) { + callTarget.setInlining(new TruffleInlining(callTarget, new DefaultInliningPolicy())); + if (TruffleFunctionInliningCache.getValue()) { + inliningCache = new TruffleInliningCache(); + } + } + + expandDirectCalls(graph, assumptions, expansionLogger, callTarget.getInlining(), inliningCache); + + if (Thread.currentThread().isInterrupted()) { + return; + } + + canonicalizer.apply(graph, baseContext); + // EA frame and clean up. + do { + try (Scope pe = Debug.scope("TrufflePartialEscape", graph)) { + new PartialEscapePhase(true, canonicalizer).apply(graph, tierContext); + new IncrementalCanonicalizerPhase<>(canonicalizer, new ConditionalEliminationPhase()).apply(graph, tierContext); + } catch (Throwable t) { + Debug.handle(t); + } + } while (expandTree(graph, assumptions, expansionLogger)); + + if (expansionLogger != null) { + expansionLogger.print(callTarget); + } + } + + public StructuredGraph createRootGraph(StructuredGraph graph) { + new GraphBuilderPhase.Instance(providers.getMetaAccess(), providers.getStampProvider(), new Assumptions(false), providers.getConstantReflection(), configForRoot, + TruffleCompilerImpl.Optimizations).apply(graph); + return graph; + } + + public StructuredGraph createInlineGraph(String name) { + StructuredGraph graph = new StructuredGraph(name, callInlinedMethod); + new GraphBuilderPhase.Instance(providers.getMetaAccess(), providers.getStampProvider(), new Assumptions(false), providers.getConstantReflection(), configForRoot, + TruffleCompilerImpl.Optimizations).apply(graph); + return graph; + } + private static void postPartialEvaluation(final StructuredGraph graph) { NeverPartOfCompilationNode.verifyNotFoundIn(graph); for (MaterializeFrameNode materializeNode : graph.getNodes(MaterializeFrameNode.class).snapshot()) { @@ -464,7 +544,7 @@ private StructuredGraph createInlineGraph(PhaseContext phaseContext, Assumptions assumptions, TruffleInliningCache cache, TruffleInliningDecision decision) { try (Scope s = Debug.scope("GuestLanguageInlinedGraph", new DebugDumpScope(decision.getTarget().toString()))) { OptimizedCallTarget target = decision.getTarget(); - StructuredGraph inlineGraph = truffleCache.createInlineGraph(target.toString()); + StructuredGraph inlineGraph = createInlineGraph(target.toString()); injectConstantCallTarget(inlineGraph, decision.getTarget(), phaseContext); TruffleExpansionLogger expansionLogger = null; if (TraceTruffleExpansion.getValue()) { diff -r 64e6c7b83515 -r f10ca512eb40 graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/TruffleCache.java --- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/TruffleCache.java Wed Feb 04 16:34:07 2015 -0800 +++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/TruffleCache.java Wed Feb 04 16:38:09 2015 -0800 @@ -30,13 +30,6 @@ public interface TruffleCache { /** - * Creates the graph for the root method, i.e. {@link OptimizedCallTarget#callBoundary}. - */ - StructuredGraph createRootGraph(String name); - - StructuredGraph createInlineGraph(String name); - - /** * Returns a cached graph for a method with given arguments. */ StructuredGraph lookup(final ResolvedJavaMethod method, final NodeInputList arguments, final CanonicalizerPhase finalCanonicalizer); diff -r 64e6c7b83515 -r f10ca512eb40 graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/TruffleCacheImpl.java --- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/TruffleCacheImpl.java Wed Feb 04 16:34:07 2015 -0800 +++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/TruffleCacheImpl.java Wed Feb 04 16:38:09 2015 -0800 @@ -56,7 +56,6 @@ private final Providers providers; private final GraphBuilderConfiguration config; - private final GraphBuilderConfiguration configForRoot; private final OptimisticOptimizations optimisticOptimizations; private final HashMap, StructuredGraph> cache = new HashMap<>(); @@ -68,40 +67,17 @@ private final ResolvedJavaType errorClass; private final ResolvedJavaType controlFlowExceptionClass; - protected final ResolvedJavaMethod callRootMethod; - protected final ResolvedJavaMethod callInlinedMethod; - private long counter; - public TruffleCacheImpl(Providers providers, GraphBuilderConfiguration config, GraphBuilderConfiguration configForRoot, OptimisticOptimizations optimisticOptimizations) { + public TruffleCacheImpl(Providers providers, GraphBuilderConfiguration config, OptimisticOptimizations optimisticOptimizations) { this.providers = providers; this.config = config; - this.configForRoot = configForRoot; this.optimisticOptimizations = optimisticOptimizations; this.stringBuilderClass = providers.getMetaAccess().lookupJavaType(StringBuilder.class); this.runtimeExceptionClass = providers.getMetaAccess().lookupJavaType(RuntimeException.class); this.errorClass = providers.getMetaAccess().lookupJavaType(Error.class); this.controlFlowExceptionClass = providers.getMetaAccess().lookupJavaType(ControlFlowException.class); - - try { - callRootMethod = providers.getMetaAccess().lookupJavaMethod(OptimizedCallTarget.class.getDeclaredMethod("callRoot", Object[].class)); - } catch (NoSuchMethodException ex) { - throw new RuntimeException(ex); - } - this.callInlinedMethod = providers.getMetaAccess().lookupJavaMethod(OptimizedCallTarget.getCallInlinedMethod()); - } - - public StructuredGraph createInlineGraph(String name) { - StructuredGraph graph = new StructuredGraph(name, callInlinedMethod); - new GraphBuilderPhase.Instance(providers.getMetaAccess(), providers.getStampProvider(), new Assumptions(false), config, TruffleCompilerImpl.Optimizations).apply(graph); - return graph; - } - - public StructuredGraph createRootGraph(String name) { - StructuredGraph graph = new StructuredGraph(name, callRootMethod); - new GraphBuilderPhase.Instance(providers.getMetaAccess(), providers.getStampProvider(), new Assumptions(false), configForRoot, TruffleCompilerImpl.Optimizations).apply(graph); - return graph; } private static List computeCacheKey(ResolvedJavaMethod method, NodeInputList arguments) { @@ -294,7 +270,7 @@ protected StructuredGraph parseGraph(final ResolvedJavaMethod method, final PhaseContext phaseContext) { final StructuredGraph graph = new StructuredGraph(method); - new GraphBuilderPhase.Instance(phaseContext.getMetaAccess(), phaseContext.getStampProvider(), phaseContext.getAssumptions(), config, optimisticOptimizations).apply(graph); + new GraphBuilderPhase.Instance(phaseContext.getMetaAccess(), phaseContext.getStampProvider(), phaseContext.getAssumptions(), null, config, optimisticOptimizations).apply(graph); return graph; } diff -r 64e6c7b83515 -r f10ca512eb40 graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/TruffleCompilerImpl.java --- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/TruffleCompilerImpl.java Wed Feb 04 16:34:07 2015 -0800 +++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/TruffleCompilerImpl.java Wed Feb 04 16:38:09 2015 -0800 @@ -84,9 +84,9 @@ ResolvedJavaType[] skippedExceptionTypes = getSkippedExceptionTypes(providers.getMetaAccess()); GraphBuilderConfiguration eagerConfig = GraphBuilderConfiguration.getEagerDefault().withSkippedExceptionTypes(skippedExceptionTypes); this.config = GraphBuilderConfiguration.getDefault().withSkippedExceptionTypes(skippedExceptionTypes); - this.truffleCache = new TruffleCacheImpl(providers, eagerConfig, config, TruffleCompilerImpl.Optimizations); + this.truffleCache = new TruffleCacheImpl(providers, eagerConfig, TruffleCompilerImpl.Optimizations); - this.partialEvaluator = new PartialEvaluator(providers, truffleCache, Graal.getRequiredCapability(SnippetReflectionProvider.class)); + this.partialEvaluator = new PartialEvaluator(providers, config, truffleCache, Graal.getRequiredCapability(SnippetReflectionProvider.class)); if (Debug.isEnabled()) { DebugEnvironment.initialize(System.out); @@ -197,8 +197,9 @@ private PhaseSuite createGraphBuilderSuite() { PhaseSuite suite = backend.getSuites().getDefaultGraphBuilderSuite().copy(); ListIterator> iterator = suite.findPhase(GraphBuilderPhase.class); + GraphBuilderPhase graphBuilderPhase = (GraphBuilderPhase) iterator.previous(); iterator.remove(); - iterator.add(new GraphBuilderPhase(config)); + iterator.add(new GraphBuilderPhase(config, graphBuilderPhase.getGraphBuilderPlugins())); return suite; } diff -r 64e6c7b83515 -r f10ca512eb40 graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/substitutions/TruffleGraphBuilderPluginsProvider.java --- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/substitutions/TruffleGraphBuilderPluginsProvider.java Wed Feb 04 16:34:07 2015 -0800 +++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/substitutions/TruffleGraphBuilderPluginsProvider.java Wed Feb 04 16:38:09 2015 -0800 @@ -28,6 +28,8 @@ import com.oracle.graal.api.meta.*; import com.oracle.graal.api.runtime.*; import com.oracle.graal.java.*; +import com.oracle.graal.java.GraphBuilderPlugins.InvocationPlugin; +import com.oracle.graal.java.GraphBuilderPlugins.Registration; import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.extended.*; import com.oracle.graal.truffle.nodes.frame.*; @@ -39,96 +41,69 @@ @ServiceProvider(GraphBuilderPluginsProvider.class) public class TruffleGraphBuilderPluginsProvider implements GraphBuilderPluginsProvider { public void registerPlugins(MetaAccessProvider metaAccess, GraphBuilderPlugins plugins) { - plugins.register(metaAccess, CompilerDirectivesPlugin.class); - } - - /** - * Plugins for {@link CompilerDirectives}. - */ - enum CompilerDirectivesPlugin implements GraphBuilderPlugin { - inInterpreter() { - public boolean handleInvocation(GraphBuilderContext builder, ValueNode[] args) { - builder.append(ConstantNode.forBoolean(false)); + Registration r = new Registration(plugins, metaAccess, CompilerDirectives.class); + r.register0("inInterpreter", new InvocationPlugin() { + public boolean apply(GraphBuilderContext builder) { + builder.push(Kind.Boolean, builder.append(ConstantNode.forBoolean(false))); return true; } - }, - inCompiledCode() { - public boolean handleInvocation(GraphBuilderContext builder, ValueNode[] args) { - builder.append(ConstantNode.forBoolean(true)); + }); + r.register0("inCompiledCode", new InvocationPlugin() { + public boolean apply(GraphBuilderContext builder) { + builder.push(Kind.Boolean, builder.append(ConstantNode.forBoolean(true))); return true; } - }, - transferToInterpreter() { - public boolean handleInvocation(GraphBuilderContext builder, ValueNode[] args) { + }); + r.register0("transferToInterpreter", new InvocationPlugin() { + public boolean apply(GraphBuilderContext builder) { builder.append(new DeoptimizeNode(DeoptimizationAction.None, DeoptimizationReason.TransferToInterpreter)); return true; } - }, - transferToInterpreterAndInvalidate() { - public boolean handleInvocation(GraphBuilderContext builder, ValueNode[] args) { + }); + r.register0("transferToInterpreterAndInvalidate", new InvocationPlugin() { + public boolean apply(GraphBuilderContext builder) { builder.append(new DeoptimizeNode(DeoptimizationAction.InvalidateReprofile, DeoptimizationReason.TransferToInterpreter)); return true; } - }, - interpreterOnly(Runnable.class) { - public boolean handleInvocation(GraphBuilderContext builder, ValueNode[] args) { + }); + r.register1("interpreterOnly", Runnable.class, new InvocationPlugin() { + public boolean apply(GraphBuilderContext builder, ValueNode arg) { return true; } - }, - interpreterOnly$(Callable.class) { - public boolean handleInvocation(GraphBuilderContext builder, ValueNode[] args) { + }); + r.register1("interpreterOnly", Callable.class, new InvocationPlugin() { + public boolean apply(GraphBuilderContext builder, ValueNode arg) { return true; } - }, - injectBranchProbability(double.class, boolean.class) { - public boolean handleInvocation(GraphBuilderContext builder, ValueNode[] args) { - ValueNode probability = args[0]; - ValueNode condition = args[1]; + }); + r.register2("injectBranchProbability", double.class, boolean.class, new InvocationPlugin() { + public boolean apply(GraphBuilderContext builder, ValueNode probability, ValueNode condition) { builder.append(new BranchProbabilityNode(probability, condition)); return true; } - }, - bailout(String.class) { - public boolean handleInvocation(GraphBuilderContext builder, ValueNode[] args) { - // TODO: is this too eager? Should a BailoutNode be created instead? - ValueNode message = args[0]; + }); + r.register1("bailout", String.class, new InvocationPlugin() { + public boolean apply(GraphBuilderContext builder, ValueNode message) { if (message.isConstant()) { throw new BailoutException(message.asConstant().toValueString()); } throw new BailoutException("bailout (message is not compile-time constant, so no additional information is available)"); } - }, - - isCompilationConstant(Object.class) { - public boolean handleInvocation(GraphBuilderContext builder, ValueNode[] args) { - ValueNode arg0 = args[0]; - if (arg0 instanceof BoxNode) { - arg0 = ((BoxNode) arg0).getValue(); - } - if (arg0.isConstant()) { + }); + r.register1("isCompilationConstant", Object.class, new InvocationPlugin() { + public boolean apply(GraphBuilderContext builder, ValueNode value) { + if ((value instanceof BoxNode ? ((BoxNode) value).getValue() : value).isConstant()) { builder.push(Kind.Boolean, builder.append(ConstantNode.forBoolean(true))); return true; } - - // Cannot create MacroNodes in a plugin (yet) return false; } - }, - materialize(Object.class) { - public boolean handleInvocation(GraphBuilderContext builder, ValueNode[] args) { - builder.append(new ForceMaterializeNode(args[0])); + }); + r.register1("materialize", Object.class, new InvocationPlugin() { + public boolean apply(GraphBuilderContext builder, ValueNode value) { + builder.append(new ForceMaterializeNode(value)); return true; } - }; - - CompilerDirectivesPlugin(Class... parameterTypes) { - this.parameterTypes = parameterTypes; - } - - private final Class[] parameterTypes; - - public ResolvedJavaMethod getInvocationTarget(MetaAccessProvider metaAccess) { - return GraphBuilderPlugin.resolveTarget(metaAccess, CompilerDirectives.class, name(), parameterTypes); - } + }); } } diff -r 64e6c7b83515 -r f10ca512eb40 mx/suite.py --- a/mx/suite.py Wed Feb 04 16:34:07 2015 -0800 +++ b/mx/suite.py Wed Feb 04 16:38:09 2015 -0800 @@ -601,7 +601,6 @@ "subDir" : "graal", "sourceDirs" : ["src"], "dependencies" : [ - "com.oracle.graal.api.directives", "com.oracle.graal.compiler", "com.oracle.graal.java", "com.oracle.graal.word", @@ -815,6 +814,7 @@ "subDir" : "graal", "sourceDirs" : ["src"], "dependencies" : [ + "com.oracle.graal.api.directives", "com.oracle.graal.phases", ], "checkstyle" : "com.oracle.graal.graph", @@ -875,7 +875,6 @@ "subDir" : "graal", "sourceDirs" : ["src"], "dependencies" : [ - "com.oracle.graal.api.directives", "com.oracle.graal.test", "com.oracle.graal.printer", "com.oracle.graal.runtime",