# HG changeset patch # User Stefan Anzinger # Date 1404145033 -7200 # Node ID 281c30cf195226880b5172dfb921664ff272148a # Parent 34ac3ddfd5ac55f6262b062e81e5ed46bf89d0c2# Parent 8da760bd1575ac9e7dbe5baa975fb407593dc893 Merge diff -r 34ac3ddfd5ac -r 281c30cf1952 graal/com.oracle.graal.debug/src/com/oracle/graal/debug/Debug.java --- a/graal/com.oracle.graal.debug/src/com/oracle/graal/debug/Debug.java Mon Jun 30 17:27:35 2014 +0200 +++ b/graal/com.oracle.graal.debug/src/com/oracle/graal/debug/Debug.java Mon Jun 30 18:17:13 2014 +0200 @@ -90,7 +90,7 @@ * Determines if verification is enabled in the current method, regardless of the * {@linkplain Debug#currentScope() current debug scope}. * - * @see Debug#verify(Object, Object) + * @see Debug#verify(Object, String) */ public static boolean isVerifyEnabledForMethod() { if (!ENABLED) { @@ -107,7 +107,7 @@ * Determines if verification is enabled in the {@linkplain Debug#currentScope() current debug * scope}. * - * @see Debug#verify(Object, Object) + * @see Debug#verify(Object, String) */ public static boolean isVerifyEnabled() { return ENABLED && DebugScope.getInstance().isVerifyEnabled(); @@ -491,13 +491,13 @@ * config} to perform verification on a given object. * * @param object object to verify - * @param context object describing the context of verification + * @param message description of verification context * - * @see DebugVerifyHandler#verify(Object, Object...) + * @see DebugVerifyHandler#verify(Object, String) */ - public static void verify(Object object, Object context) { + public static void verify(Object object, String message) { if (ENABLED && DebugScope.getInstance().isVerifyEnabled()) { - DebugScope.getInstance().verify(object, context); + DebugScope.getInstance().verify(object, message); } } @@ -506,28 +506,28 @@ * config} to perform verification on a given object. * * @param object object to verify - * @param context1 first object describing the context of verification - * @param context2 second object describing the context of verification + * @param format a format string for the description of the verification context + * @param arg the argument referenced by the format specifiers in {@code format} * - * @see DebugVerifyHandler#verify(Object, Object...) + * @see DebugVerifyHandler#verify(Object, String) */ - public static void verify(Object object, Object context1, Object context2) { + public static void verify(Object object, String format, Object arg) { if (ENABLED && DebugScope.getInstance().isVerifyEnabled()) { - DebugScope.getInstance().verify(object, context1, context2); + DebugScope.getInstance().verify(object, format, arg); } } /** - * This override exists to catch cases when {@link #verify(Object, Object)} is called with one - * argument bound to a varargs method parameter. It will bind to this method instead of the - * single arg variant and produce a deprecation warning instead of silently wrapping the + * This override exists to catch cases when {@link #verify(Object, String, Object)} is called + * with one argument bound to a varargs method parameter. It will bind to this method instead of + * the single arg variant and produce a deprecation warning instead of silently wrapping the * Object[] inside of another Object[]. */ @Deprecated - public static void verify(Object object, Object[] args) { + public static void verify(Object object, String format, Object[] args) { assert false : "shouldn't use this"; if (ENABLED && DebugScope.getInstance().isVerifyEnabled()) { - DebugScope.getInstance().verify(object, args); + DebugScope.getInstance().verify(object, format, args); } } diff -r 34ac3ddfd5ac -r 281c30cf1952 graal/com.oracle.graal.debug/src/com/oracle/graal/debug/DebugVerifyHandler.java --- a/graal/com.oracle.graal.debug/src/com/oracle/graal/debug/DebugVerifyHandler.java Mon Jun 30 17:27:35 2014 +0200 +++ b/graal/com.oracle.graal.debug/src/com/oracle/graal/debug/DebugVerifyHandler.java Mon Jun 30 18:17:13 2014 +0200 @@ -31,25 +31,7 @@ * Verifies that a given object satisfies some invariants. * * @param object object to verify - * @param context object(s) describing the context of verification - */ - void verify(Object object, Object... context); - - /** - * Extracts the first object of a given type from a verification input object. + * @param message description of verification context */ - default T extract(Class type, Object input) { - if (type.isInstance(input)) { - return type.cast(input); - } - if (input instanceof Object[]) { - for (Object nestedContext : (Object[]) input) { - T object = extract(type, nestedContext); - if (object != null) { - return object; - } - } - } - return null; - } + void verify(Object object, String message); } diff -r 34ac3ddfd5ac -r 281c30cf1952 graal/com.oracle.graal.debug/src/com/oracle/graal/debug/internal/DebugScope.java --- a/graal/com.oracle.graal.debug/src/com/oracle/graal/debug/internal/DebugScope.java Mon Jun 30 17:27:35 2014 +0200 +++ b/graal/com.oracle.graal.debug/src/com/oracle/graal/debug/internal/DebugScope.java Mon Jun 30 18:17:13 2014 +0200 @@ -218,14 +218,15 @@ } /** - * @see Debug#verify(Object, Object) + * @see Debug#verify(Object, String) */ - public void verify(Object object, Object... ctx) { + public void verify(Object object, String formatString, Object... args) { if (isVerifyEnabled()) { DebugConfig config = getConfig(); if (config != null) { + String message = String.format(formatString, args); for (DebugVerifyHandler handler : config.verifyHandlers()) { - handler.verify(object, ctx); + handler.verify(object, message); } } } diff -r 34ac3ddfd5ac -r 281c30cf1952 graal/com.oracle.graal.graph/src/com/oracle/graal/graph/Graph.java --- a/graal/com.oracle.graal.graph/src/com/oracle/graal/graph/Graph.java Mon Jun 30 17:27:35 2014 +0200 +++ b/graal/com.oracle.graal.graph/src/com/oracle/graal/graph/Graph.java Mon Jun 30 18:17:13 2014 +0200 @@ -26,7 +26,6 @@ import com.oracle.graal.compiler.common.*; import com.oracle.graal.debug.*; -import com.oracle.graal.graph.GraphEvent.NodeEvent; import com.oracle.graal.graph.Node.ValueNumberable; import com.oracle.graal.graph.NodeClass.NodeClassIterator; import com.oracle.graal.graph.NodeClass.Position; @@ -39,8 +38,6 @@ public final String name; - private static final boolean TIME_TRAVEL = false; - /** * The set of nodes in the graph, ordered by {@linkplain #register(Node) registration} time. */ @@ -67,7 +64,6 @@ private final ArrayList nodeCacheLast; private int nodesDeletedSinceLastCompression; private int nodesDeletedBeforeLastCompression; - private GraphEventLog eventLog; /** * The number of times this graph has been compressed. @@ -302,16 +298,46 @@ } /** + * The type of events sent to a {@link NodeEventListener}. + */ + public enum NodeEvent { + /** + * A node's input is changed. + */ + INPUT_CHANGED, + + /** + * A node's {@linkplain Node#usages() usages} count dropped to zero. + */ + ZERO_USAGES, + + /** + * A node was added to a graph. + */ + NODE_ADDED; + } + + /** * Client interested in one or more node related events. */ public interface NodeEventListener { /** + * Default handler for events. + * + * @param e an event + * @param node the node related to {@code e} + */ + default void event(NodeEvent e, Node node) { + } + + /** * Notifies this listener of a change in a node's inputs. * * @param node a node who has had one of its inputs changed */ default void inputChanged(Node node) { + event(NodeEvent.INPUT_CHANGED, node); } /** @@ -320,6 +346,7 @@ * @param node a node whose {@link Node#usages()} just became empty */ default void usagesDroppedToZero(Node node) { + event(NodeEvent.ZERO_USAGES, node); } /** @@ -328,6 +355,7 @@ * @param node a node that was just added to the graph */ default void nodeAdded(Node node) { + event(NodeEvent.NODE_ADDED, node); } } @@ -375,8 +403,8 @@ } public void usagesDroppedToZero(Node node) { - head.inputChanged(node); - next.inputChanged(node); + head.usagesDroppedToZero(node); + next.usagesDroppedToZero(node); } } @@ -851,36 +879,11 @@ if (nodeEventListener != null) { nodeEventListener.nodeAdded(node); } - logNodeAdded(node); - } - - void logNodeAdded(Node node) { - if (TIME_TRAVEL) { - log(new GraphEvent.NodeEvent(node, GraphEvent.NodeEvent.Type.ADDED)); - } - } - - void logNodeDeleted(Node node) { - if (TIME_TRAVEL) { - log(new GraphEvent.NodeEvent(node, GraphEvent.NodeEvent.Type.DELETED)); - } - } - - private void log(NodeEvent nodeEvent) { - if (eventLog == null) { - eventLog = new GraphEventLog(); - } - eventLog.add(nodeEvent); - } - - public GraphEventLog getEventLog() { - return eventLog; } void unregister(Node node) { assert !isFrozen(); assert !node.isDeleted() : "cannot delete a node twice! node=" + node; - logNodeDeleted(node); nodes[node.id] = null; nodesDeletedSinceLastCompression++; diff -r 34ac3ddfd5ac -r 281c30cf1952 graal/com.oracle.graal.graph/src/com/oracle/graal/graph/GraphEvent.java --- a/graal/com.oracle.graal.graph/src/com/oracle/graal/graph/GraphEvent.java Mon Jun 30 17:27:35 2014 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,102 +0,0 @@ -/* - * Copyright (c) 2011, 2011, 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.graph; - -import java.io.*; - -public abstract class GraphEvent { - - private Exception exceptionContext; - - public static class NodeEvent extends GraphEvent { - - public static enum Type { - ADDED, - DELETED, - CHANGED - } - - public final Node node; - public final Type type; - private final String nodeString; - - public NodeEvent(Node n, Type type) { - this.node = n; - this.type = type; - nodeString = n.toString(); - } - - @Override - public StackTraceElement[] print(StackTraceElement[] last, PrintStream stream) { - stream.println(type.toString() + ", " + nodeString); - return super.print(last, stream); - } - } - - public static class EdgeEvent extends GraphEvent { - - public static enum Type { - INPUT, - SUCC - } - - public final Node node; - public final int index; - public final Node newValue; - public final Type type; - - public EdgeEvent(Node node, int index, Node newValue, Type type) { - this.node = node; - this.index = index; - this.newValue = newValue; - this.type = type; - } - } - - public GraphEvent() { - exceptionContext = new Exception(); - } - - public StackTraceElement[] print(StackTraceElement[] last, PrintStream stream) { - StackTraceElement[] stackTrace = exceptionContext.getStackTrace(); - - boolean atTop = true; - for (int i = 0; i < stackTrace.length; ++i) { - StackTraceElement elem = stackTrace[i]; - int toBottom = stackTrace.length - i; - if (atTop) { - if (!elem.getClassName().startsWith("com.oracle.graal.graph.Graph") && !elem.getClassName().startsWith("com.oracle.graal.graph.Node")) { - atTop = false; - } else { - continue; - } - } else { - if (last.length >= toBottom && last[last.length - toBottom].equals(elem)) { - continue; - } - } - stream.println(String.format("%s.%s(%s:%d)", elem.getClassName(), elem.getMethodName(), elem.getFileName(), elem.getLineNumber())); - } - return stackTrace; - } -} diff -r 34ac3ddfd5ac -r 281c30cf1952 graal/com.oracle.graal.graph/src/com/oracle/graal/graph/GraphEventLog.java --- a/graal/com.oracle.graal.graph/src/com/oracle/graal/graph/GraphEventLog.java Mon Jun 30 17:27:35 2014 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,42 +0,0 @@ -/* - * Copyright (c) 2011, 2011, 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.graph; - -import java.io.*; -import java.util.*; - -public class GraphEventLog { - - private List events = new ArrayList<>(); - - public void add(GraphEvent e) { - this.events.add(e); - } - - public void printEvents(PrintStream stream) { - StackTraceElement[] last = new StackTraceElement[0]; - for (GraphEvent e : events) { - last = e.print(last, stream); - } - } -} diff -r 34ac3ddfd5ac -r 281c30cf1952 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/ClassCastNode.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/ClassCastNode.java Mon Jun 30 17:27:35 2014 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/ClassCastNode.java Mon Jun 30 18:17:13 2014 +0200 @@ -34,7 +34,7 @@ * * @see ClassSubstitutions#cast(Class, Object) */ -public class ClassCastNode extends MacroNode implements Canonicalizable.Binary { +public class ClassCastNode extends MacroStateSplitNode implements Canonicalizable.Binary { public ClassCastNode(Invoke invoke) { super(invoke); diff -r 34ac3ddfd5ac -r 281c30cf1952 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/ClassGetClassLoader0Node.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/ClassGetClassLoader0Node.java Mon Jun 30 17:27:35 2014 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/ClassGetClassLoader0Node.java Mon Jun 30 18:17:13 2014 +0200 @@ -35,7 +35,7 @@ * @see ClassSubstitutions#getClassLoader0(Class) */ @SuppressWarnings("javadoc") -public class ClassGetClassLoader0Node extends MacroNode implements Canonicalizable { +public class ClassGetClassLoader0Node extends MacroStateSplitNode implements Canonicalizable { public ClassGetClassLoader0Node(Invoke invoke) { super(invoke); diff -r 34ac3ddfd5ac -r 281c30cf1952 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/ArrayCopyNode.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/ArrayCopyNode.java Mon Jun 30 17:27:35 2014 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/ArrayCopyNode.java Mon Jun 30 18:17:13 2014 +0200 @@ -38,7 +38,7 @@ import com.oracle.graal.phases.tiers.*; import com.oracle.graal.replacements.nodes.*; -public class ArrayCopyNode extends MacroNode implements Virtualizable, Lowerable { +public class ArrayCopyNode extends MacroStateSplitNode implements Virtualizable, Lowerable { public ArrayCopyNode(Invoke invoke) { super(invoke); diff -r 34ac3ddfd5ac -r 281c30cf1952 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/CallSiteTargetNode.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/CallSiteTargetNode.java Mon Jun 30 17:27:35 2014 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/CallSiteTargetNode.java Mon Jun 30 18:17:13 2014 +0200 @@ -33,7 +33,7 @@ import com.oracle.graal.nodes.spi.*; import com.oracle.graal.replacements.nodes.*; -public class CallSiteTargetNode extends MacroNode implements Canonicalizable, Lowerable { +public class CallSiteTargetNode extends MacroStateSplitNode implements Canonicalizable, Lowerable { public CallSiteTargetNode(Invoke invoke) { super(invoke); diff -r 34ac3ddfd5ac -r 281c30cf1952 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/MethodHandleNode.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/MethodHandleNode.java Mon Jun 30 17:27:35 2014 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/MethodHandleNode.java Mon Jun 30 18:17:13 2014 +0200 @@ -44,7 +44,7 @@ /** * Node for invocation methods defined on the class {@link MethodHandle}. */ -public class MethodHandleNode extends MacroNode implements Simplifiable { +public class MethodHandleNode extends MacroStateSplitNode implements Simplifiable { /** The method that this node is representing. */ private final IntrinsicMethod intrinsicMethod; diff -r 34ac3ddfd5ac -r 281c30cf1952 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/ObjectCloneNode.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/ObjectCloneNode.java Mon Jun 30 17:27:35 2014 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/ObjectCloneNode.java Mon Jun 30 18:17:13 2014 +0200 @@ -39,7 +39,7 @@ import com.oracle.graal.nodes.virtual.*; import com.oracle.graal.replacements.nodes.*; -public class ObjectCloneNode extends MacroNode implements VirtualizableAllocation, ArrayLengthProvider { +public class ObjectCloneNode extends MacroStateSplitNode implements VirtualizableAllocation, ArrayLengthProvider { public ObjectCloneNode(Invoke invoke) { super(invoke); @@ -107,7 +107,7 @@ /* * Looks at the given stamp and determines if it is an exact type (or can be assumed to be an * exact type) and if it is a cloneable type. - * + * * If yes, then the exact type is returned, otherwise it returns null. */ private static ResolvedJavaType getConcreteType(Stamp stamp, Assumptions assumptions, MetaAccessProvider metaAccess) { diff -r 34ac3ddfd5ac -r 281c30cf1952 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/ReflectionGetCallerClassNode.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/ReflectionGetCallerClassNode.java Mon Jun 30 17:27:35 2014 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/ReflectionGetCallerClassNode.java Mon Jun 30 18:17:13 2014 +0200 @@ -33,7 +33,7 @@ import com.oracle.graal.nodes.spi.*; import com.oracle.graal.replacements.nodes.*; -public class ReflectionGetCallerClassNode extends MacroNode implements Canonicalizable, Lowerable { +public class ReflectionGetCallerClassNode extends MacroStateSplitNode implements Canonicalizable, Lowerable { public ReflectionGetCallerClassNode(Invoke invoke) { super(invoke); diff -r 34ac3ddfd5ac -r 281c30cf1952 graal/com.oracle.graal.lir.test/src/com/oracle/graal/lir/test/ValuePositionTest1.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.lir.test/src/com/oracle/graal/lir/test/ValuePositionTest1.java Mon Jun 30 18:17:13 2014 +0200 @@ -0,0 +1,171 @@ +/* + * Copyright (c) 2014, 2014, 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.lir.test; + +import static com.oracle.graal.lir.LIRInstruction.OperandFlag.*; +import static org.junit.Assert.*; + +import java.util.*; + +import org.junit.*; + +import com.oracle.graal.api.meta.*; +import com.oracle.graal.lir.*; +import com.oracle.graal.lir.LIRInstruction.OperandFlag; +import com.oracle.graal.lir.LIRInstruction.ValuePositionProcedure; +import com.oracle.graal.lir.asm.*; + +public class ValuePositionTest1 { + + private static class NestedCompositeValue extends CompositeValue { + + private static final long serialVersionUID = -8804214200173503527L; + @Component({REG, OperandFlag.ILLEGAL}) protected Value value; + + public NestedCompositeValue(Value value) { + super(LIRKind.Illegal); + this.value = value; + } + + } + + private static class DummyValue extends Value { + + private static final long serialVersionUID = -645435039553382737L; + private final int id; + private static int counter = 1; + + protected DummyValue() { + super(LIRKind.Illegal); + this.id = counter++; + } + + @Override + public int hashCode() { + final int prime = 31; + int result = super.hashCode(); + result = prime * result + id; + return result; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (!super.equals(obj)) { + return false; + } + if (getClass() != obj.getClass()) { + return false; + } + DummyValue other = (DummyValue) obj; + if (id != other.id) { + return false; + } + return true; + } + } + + private static class TestOp extends LIRInstruction { + + @Use({COMPOSITE}) protected NestedCompositeValue compValue; + + public TestOp(NestedCompositeValue compValue) { + this.compValue = compValue; + } + + @Override + public void emitCode(CompilationResultBuilder crb) { + fail("should not reach!"); + } + + } + + private static LIRInstruction createNestedOp(Value value, int nestingLevel) { + NestedCompositeValue compValue = new NestedCompositeValue(value); + for (int i = 0; i < nestingLevel; i++) { + compValue = new NestedCompositeValue(compValue); + } + TestOp op = new TestOp(compValue); + return op; + } + + @Test + public void nestedTest0() { + DummyValue dummyValue = new DummyValue(); + LIRInstruction op = createNestedOp(dummyValue, 0); + + List positions = new ArrayList<>(); + + op.forEachInput(new ValuePositionProcedure() { + + @Override + public void doValue(LIRInstruction instruction, ValuePosition position) { + positions.add(position); + } + }); + + assertEquals(1, positions.size()); + assertEquals(dummyValue, positions.get(0).get(op)); + } + + @Test + public void nestedTest1() { + DummyValue dummyValue = new DummyValue(); + LIRInstruction op = createNestedOp(dummyValue, 1); + + List positions = new ArrayList<>(); + + op.forEachInput(new ValuePositionProcedure() { + + @Override + public void doValue(LIRInstruction instruction, ValuePosition position) { + positions.add(position); + } + }); + + assertEquals(1, positions.size()); + assertEquals(dummyValue, positions.get(0).get(op)); + } + + @Test + public void nestedTest2() { + DummyValue dummyValue = new DummyValue(); + LIRInstruction op = createNestedOp(dummyValue, 2); + + List positions = new ArrayList<>(); + + op.forEachInput(new ValuePositionProcedure() { + + @Override + public void doValue(LIRInstruction instruction, ValuePosition position) { + positions.add(position); + } + }); + + assertEquals(1, positions.size()); + assertEquals(dummyValue, positions.get(0).get(op)); + } + +} diff -r 34ac3ddfd5ac -r 281c30cf1952 graal/com.oracle.graal.lir.test/src/com/oracle/graal/lir/test/ValuePositionTest2.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.lir.test/src/com/oracle/graal/lir/test/ValuePositionTest2.java Mon Jun 30 18:17:13 2014 +0200 @@ -0,0 +1,149 @@ +/* + * Copyright (c) 2014, 2014, 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.lir.test; + +import static com.oracle.graal.lir.LIRInstruction.OperandFlag.*; +import static org.junit.Assert.*; + +import java.util.*; + +import org.junit.*; + +import com.oracle.graal.api.meta.*; +import com.oracle.graal.lir.*; +import com.oracle.graal.lir.LIRInstruction.OperandFlag; +import com.oracle.graal.lir.LIRInstruction.ValuePositionProcedure; +import com.oracle.graal.lir.asm.*; + +public class ValuePositionTest2 { + + private static class NestedCompositeValue extends CompositeValue { + + private static final long serialVersionUID = -2243948303328857965L; + @Component({REG, OperandFlag.ILLEGAL}) protected Value value1; + @Component({REG, OperandFlag.ILLEGAL}) protected Value value2; + + public NestedCompositeValue(Value value1, Value value2) { + super(LIRKind.Illegal); + this.value1 = value1; + this.value2 = value2; + } + + } + + private static class DummyValue extends Value { + + private static final long serialVersionUID = 3620305384660607012L; + private final int id; + private static int counter = 0; + + protected DummyValue() { + super(LIRKind.Illegal); + this.id = counter++; + } + + @Override + public int hashCode() { + final int prime = 31; + int result = super.hashCode(); + result = prime * result + id; + return result; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (!super.equals(obj)) { + return false; + } + if (getClass() != obj.getClass()) { + return false; + } + DummyValue other = (DummyValue) obj; + if (id != other.id) { + return false; + } + return true; + } + } + + private static class TestOp extends LIRInstruction { + + @Use({COMPOSITE}) protected NestedCompositeValue compValue; + + public TestOp(NestedCompositeValue compValue) { + this.compValue = compValue; + } + + @Override + public void emitCode(CompilationResultBuilder crb) { + fail("should not reach!"); + } + + } + + @Test + public void testSetGet() { + DummyValue dummyValue0 = new DummyValue(); + DummyValue dummyValue1 = new DummyValue(); + DummyValue dummyValue2 = new DummyValue(); + DummyValue dummyValue3 = new DummyValue(); + + NestedCompositeValue compValue0 = new NestedCompositeValue(dummyValue0, dummyValue1); + NestedCompositeValue compValue1 = new NestedCompositeValue(compValue0, dummyValue2); + NestedCompositeValue compValue2 = new NestedCompositeValue(dummyValue3, compValue1); + + LIRInstruction op = new TestOp(compValue2); + List positions = new ArrayList<>(); + + op.forEachInput(new ValuePositionProcedure() { + + @Override + public void doValue(LIRInstruction instruction, ValuePosition position) { + positions.add(position); + } + }); + + assertEquals(4, positions.size()); + + // replace values + List replValues = new ArrayList<>(); + for (ValuePosition pos : positions) { + Value v = new DummyValue(); + replValues.add(v); + pos.set(op, v); + + } + + // check replaced values + Iterator it = replValues.iterator(); + for (ValuePosition pos : positions) { + Value v = pos.get(op); + assertEquals(it.next(), v); + } + assertFalse(it.hasNext()); + } + +} diff -r 34ac3ddfd5ac -r 281c30cf1952 graal/com.oracle.graal.lir/src/com/oracle/graal/lir/CompositeValue.java --- a/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/CompositeValue.java Mon Jun 30 17:27:35 2014 +0200 +++ b/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/CompositeValue.java Mon Jun 30 18:17:13 2014 +0200 @@ -29,6 +29,7 @@ import com.oracle.graal.lir.LIRInstruction.InstructionValueProcedure; import com.oracle.graal.lir.LIRInstruction.OperandFlag; import com.oracle.graal.lir.LIRInstruction.OperandMode; +import com.oracle.graal.lir.LIRInstruction.ValuePositionProcedure; /** * Base class to represent values that need to be stored in more than one register. @@ -58,6 +59,10 @@ valueClass.forEachComponent(inst, this, mode, proc); } + public final void forEachComponent(LIRInstruction inst, OperandMode mode, ValuePositionProcedure proc, ValuePosition outerPosition) { + valueClass.forEachComponent(inst, this, mode, proc, outerPosition); + } + @Override public String toString() { return valueClass.toString(this); @@ -76,4 +81,9 @@ } return false; } + + CompositeValueClass getValueClass() { + return valueClass; + } + } diff -r 34ac3ddfd5ac -r 281c30cf1952 graal/com.oracle.graal.lir/src/com/oracle/graal/lir/CompositeValueClass.java --- a/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/CompositeValueClass.java Mon Jun 30 17:27:35 2014 +0200 +++ b/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/CompositeValueClass.java Mon Jun 30 18:17:13 2014 +0200 @@ -25,11 +25,13 @@ import java.lang.reflect.*; import java.util.*; +import com.oracle.graal.api.meta.*; import com.oracle.graal.compiler.common.*; import com.oracle.graal.lir.CompositeValue.Component; import com.oracle.graal.lir.LIRInstruction.InstructionValueProcedure; import com.oracle.graal.lir.LIRInstruction.OperandFlag; import com.oracle.graal.lir.LIRInstruction.OperandMode; +import com.oracle.graal.lir.LIRInstruction.ValuePositionProcedure; /** * Lazily associated metadata for every {@link CompositeValue} type. The metadata includes: @@ -143,6 +145,10 @@ forEach(inst, obj, directComponentCount, componentOffsets, mode, componentFlags, proc); } + public final void forEachComponent(LIRInstruction inst, CompositeValue obj, OperandMode mode, ValuePositionProcedure proc, ValuePosition outerPosition) { + forEach(inst, obj, directComponentCount, componentOffsets, mode, componentFlags, proc, outerPosition); + } + public String toString(CompositeValue obj) { StringBuilder result = new StringBuilder(); @@ -154,4 +160,16 @@ return result.toString(); } + + Value getValue(CompositeValue obj, ValuePosition pos) { + return getValueForPosition(obj, componentOffsets, directComponentCount, pos); + } + + void setValue(CompositeValue obj, ValuePosition pos, Value value) { + setValueForPosition(obj, componentOffsets, directComponentCount, pos, value); + } + + EnumSet getFlags(ValuePosition pos) { + return componentFlags[pos.getIndex()]; + } } diff -r 34ac3ddfd5ac -r 281c30cf1952 graal/com.oracle.graal.lir/src/com/oracle/graal/lir/LIRInstruction.java --- a/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/LIRInstruction.java Mon Jun 30 17:27:35 2014 +0200 +++ b/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/LIRInstruction.java Mon Jun 30 18:17:13 2014 +0200 @@ -42,6 +42,22 @@ public static final Value[] NO_OPERANDS = {}; /** + * Iterator for iterating over a list of {@linkplain ValuePosition value positions}. + */ + public abstract static class ValuePositionProcedure { + + /** + * Iterator method to be overwritten. This version of the iterator does not take additional + * parameters to keep the signature short. + * + * @param instruction The current instruction. + * @param position The position of the value that is iterated. + */ + + public abstract void doValue(LIRInstruction instruction, ValuePosition position); + } + + /** * Iterator for iterating over a list of values. Subclasses must overwrite one of the doValue * methods. Clients of the class must only call the doValue method that takes additional * parameters. @@ -297,6 +313,22 @@ return false; } + public final void forEachInput(ValuePositionProcedure proc) { + instructionClass.forEachUse(this, proc); + } + + public final void forEachAlive(ValuePositionProcedure proc) { + instructionClass.forEachAlive(this, proc); + } + + public final void forEachTemp(ValuePositionProcedure proc) { + instructionClass.forEachTemp(this, proc); + } + + public final void forEachOutput(ValuePositionProcedure proc) { + instructionClass.forEachDef(this, proc); + } + public final void forEachInput(InstructionValueProcedure proc) { instructionClass.forEachUse(this, proc); } @@ -354,4 +386,8 @@ public String toString() { return instructionClass.toString(this); } + + public LIRInstructionClass getLIRInstructionClass() { + return instructionClass; + } } diff -r 34ac3ddfd5ac -r 281c30cf1952 graal/com.oracle.graal.lir/src/com/oracle/graal/lir/LIRInstructionClass.java --- a/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/LIRInstructionClass.java Mon Jun 30 17:27:35 2014 +0200 +++ b/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/LIRInstructionClass.java Mon Jun 30 18:17:13 2014 +0200 @@ -32,6 +32,7 @@ import com.oracle.graal.lir.LIRInstruction.OperandFlag; import com.oracle.graal.lir.LIRInstruction.OperandMode; import com.oracle.graal.lir.LIRInstruction.StateProcedure; +import com.oracle.graal.lir.LIRInstruction.ValuePositionProcedure; public class LIRInstructionClass extends LIRIntrospection { @@ -241,6 +242,73 @@ return str.toString(); } + Value getValue(LIRInstruction obj, ValuePosition pos) { + long[] offsets; + int directCount; + switch (pos.getMode()) { + case USE: + directCount = directUseCount; + offsets = useOffsets; + break; + case ALIVE: + directCount = directAliveCount; + offsets = aliveOffsets; + break; + case TEMP: + directCount = directTempCount; + offsets = tempOffsets; + break; + case DEF: + directCount = directDefCount; + offsets = defOffsets; + break; + default: + throw GraalInternalError.shouldNotReachHere("unkown OperandMode: " + pos.getMode()); + } + return getValueForPosition(obj, offsets, directCount, pos); + } + + void setValue(LIRInstruction obj, ValuePosition pos, Value value) { + long[] offsets; + int directCount; + switch (pos.getMode()) { + case USE: + directCount = directUseCount; + offsets = useOffsets; + break; + case ALIVE: + directCount = directAliveCount; + offsets = aliveOffsets; + break; + case TEMP: + directCount = directTempCount; + offsets = tempOffsets; + break; + case DEF: + directCount = directDefCount; + offsets = defOffsets; + break; + default: + throw GraalInternalError.shouldNotReachHere("unkown OperandMode: " + pos.getMode()); + } + setValueForPosition(obj, offsets, directCount, pos, value); + } + + EnumSet getFlags(ValuePosition pos) { + switch (pos.getMode()) { + case USE: + return useFlags[pos.getIndex()]; + case ALIVE: + return aliveFlags[pos.getIndex()]; + case TEMP: + return tempFlags[pos.getIndex()]; + case DEF: + return defFlags[pos.getIndex()]; + default: + throw GraalInternalError.shouldNotReachHere("unkown OperandMode: " + pos.getMode()); + } + } + public final String getOpcode(LIRInstruction obj) { if (opcodeConstant != null) { return opcodeConstant; @@ -262,6 +330,22 @@ return false; } + public final void forEachUse(LIRInstruction obj, ValuePositionProcedure proc) { + forEach(obj, obj, directUseCount, useOffsets, OperandMode.USE, useFlags, proc, ValuePosition.ROOT_VALUE_POSITION); + } + + public final void forEachAlive(LIRInstruction obj, ValuePositionProcedure proc) { + forEach(obj, obj, directAliveCount, aliveOffsets, OperandMode.ALIVE, aliveFlags, proc, ValuePosition.ROOT_VALUE_POSITION); + } + + public final void forEachTemp(LIRInstruction obj, ValuePositionProcedure proc) { + forEach(obj, obj, directTempCount, tempOffsets, OperandMode.TEMP, tempFlags, proc, ValuePosition.ROOT_VALUE_POSITION); + } + + public final void forEachDef(LIRInstruction obj, ValuePositionProcedure proc) { + forEach(obj, obj, directDefCount, defOffsets, OperandMode.DEF, defFlags, proc, ValuePosition.ROOT_VALUE_POSITION); + } + public final void forEachUse(LIRInstruction obj, InstructionValueProcedure proc) { forEach(obj, obj, directUseCount, useOffsets, OperandMode.USE, useFlags, proc); } diff -r 34ac3ddfd5ac -r 281c30cf1952 graal/com.oracle.graal.lir/src/com/oracle/graal/lir/LIRIntrospection.java --- a/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/LIRIntrospection.java Mon Jun 30 17:27:35 2014 +0200 +++ b/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/LIRIntrospection.java Mon Jun 30 18:17:13 2014 +0200 @@ -35,6 +35,7 @@ import com.oracle.graal.lir.LIRInstruction.InstructionValueProcedure; import com.oracle.graal.lir.LIRInstruction.OperandFlag; import com.oracle.graal.lir.LIRInstruction.OperandMode; +import com.oracle.graal.lir.LIRInstruction.ValuePositionProcedure; abstract class LIRIntrospection extends FieldIntrospection { @@ -146,6 +147,49 @@ } } + protected static void forEach(LIRInstruction inst, Object obj, int directCount, long[] offsets, OperandMode mode, EnumSet[] flags, ValuePositionProcedure proc, + ValuePosition outerPosition) { + for (int i = 0; i < offsets.length; i++) { + assert LIRInstruction.ALLOWED_FLAGS.get(mode).containsAll(flags[i]); + + if (i < directCount) { + Value value = getValue(obj, offsets[i]); + doForValue(inst, mode, proc, outerPosition, i, ValuePosition.NO_SUBINDEX, value); + } else { + Value[] values = getValueArray(obj, offsets[i]); + for (int j = 0; j < values.length; j++) { + Value value = values[j]; + doForValue(inst, mode, proc, outerPosition, i, j, value); + } + } + } + } + + private static void doForValue(LIRInstruction inst, OperandMode mode, ValuePositionProcedure proc, ValuePosition outerPosition, int index, int subIndex, Value value) { + ValuePosition position = new ValuePosition(mode, index, subIndex, outerPosition); + if (value instanceof CompositeValue) { + CompositeValue composite = (CompositeValue) value; + composite.forEachComponent(inst, mode, proc, position); + } else { + proc.doValue(inst, position); + } + } + + protected static Value getValueForPosition(Object obj, long[] offsets, int directCount, ValuePosition pos) { + if (pos.getIndex() < directCount) { + return getValue(obj, offsets[pos.getIndex()]); + } + return getValueArray(obj, offsets[pos.getIndex()])[pos.getSubIndex()]; + } + + protected static void setValueForPosition(Object obj, long[] offsets, int directCount, ValuePosition pos, Value value) { + if (pos.getIndex() < directCount) { + setValue(obj, offsets[pos.getIndex()], value); + } else { + getValueArray(obj, offsets[pos.getIndex()])[pos.getSubIndex()] = value; + } + } + protected static Value getValue(Object obj, long offset) { return (Value) unsafe.getObject(obj, offset); } diff -r 34ac3ddfd5ac -r 281c30cf1952 graal/com.oracle.graal.lir/src/com/oracle/graal/lir/ValuePosition.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/ValuePosition.java Mon Jun 30 18:17:13 2014 +0200 @@ -0,0 +1,145 @@ +/* + * Copyright (c) 2014, 2014, 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.lir; + +import java.util.*; + +import com.oracle.graal.api.meta.*; +import com.oracle.graal.lir.LIRInstruction.*; + +/** + * Describes an operand slot for a {@link LIRInstructionClass}. + */ +public final class ValuePosition { + + private final OperandMode mode; + private final int index; + private final int subIndex; + private final ValuePosition outerPosition; + + public static final int NO_SUBINDEX = -1; + public static final ValuePosition ROOT_VALUE_POSITION = null; + + public ValuePosition(OperandMode mode, int index, int subIndex, ValuePosition outerPosition) { + this.mode = mode; + this.index = index; + this.subIndex = subIndex; + this.outerPosition = outerPosition; + } + + public boolean isCompositePosition() { + return outerPosition != ROOT_VALUE_POSITION; + } + + public Value get(LIRInstruction inst) { + if (isCompositePosition()) { + CompositeValue compValue = (CompositeValue) outerPosition.get(inst); + return compValue.getValueClass().getValue(compValue, this); + } + return inst.getLIRInstructionClass().getValue(inst, this); + } + + public EnumSet getFlags(LIRInstruction inst) { + if (isCompositePosition()) { + CompositeValue compValue = (CompositeValue) outerPosition.get(inst); + return compValue.getValueClass().getFlags(this); + } + return inst.getLIRInstructionClass().getFlags(this); + } + + public void set(LIRInstruction inst, Value value) { + if (isCompositePosition()) { + CompositeValue compValue = (CompositeValue) outerPosition.get(inst); + compValue.getValueClass().setValue(compValue, this, value); + } else { + inst.getLIRInstructionClass().setValue(inst, this, value); + } + } + + public int getSubIndex() { + return subIndex; + } + + public int getIndex() { + return index; + } + + public OperandMode getMode() { + return mode; + } + + public ValuePosition getSuperPosition() { + return outerPosition; + } + + @Override + public String toString() { + if (outerPosition == ROOT_VALUE_POSITION) { + return mode.toString() + "(" + index + (subIndex < 0 ? "" : "/" + subIndex) + ")"; + } + return outerPosition.toString() + "[" + mode.toString() + "(" + index + (subIndex < 0 ? "" : "/" + subIndex) + ")]"; + } + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + index; + result = prime * result + ((mode == null) ? 0 : mode.hashCode()); + result = prime * result + subIndex; + result = prime * result + ((outerPosition == null) ? 0 : outerPosition.hashCode()); + return result; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (obj == null) { + return false; + } + if (getClass() != obj.getClass()) { + return false; + } + ValuePosition other = (ValuePosition) obj; + if (index != other.index) { + return false; + } + if (mode != other.mode) { + return false; + } + if (subIndex != other.subIndex) { + return false; + } + if (outerPosition == null) { + if (other.outerPosition != null) { + return false; + } + } else if (!outerPosition.equals(other.outerPosition)) { + return false; + } + return true; + } + +} diff -r 34ac3ddfd5ac -r 281c30cf1952 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/MergeNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/MergeNode.java Mon Jun 30 17:27:35 2014 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/MergeNode.java Mon Jun 30 18:17:13 2014 +0200 @@ -163,6 +163,9 @@ int numEnds = this.forwardEndCount(); for (int i = 0; i < numEnds - 1; i++) { AbstractEndNode end = forwardEndAt(numEnds - 1 - i); + if (tool != null) { + tool.addToWorkList(end); + } AbstractEndNode newEnd; if (merge instanceof LoopBeginNode) { newEnd = graph().add(new LoopEndNode((LoopBeginNode) merge)); @@ -207,6 +210,9 @@ List endNodes = forwardEnds().snapshot(); for (AbstractEndNode end : endNodes) { ReturnNode newReturn = graph().add(new ReturnNode(returnValuePhi == null ? returnNode.result() : returnValuePhi.valueAt(end))); + if (tool != null) { + tool.addToWorkList(end.predecessor()); + } end.replaceAtPredecessor(newReturn); } GraphUtil.killCFG(this); diff -r 34ac3ddfd5ac -r 281c30cf1952 graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/IterativeConditionalEliminationPhase.java --- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/IterativeConditionalEliminationPhase.java Mon Jun 30 17:27:35 2014 +0200 +++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/IterativeConditionalEliminationPhase.java Mon Jun 30 18:17:13 2014 +0200 @@ -22,6 +22,8 @@ */ package com.oracle.graal.phases.common; +import static com.oracle.graal.graph.Graph.NodeEvent.*; + import com.oracle.graal.api.code.*; import com.oracle.graal.graph.*; import com.oracle.graal.graph.Graph.*; @@ -44,7 +46,7 @@ @Override protected void run(StructuredGraph graph, PhaseContext context) { ConditionalEliminationPhase eliminate = new ConditionalEliminationPhase(context.getMetaAccess()); - HashSetNodeEventListener listener = new HashSetNodeEventListener.ExceptForAddedNodes(); + HashSetNodeEventListener listener = new HashSetNodeEventListener().exclude(NODE_ADDED); int count = 0; while (true) { try (NodeEventScope nes = graph.trackNodeEvents(listener)) { diff -r 34ac3ddfd5ac -r 281c30cf1952 graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/cfs/IterativeFlowSensitiveReductionPhase.java --- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/cfs/IterativeFlowSensitiveReductionPhase.java Mon Jun 30 17:27:35 2014 +0200 +++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/cfs/IterativeFlowSensitiveReductionPhase.java Mon Jun 30 18:17:13 2014 +0200 @@ -22,13 +22,15 @@ */ package com.oracle.graal.phases.common.cfs; +import static com.oracle.graal.graph.Graph.NodeEvent.*; + import com.oracle.graal.api.code.*; +import com.oracle.graal.graph.Graph.NodeEventScope; import com.oracle.graal.graph.*; -import com.oracle.graal.graph.Graph.*; import com.oracle.graal.graph.spi.*; import com.oracle.graal.nodes.*; import com.oracle.graal.phases.*; -import com.oracle.graal.phases.common.CanonicalizerPhase; +import com.oracle.graal.phases.common.*; import com.oracle.graal.phases.common.util.*; import com.oracle.graal.phases.tiers.*; @@ -47,7 +49,7 @@ @Override protected void run(StructuredGraph graph, PhaseContext context) { FlowSensitiveReductionPhase eliminate = new FlowSensitiveReductionPhase(context.getMetaAccess()); - HashSetNodeEventListener listener = new HashSetNodeEventListener.ExceptForAddedNodes(); + HashSetNodeEventListener listener = new HashSetNodeEventListener().exclude(NODE_ADDED); int count = 1; while (true) { try (NodeEventScope nes = graph.trackNodeEvents(listener)) { diff -r 34ac3ddfd5ac -r 281c30cf1952 graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/util/HashSetNodeEventListener.java --- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/util/HashSetNodeEventListener.java Mon Jun 30 17:27:35 2014 +0200 +++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/util/HashSetNodeEventListener.java Mon Jun 30 18:17:13 2014 +0200 @@ -24,7 +24,7 @@ import java.util.*; -import com.oracle.graal.graph.Graph.NodeEventListener; +import com.oracle.graal.graph.Graph.*; import com.oracle.graal.graph.*; /** @@ -33,36 +33,42 @@ */ public class HashSetNodeEventListener implements NodeEventListener { + private final Set nodes; + private final Set filter; + /** - * Accumulates all node events except for {@link NodeEventListener#nodeAdded(Node) node - * additions}. + * Creates a {@link NodeEventListener} that collects nodes from all events. + */ + public HashSetNodeEventListener() { + this.nodes = new HashSet<>(); + this.filter = EnumSet.allOf(NodeEvent.class); + } + + /** + * Creates a {@link NodeEventListener} that collects nodes from all events that match a given + * filter. */ - public static class ExceptForAddedNodes extends HashSetNodeEventListener { - @Override - public void nodeAdded(Node node) { + public HashSetNodeEventListener(Set filter) { + this.nodes = new HashSet<>(); + this.filter = filter; + } + + /** + * Excludes a given event from those for which nodes are collected. + */ + public HashSetNodeEventListener exclude(NodeEvent e) { + filter.remove(e); + return this; + } + + public void event(NodeEvent e, Node node) { + if (filter.contains(e)) { + nodes.add(node); } } - private final Set nodes; - - public HashSetNodeEventListener() { - this.nodes = new HashSet<>(); - } - - public void nodeAdded(Node node) { - nodes.add(node); - } - - public void inputChanged(Node node) { - nodes.add(node); - } - - public void usagesDroppedToZero(Node node) { - nodes.add(node); - } - /** - * Gets the set of nodes that were communicated to this listener. + * Gets the set being used to accumulate the nodes communicated to this listener. */ public Set getNodes() { return nodes; diff -r 34ac3ddfd5ac -r 281c30cf1952 graal/com.oracle.graal.phases/src/com/oracle/graal/phases/BasePhase.java --- a/graal/com.oracle.graal.phases/src/com/oracle/graal/phases/BasePhase.java Mon Jun 30 17:27:35 2014 +0200 +++ b/graal/com.oracle.graal.phases/src/com/oracle/graal/phases/BasePhase.java Mon Jun 30 18:17:13 2014 +0200 @@ -101,7 +101,7 @@ Debug.dump(graph, "After phase %s", getName()); } if (Debug.isVerifyEnabled()) { - Debug.verify(graph, this, "After phase " + getName()); + Debug.verify(graph, "After phase %s", getName()); } assert graph.verify(); } catch (Throwable t) { diff -r 34ac3ddfd5ac -r 281c30cf1952 graal/com.oracle.graal.printer/src/com/oracle/graal/printer/NoDeadCodeVerifyHandler.java --- a/graal/com.oracle.graal.printer/src/com/oracle/graal/printer/NoDeadCodeVerifyHandler.java Mon Jun 30 17:27:35 2014 +0200 +++ b/graal/com.oracle.graal.printer/src/com/oracle/graal/printer/NoDeadCodeVerifyHandler.java Mon Jun 30 18:17:13 2014 +0200 @@ -25,14 +25,12 @@ import static com.oracle.graal.printer.NoDeadCodeVerifyHandler.Options.*; import java.util.*; -import java.util.concurrent.*; import com.oracle.graal.compiler.common.*; import com.oracle.graal.debug.*; import com.oracle.graal.graph.*; import com.oracle.graal.nodes.*; import com.oracle.graal.options.*; -import com.oracle.graal.phases.*; import com.oracle.graal.phases.common.*; /** @@ -54,34 +52,24 @@ // @formatter:on } - private static final Map, Boolean> discovered = new ConcurrentHashMap<>(); - - public void verify(Object object, Object... context) { - if (NDCV.getValue() != OFF) { - StructuredGraph graph = extract(StructuredGraph.class, object); - BasePhase phase = extract(BasePhase.class, context); - assert phase != null : "a Phase context is required by " + getClass().getSimpleName(); - if (graph != null) { - List before = graph.getNodes().snapshot(); - new DeadCodeEliminationPhase().run(graph); - List after = graph.getNodes().snapshot(); - assert after.size() <= before.size(); - if (before.size() != after.size()) { - before.removeAll(after); - if (discovered.put(phase.getClass(), Boolean.TRUE) == null) { - String message = extract(String.class, context); - String prefix = message == null ? "" : message + ": "; - String phaseClass = phase.getClass().getName(); - GraalInternalError error = new GraalInternalError("%sfound dead nodes in %s (phase class=%s): %s", prefix, graph, phaseClass, before); - if (NDCV.getValue() == INFO) { - System.out.println(error.getMessage()); - } else if (NDCV.getValue() == VERBOSE) { - error.printStackTrace(System.out); - } else { - assert NDCV.getValue() == FATAL; - throw error; - } - } + public void verify(Object object, String message) { + if (NDCV.getValue() != OFF && object instanceof StructuredGraph) { + StructuredGraph graph = (StructuredGraph) object; + List before = graph.getNodes().snapshot(); + new DeadCodeEliminationPhase().run(graph); + List after = graph.getNodes().snapshot(); + assert after.size() <= before.size(); + if (before.size() != after.size()) { + before.removeAll(after); + String prefix = message == null ? "" : message + ": "; + GraalInternalError error = new GraalInternalError("%sfound dead nodes in %s: %s", prefix, graph, before); + if (NDCV.getValue() == INFO) { + System.out.println(error.getMessage()); + } else if (NDCV.getValue() == VERBOSE) { + error.printStackTrace(System.out); + } else { + assert NDCV.getValue() == FATAL; + throw error; } } } diff -r 34ac3ddfd5ac -r 281c30cf1952 graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/SnippetTemplate.java --- a/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/SnippetTemplate.java Mon Jun 30 17:27:35 2014 +0200 +++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/SnippetTemplate.java Mon Jun 30 18:17:13 2014 +0200 @@ -687,24 +687,23 @@ List returnNodes = snippet.getNodes(ReturnNode.class).snapshot(); if (returnNodes.isEmpty()) { this.returnNode = null; - this.memoryMap = null; } else if (returnNodes.size() == 1) { this.returnNode = returnNodes.get(0); - this.memoryMap = returnNode.getMemoryMap(); } else { MergeNode merge = snippet.add(new MergeNode()); List memMaps = returnNodes.stream().map(n -> n.getMemoryMap()).collect(Collectors.toList()); ValueNode returnValue = InliningUtil.mergeReturns(merge, returnNodes, null); this.returnNode = snippet.add(new ReturnNode(returnValue)); MemoryMapImpl mmap = FloatingReadPhase.mergeMemoryMaps(merge, memMaps); - this.memoryMap = snippet.unique(new MemoryMapNode(mmap.getMap())); - merge.setNext(this.returnNode); - + MemoryMapNode memoryMap = snippet.unique(new MemoryMapNode(mmap.getMap())); + this.returnNode.setMemoryMap(memoryMap); for (MemoryMapNode mm : memMaps) { - if (mm.isAlive()) { - mm.safeDelete(); + if (mm != memoryMap && mm.isAlive()) { + assert mm.usages().isEmpty(); + GraphUtil.killWithUnusedFloatingInputs(mm); } } + merge.setNext(this.returnNode); } this.sideEffectNodes = curSideEffectNodes; @@ -794,11 +793,6 @@ private final ArrayList nodes; /** - * Map of killing locations to memory checkpoints (nodes). - */ - private final MemoryMapNode memoryMap; - - /** * Times instantiations of this template. * * @see SnippetInfo#instantiationTimer @@ -957,6 +951,7 @@ // no floating reads yet, ignore locations created while lowering return true; } + MemoryMapNode memoryMap = returnNode.getMemoryMap(); if (memoryMap == null || memoryMap.isEmpty()) { // there are no kills in the snippet graph return true; @@ -1018,6 +1013,7 @@ @Override public MemoryNode getLastLocationAccess(LocationIdentity locationIdentity) { + MemoryMapNode memoryMap = returnNode.getMemoryMap(); assert memoryMap != null : "no memory map stored for this snippet graph (snippet doesn't have a ReturnNode?)"; MemoryNode lastLocationAccess = memoryMap.getLastLocationAccess(locationIdentity); assert lastLocationAccess != null; @@ -1030,7 +1026,7 @@ @Override public Collection getLocations() { - return memoryMap.getLocations(); + return returnNode.getMemoryMap().getLocations(); } } diff -r 34ac3ddfd5ac -r 281c30cf1952 graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/nodes/MacroNode.java --- a/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/nodes/MacroNode.java Mon Jun 30 17:27:35 2014 +0200 +++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/nodes/MacroNode.java Mon Jun 30 18:17:13 2014 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2014, 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 @@ -24,13 +24,13 @@ import com.oracle.graal.api.code.*; import com.oracle.graal.api.meta.*; -import com.oracle.graal.compiler.common.*; +import com.oracle.graal.api.replacements.*; +import com.oracle.graal.compiler.common.type.*; import com.oracle.graal.debug.*; import com.oracle.graal.debug.Debug.Scope; import com.oracle.graal.graph.*; import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.StructuredGraph.GuardsStage; -import com.oracle.graal.nodes.extended.*; import com.oracle.graal.nodes.java.*; import com.oracle.graal.nodes.java.MethodCallTargetNode.InvokeKind; import com.oracle.graal.nodes.spi.*; @@ -39,7 +39,22 @@ import com.oracle.graal.phases.tiers.*; import com.oracle.graal.replacements.*; -public class MacroNode extends AbstractMemoryCheckpoint implements Lowerable, MemoryCheckpoint.Single { +/** + * Macro nodes can be used to temporarily replace an invoke (usually by using the + * {@link MacroSubstitution} annotation). They can, for example, be used to implement constant + * folding for known JDK functions like {@link Class#isInterface()}.
+ *
+ * During lowering, multiple sources are queried in order to look for a replacement: + *
    + *
  • If {@link #getLoweredSnippetGraph(LoweringTool)} returns a non-null result, this graph is + * used as a replacement.
  • + *
  • If a {@link MethodSubstitution} for the target method is found, this substitution is used as + * a replacement.
  • + *
  • Otherwise, the macro node is replaced with an {@link InvokeNode}. Note that this is only + * possible if the macro node is a {@link MacroStateSplitNode}.
  • + *
+ */ +public class MacroNode extends FixedWithNextNode implements Lowerable { @Input protected final NodeInputList arguments; @@ -49,7 +64,7 @@ private final InvokeKind invokeKind; protected MacroNode(Invoke invoke) { - super(invoke.asNode().stamp(), invoke.stateAfter()); + super(StampFactory.forKind(((MethodCallTargetNode) invoke.callTarget()).targetMethod().getSignature().getReturnKind())); MethodCallTargetNode methodCallTarget = (MethodCallTargetNode) invoke.callTarget(); this.arguments = new NodeInputList<>(this, methodCallTarget.arguments()); this.bci = invoke.bci(); @@ -70,6 +85,10 @@ return returnType; } + protected FrameState stateAfter() { + return null; + } + /** * Gets a snippet to be used for lowering this macro node. The returned graph (if non-null) must * have been {@linkplain #lowerReplacement(StructuredGraph, LoweringTool) lowered}. @@ -145,6 +164,7 @@ InliningUtil.inline(invoke, replacementGraph, false, null); Debug.dump(graph(), "After inlining replacement %s", replacementGraph); } else { + assert stateAfter() != null : "cannot lower to invoke without state: " + this; invoke.lower(tool); } } @@ -166,23 +186,4 @@ } return invoke; } - - protected void replaceSnippetInvokes(StructuredGraph snippetGraph) { - for (MethodCallTargetNode call : snippetGraph.getNodes(MethodCallTargetNode.class)) { - Invoke invoke = call.invoke(); - if (!call.targetMethod().equals(getTargetMethod())) { - throw new GraalInternalError("unexpected invoke %s in snippet", getClass().getSimpleName()); - } - assert invoke.stateAfter().bci == BytecodeFrame.AFTER_BCI; - // Here we need to fix the bci of the invoke - InvokeNode newInvoke = snippetGraph.add(new InvokeNode(invoke.callTarget(), getBci())); - newInvoke.setStateAfter(invoke.stateAfter()); - snippetGraph.replaceFixedWithFixed((InvokeNode) invoke.asNode(), newInvoke); - } - } - - @Override - public LocationIdentity getLocationIdentity() { - return LocationIdentity.ANY_LOCATION; - } } diff -r 34ac3ddfd5ac -r 281c30cf1952 graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/nodes/MacroStateSplitNode.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/nodes/MacroStateSplitNode.java Mon Jun 30 18:17:13 2014 +0200 @@ -0,0 +1,86 @@ +/* + * Copyright (c) 2013, 2014, 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.api.code.*; +import com.oracle.graal.api.meta.*; +import com.oracle.graal.compiler.common.*; +import com.oracle.graal.graph.*; +import com.oracle.graal.nodes.*; +import com.oracle.graal.nodes.extended.*; +import com.oracle.graal.nodes.java.*; + +/** + * This is an extension of {@link MacroNode} that is a {@link StateSplit} and a + * {@link MemoryCheckpoint}. + */ +public class MacroStateSplitNode extends MacroNode implements StateSplit, MemoryCheckpoint.Single { + + @Input(InputType.State) private FrameState stateAfter; + + protected MacroStateSplitNode(Invoke invoke) { + super(invoke); + this.stateAfter = invoke.stateAfter(); + } + + @Override + public FrameState stateAfter() { + return stateAfter; + } + + public void setStateAfter(FrameState x) { + assert x == null || x.isAlive() : "frame state must be in a graph"; + updateUsages(stateAfter, x); + stateAfter = x; + } + + public boolean hasSideEffect() { + return true; + } + + public LocationIdentity getLocationIdentity() { + return LocationIdentity.ANY_LOCATION; + } + + public MemoryCheckpoint asMemoryCheckpoint() { + return this; + } + + public MemoryPhiNode asMemoryPhi() { + return null; + } + + protected void replaceSnippetInvokes(StructuredGraph snippetGraph) { + for (MethodCallTargetNode call : snippetGraph.getNodes(MethodCallTargetNode.class)) { + Invoke invoke = call.invoke(); + if (!call.targetMethod().equals(getTargetMethod())) { + throw new GraalInternalError("unexpected invoke %s in snippet", getClass().getSimpleName()); + } + assert invoke.stateAfter().bci == BytecodeFrame.AFTER_BCI; + // Here we need to fix the bci of the invoke + InvokeNode newInvoke = snippetGraph.add(new InvokeNode(invoke.callTarget(), getBci())); + newInvoke.setStateAfter(invoke.stateAfter()); + snippetGraph.replaceFixedWithFixed((InvokeNode) invoke.asNode(), newInvoke); + } + } +} diff -r 34ac3ddfd5ac -r 281c30cf1952 graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/nodes/PureFunctionMacroNode.java --- a/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/nodes/PureFunctionMacroNode.java Mon Jun 30 17:27:35 2014 +0200 +++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/nodes/PureFunctionMacroNode.java Mon Jun 30 18:17:13 2014 +0200 @@ -31,7 +31,7 @@ * This node class can be used to create {@link MacroNode}s for simple pure functions like * {@link System#identityHashCode(Object)}. */ -public abstract class PureFunctionMacroNode extends MacroNode implements Canonicalizable { +public abstract class PureFunctionMacroNode extends MacroStateSplitNode implements Canonicalizable { public PureFunctionMacroNode(Invoke invoke) { super(invoke); diff -r 34ac3ddfd5ac -r 281c30cf1952 graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/AssumptionNode.java --- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/AssumptionNode.java Mon Jun 30 17:27:35 2014 +0200 +++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/AssumptionNode.java Mon Jun 30 18:17:13 2014 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2014, 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 @@ -25,8 +25,11 @@ import com.oracle.graal.api.meta.*; import com.oracle.graal.api.replacements.*; import com.oracle.graal.api.runtime.*; +import com.oracle.graal.compiler.common.*; import com.oracle.graal.graph.spi.*; import com.oracle.graal.nodes.*; +import com.oracle.graal.nodes.spi.*; +import com.oracle.graal.nodes.util.*; import com.oracle.graal.replacements.nodes.*; import com.oracle.graal.truffle.*; @@ -50,6 +53,11 @@ } @Override + public void lower(LoweringTool tool) { + throw new GraalInternalError(GraphUtil.approxSourceException(this, new RuntimeException("assumption could not be evaluated to a constant"))); + } + + @Override public void simplify(SimplifierTool tool) { ValueNode assumption = getAssumption(); if (tool.assumptions() != null && assumption.isConstant()) { diff -r 34ac3ddfd5ac -r 281c30cf1952 graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/BailoutNode.java --- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/BailoutNode.java Mon Jun 30 17:27:35 2014 +0200 +++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/BailoutNode.java Mon Jun 30 18:17:13 2014 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2014, 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 @@ -26,6 +26,7 @@ import com.oracle.graal.graph.*; import com.oracle.graal.graph.spi.*; import com.oracle.graal.nodes.*; +import com.oracle.graal.nodes.spi.*; import com.oracle.graal.replacements.nodes.*; public class BailoutNode extends MacroNode implements Canonicalizable { @@ -35,13 +36,20 @@ assert arguments.size() == 1; } + public ValueNode getMessage() { + return arguments.get(0); + } + + @Override + public void lower(LoweringTool tool) { + throw new BailoutException("bailout (message is not compile-time constant, so no additional information is available)"); + } + @Override public Node canonical(CanonicalizerTool tool) { - ValueNode arg = arguments.get(0); - String message = ""; - if (arg.isConstant()) { - message = arg.asConstant().toValueString(); + if (getMessage().isConstant()) { + throw new BailoutException(getMessage().asConstant().toValueString()); } - throw new BailoutException(message); + return this; } } diff -r 34ac3ddfd5ac -r 281c30cf1952 graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/asserts/NeverInlineMacroNode.java --- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/asserts/NeverInlineMacroNode.java Mon Jun 30 17:27:35 2014 +0200 +++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/asserts/NeverInlineMacroNode.java Mon Jun 30 18:17:13 2014 +0200 @@ -26,7 +26,7 @@ import com.oracle.graal.nodes.spi.*; import com.oracle.graal.replacements.nodes.*; -public class NeverInlineMacroNode extends MacroNode implements com.oracle.graal.graph.IterableNodeType { +public class NeverInlineMacroNode extends MacroStateSplitNode implements com.oracle.graal.graph.IterableNodeType { public NeverInlineMacroNode(Invoke invoke) { super(invoke); diff -r 34ac3ddfd5ac -r 281c30cf1952 graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/asserts/NeverPartOfCompilationNode.java --- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/asserts/NeverPartOfCompilationNode.java Mon Jun 30 17:27:35 2014 +0200 +++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/asserts/NeverPartOfCompilationNode.java Mon Jun 30 18:17:13 2014 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,10 +22,11 @@ */ package com.oracle.graal.truffle.nodes.asserts; +import com.oracle.graal.graph.*; import com.oracle.graal.nodes.*; import com.oracle.graal.replacements.nodes.*; -public class NeverPartOfCompilationNode extends MacroNode implements com.oracle.graal.graph.IterableNodeType { +public class NeverPartOfCompilationNode extends MacroNode implements IterableNodeType { private final String message; diff -r 34ac3ddfd5ac -r 281c30cf1952 graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/typesystem/CustomizedUnsafeStoreMacroNode.java --- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/typesystem/CustomizedUnsafeStoreMacroNode.java Mon Jun 30 17:27:35 2014 +0200 +++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/typesystem/CustomizedUnsafeStoreMacroNode.java Mon Jun 30 18:17:13 2014 +0200 @@ -34,7 +34,9 @@ /** * Macro node for method {@link CompilerDirectives#unsafeCast(Object, Class, boolean)}. */ -public class CustomizedUnsafeStoreMacroNode extends NeverPartOfCompilationNode implements Canonicalizable { +public class CustomizedUnsafeStoreMacroNode extends NeverPartOfCompilationNode implements Canonicalizable, StateSplit { + + @Input(InputType.State) private FrameState stateAfter; private static final int ARGUMENT_COUNT = 4; private static final int OBJECT_ARGUMENT_INDEX = 0; @@ -45,6 +47,7 @@ public CustomizedUnsafeStoreMacroNode(Invoke invoke) { super(invoke, "The location argument could not be resolved to a constant."); assert arguments.size() == ARGUMENT_COUNT; + this.stateAfter = invoke.stateAfter(); } @Override @@ -61,8 +64,21 @@ locationIdentity = ObjectLocationIdentity.create(locationArgument.asConstant()); } - return new UnsafeStoreNode(objectArgument, offsetArgument, valueArgument, this.getTargetMethod().getSignature().getParameterKind(VALUE_ARGUMENT_INDEX), locationIdentity, stateAfter()); + return new UnsafeStoreNode(objectArgument, offsetArgument, valueArgument, this.getTargetMethod().getSignature().getParameterKind(VALUE_ARGUMENT_INDEX), locationIdentity, stateAfter); } return this; } + + @Override + public FrameState stateAfter() { + return stateAfter; + } + + public void setStateAfter(FrameState x) { + this.stateAfter = x; + } + + public boolean hasSideEffect() { + return true; + } } diff -r 34ac3ddfd5ac -r 281c30cf1952 graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/EffectsPhase.java --- a/graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/EffectsPhase.java Mon Jun 30 17:27:35 2014 +0200 +++ b/graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/EffectsPhase.java Mon Jun 30 18:17:13 2014 +0200 @@ -91,7 +91,7 @@ } // apply the effects collected during this iteration - HashSetNodeEventListener listener = new HashSetNodeEventListener.ExceptForAddedNodes(); + HashSetNodeEventListener listener = new HashSetNodeEventListener(); try (NodeEventScope nes = graph.trackNodeEvents(listener)) { closure.applyEffects(); } diff -r 34ac3ddfd5ac -r 281c30cf1952 mx/projects --- a/mx/projects Mon Jun 30 17:27:35 2014 +0200 +++ b/mx/projects Mon Jun 30 18:17:13 2014 +0200 @@ -345,6 +345,14 @@ project@com.oracle.graal.lir@javaCompliance=1.8 project@com.oracle.graal.lir@workingSets=Graal,LIR +# graal.lir.test +project@com.oracle.graal.lir.test@subDir=graal +project@com.oracle.graal.lir.test@sourceDirs=src +project@com.oracle.graal.lir.test@dependencies=JUNIT,com.oracle.graal.lir +project@com.oracle.graal.lir.test@checkstyle=com.oracle.graal.graph +project@com.oracle.graal.lir.test@javaCompliance=1.8 +project@com.oracle.graal.lir.test@workingSets=Graal,LIR + # graal.lir.amd64 project@com.oracle.graal.lir.amd64@subDir=graal project@com.oracle.graal.lir.amd64@sourceDirs=src diff -r 34ac3ddfd5ac -r 281c30cf1952 src/share/vm/graal/graalRuntime.cpp --- a/src/share/vm/graal/graalRuntime.cpp Mon Jun 30 17:27:35 2014 +0200 +++ b/src/share/vm/graal/graalRuntime.cpp Mon Jun 30 18:17:13 2014 +0200 @@ -778,7 +778,7 @@ if (!recognized) { bool throw_err = hotSpotOptionsClass.is_null(); if (!hotSpotOptionsClass.is_null()) { - set_option_helper(hotSpotOptionsClass, name, name_len, Handle(), ' ', Handle(), 0L); + set_option_helper(hotSpotOptionsClass, name, (int)name_len, Handle(), ' ', Handle(), 0L); if (!HAS_PENDING_EXCEPTION) { throw_err = true; }