changeset 17336:329eee851ee1

Merge
author Tom Rodriguez <tom.rodriguez@oracle.com>
date Fri, 03 Oct 2014 09:56:14 -0700
parents 508e88b5f1d3 (current diff) 6e590e01ecf9 (diff)
children 8043c997764d
files
diffstat 11 files changed, 359 insertions(+), 63 deletions(-) [+]
line wrap: on
line diff
--- a/graal/com.oracle.graal.compiler.common/src/com/oracle/graal/compiler/common/Fields.java	Thu Oct 02 10:59:03 2014 -0700
+++ b/graal/com.oracle.graal.compiler.common/src/com/oracle/graal/compiler/common/Fields.java	Fri Oct 03 09:56:14 2014 -0700
@@ -78,6 +78,43 @@
     }
 
     /**
+     * Copies fields from {@code from} to {@code to}. The objects must be of the exact same type.
+     *
+     * @param from the object from which the fields should be copied.
+     * @param to the object to which the fields should be copied.
+     */
+    public void copy(Object from, Object to) {
+        assert from.getClass() == to.getClass();
+        for (int index = 0; index < offsets.length; index++) {
+            long offset = offsets[index];
+            Class<?> type = types[index];
+            if (type.isPrimitive()) {
+                if (type == Integer.TYPE) {
+                    unsafe.putInt(to, offset, unsafe.getInt(from, offset));
+                } else if (type == Long.TYPE) {
+                    unsafe.putLong(to, offset, unsafe.getLong(from, offset));
+                } else if (type == Boolean.TYPE) {
+                    unsafe.putBoolean(to, offset, unsafe.getBoolean(from, offset));
+                } else if (type == Float.TYPE) {
+                    unsafe.putFloat(to, offset, unsafe.getFloat(from, offset));
+                } else if (type == Double.TYPE) {
+                    unsafe.putDouble(to, offset, unsafe.getDouble(from, offset));
+                } else if (type == Short.TYPE) {
+                    unsafe.putShort(to, offset, unsafe.getShort(from, offset));
+                } else if (type == Character.TYPE) {
+                    unsafe.putChar(to, offset, unsafe.getChar(from, offset));
+                } else if (type == Byte.TYPE) {
+                    unsafe.putByte(to, offset, unsafe.getByte(from, offset));
+                } else {
+                    assert false : "unhandled property type: " + type;
+                }
+            } else {
+                unsafe.putObject(to, offset, unsafe.getObject(from, offset));
+            }
+        }
+    }
+
+    /**
      * Gets the value of a field for a given object.
      *
      * @param object the object whose field is to be read
--- a/graal/com.oracle.graal.graph/src/com/oracle/graal/graph/Edges.java	Thu Oct 02 10:59:03 2014 -0700
+++ b/graal/com.oracle.graal.graph/src/com/oracle/graal/graph/Edges.java	Fri Oct 03 09:56:14 2014 -0700
@@ -135,6 +135,24 @@
     }
 
     /**
+     * Initializes the list edges in a given node based on the size of the list edges in a prototype
+     * node.
+     *
+     * @param node the node whose list edges are to be initialized
+     * @param prototype the node whose list edge sizes are used when creating new edge lists
+     */
+    public void initializeLists(Node node, Node prototype) {
+        int index = getDirectCount();
+        while (index < getCount()) {
+            NodeList<Node> list = getNodeList(prototype, index);
+            int size = list.initialSize;
+            NodeList<Node> newList = type == Edges.Type.Inputs ? new NodeInputList<>(node, size) : new NodeSuccessorList<>(node, size);
+            initializeList(node, index, newList);
+            index++;
+        }
+    }
+
+    /**
      * Copies edges from {@code fromNode} to {@code toNode}. The nodes are expected to be of the
      * exact same type.
      *
@@ -150,7 +168,13 @@
         }
         while (index < getCount()) {
             NodeList<Node> list = getNodeList(toNode, index);
-            list.copy(getNodeList(fromNode, index));
+            if (list == null) {
+                NodeList<Node> fromList = getNodeList(fromNode, index);
+                list = type == Edges.Type.Inputs ? new NodeInputList<>(toNode, fromList) : new NodeSuccessorList<>(toNode, fromList);
+                initializeList(toNode, index, list);
+            } else {
+                list.copy(getNodeList(fromNode, index));
+            }
             index++;
         }
     }
--- a/graal/com.oracle.graal.graph/src/com/oracle/graal/graph/Node.java	Thu Oct 02 10:59:03 2014 -0700
+++ b/graal/com.oracle.graal.graph/src/com/oracle/graal/graph/Node.java	Fri Oct 03 09:56:14 2014 -0700
@@ -58,6 +58,7 @@
 public abstract class Node implements Cloneable, Formattable {
 
     public final static boolean USE_GENERATED_NODES = Boolean.parseBoolean(System.getProperty("graal.useGeneratedNodes", "true"));
+    public final static boolean USE_UNSAFE_CLONE = Boolean.parseBoolean(System.getProperty("graal.useUnsafeClone", "true"));
 
     static final int DELETED_ID_START = -1000000000;
     static final int INITIAL_ID = -1;
@@ -756,24 +757,36 @@
 
         Node newNode = null;
         try {
-            newNode = (Node) this.clone();
-        } catch (CloneNotSupportedException e) {
+            if (USE_UNSAFE_CLONE) {
+                newNode = (Node) UnsafeAccess.unsafe.allocateInstance(getClass());
+                nodeClass.getData().copy(this, newNode);
+                if (clearInputsAndSuccessors) {
+                    nodeClass.getEdges(Inputs).initializeLists(newNode, this);
+                    nodeClass.getEdges(Successors).initializeLists(newNode, this);
+                } else {
+                    nodeClass.getEdges(Inputs).copy(this, newNode);
+                    nodeClass.getEdges(Successors).copy(this, newNode);
+                }
+            } else {
+                newNode = (Node) this.clone();
+                if (clearInputsAndSuccessors) {
+                    nodeClass.getEdges(Inputs).clear(newNode);
+                    nodeClass.getEdges(Successors).clear(newNode);
+                }
+                newNode.typeCacheNext = null;
+                newNode.usage0 = null;
+                newNode.usage1 = null;
+                newNode.predecessor = null;
+            }
+        } catch (Exception e) {
             throw new GraalGraphInternalError(e).addContext(this);
         }
-        if (clearInputsAndSuccessors) {
-            nodeClass.getEdges(Inputs).clear(newNode);
-            nodeClass.getEdges(Successors).clear(newNode);
-        }
         newNode.graph = into;
-        newNode.typeCacheNext = null;
         newNode.id = INITIAL_ID;
         if (into != null) {
             into.register(newNode);
         }
-        newNode.usage0 = null;
-        newNode.usage1 = null;
         newNode.extraUsages = NO_NODES;
-        newNode.predecessor = null;
 
         if (into != null && nodeClass.valueNumberable() && nodeClass.isLeafNode()) {
             into.putNodeIntoCache(newNode);
--- a/graal/com.oracle.graal.graph/src/com/oracle/graal/graph/NodeSuccessorList.java	Thu Oct 02 10:59:03 2014 -0700
+++ b/graal/com.oracle.graal.graph/src/com/oracle/graal/graph/NodeSuccessorList.java	Fri Oct 03 09:56:14 2014 -0700
@@ -24,6 +24,8 @@
 
 import static com.oracle.graal.graph.Edges.Type.*;
 
+import java.util.*;
+
 import com.oracle.graal.graph.Edges.*;
 
 public final class NodeSuccessorList<T extends Node> extends NodeList<T> {
@@ -41,6 +43,11 @@
         assert self.usages().isEmpty();
     }
 
+    public NodeSuccessorList(Node self, List<? extends T> elements) {
+        super(self, elements);
+        assert self.usages().isEmpty();
+    }
+
     @Override
     protected void update(T oldNode, T newNode) {
         self.updatePredecessor(oldNode, newNode);
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.lir.test/src/com/oracle/graal/lir/test/ValuePositionTest3.java	Fri Oct 03 09:56:14 2014 -0700
@@ -0,0 +1,158 @@
+/*
+ * 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.OperandMode;
+import com.oracle.graal.lir.asm.*;
+
+public class ValuePositionTest3 {
+
+    public static final class TestAddressValue extends CompositeValue {
+
+        private static final long serialVersionUID = -2679790860680123026L;
+
+        @Component({REG, OperandFlag.ILLEGAL}) protected AllocatableValue base;
+        @Component({REG, OperandFlag.ILLEGAL}) protected AllocatableValue index;
+
+        public TestAddressValue(LIRKind kind, AllocatableValue base) {
+            this(kind, base, Value.ILLEGAL);
+        }
+
+        public TestAddressValue(LIRKind kind, AllocatableValue base, AllocatableValue index) {
+            super(kind);
+            this.base = base;
+            this.index = index;
+        }
+    }
+
+    private static class DummyValue extends AllocatableValue {
+
+        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;
+        }
+
+        @Override
+        public String toString() {
+            return "DummyValue" + id;
+        }
+
+    }
+
+    private static class TestOp extends LIRInstruction {
+
+        @Use({COMPOSITE}) protected Value value;
+
+        public TestOp(Value value) {
+            this.value = value;
+        }
+
+        @Override
+        public void emitCode(CompilationResultBuilder crb) {
+            fail("should not reach!");
+        }
+
+        @Override
+        public String toString() {
+            return "TestOp [" + value + "]";
+        }
+
+    }
+
+    @Test
+    public void test0() {
+        DummyValue dummyValue0 = new DummyValue();
+        DummyValue dummyValue1 = new DummyValue();
+
+        TestAddressValue compValue0 = new TestAddressValue(LIRKind.Illegal, dummyValue0, dummyValue1);
+
+        LIRInstruction op = new TestOp(compValue0);
+
+        HashMap<Value, EnumSet<OperandFlag>> positionMap = new HashMap<>();
+        HashMap<Value, EnumSet<OperandFlag>> normalMap = new HashMap<>();
+
+        op.forEachInputPos(new ValuePositionProcedure() {
+
+            @Override
+            public void doValue(LIRInstruction instruction, ValuePosition position) {
+                positionMap.put(position.get(instruction), position.getFlags());
+            }
+        });
+        op.visitEachInput(new InstructionValueConsumer() {
+
+            @Override
+            public void visitValue(LIRInstruction instruction, Value value, OperandMode mode, EnumSet<OperandFlag> flags) {
+                normalMap.put(value, flags);
+            }
+        });
+
+        assertEquals(normalMap.size(), positionMap.size());
+        assertTrue(normalMap.keySet().containsAll(positionMap.keySet()));
+        normalMap.keySet().forEach(key -> {
+            EnumSet<OperandFlag> normal = normalMap.get(key);
+            EnumSet<OperandFlag> position = positionMap.get(key);
+            assertTrue(normal.containsAll(position));
+            assertTrue(position.containsAll(normal));
+        });
+    }
+}
--- a/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/LIRIntrospection.java	Thu Oct 02 10:59:03 2014 -0700
+++ b/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/LIRIntrospection.java	Fri Oct 03 09:56:14 2014 -0700
@@ -304,19 +304,18 @@
 
             if (i < values.getDirectCount()) {
                 Value value = values.getValue(obj, i);
-                doForValue(inst, mode, proc, outerPosition, i, ValuePosition.NO_SUBINDEX, value);
+                doForValue(inst, values, mode, proc, outerPosition, i, ValuePosition.NO_SUBINDEX, value);
             } else {
                 Value[] valueArray = values.getValueArray(obj, i);
                 for (int j = 0; j < valueArray.length; j++) {
                     Value value = valueArray[j];
-                    doForValue(inst, mode, proc, outerPosition, i, j, value);
+                    doForValue(inst, values, mode, proc, outerPosition, i, j, value);
                 }
             }
         }
     }
 
-    private static void doForValue(LIRInstruction inst, OperandMode mode, ValuePositionProcedure proc, ValuePosition outerPosition, int index, int subIndex, Value value) {
-        Values values = inst.getLIRInstructionClass().getValues(mode);
+    private static void doForValue(LIRInstruction inst, Values values, OperandMode mode, ValuePositionProcedure proc, ValuePosition outerPosition, int index, int subIndex, Value value) {
         ValuePosition position = new ValuePosition(values, index, subIndex, outerPosition);
         if (value instanceof CompositeValue) {
             CompositeValue composite = (CompositeValue) value;
--- a/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/ValuePosition.java	Thu Oct 02 10:59:03 2014 -0700
+++ b/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/ValuePosition.java	Fri Oct 03 09:56:14 2014 -0700
@@ -29,75 +29,108 @@
 import com.oracle.graal.lir.LIRIntrospection.Values;
 
 /**
- * Describes an operand slot for a {@link LIRInstructionClass}.
+ * Describes an operand slot for a {@link LIRInstruction}.
  */
 public final class ValuePosition {
 
+    /**
+     * The {@linkplain Values offsets} to the fields of the containing element (either
+     * {@link LIRInstruction} or {@link CompositeValue}).
+     */
     private final Values values;
+    /**
+     * The index into {@link #values}.
+     *
+     * @see Values#getValue(Object, int)
+     */
     private final int index;
+    /**
+     * The sub-index if {@link #index} points to a value array, otherwise {@link #NO_SUBINDEX}.
+     *
+     * @see Values#getDirectCount()
+     * @see Values#getValueArray(Object, int)
+     */
     private final int subIndex;
+    /**
+     * @see #getOuterPosition()
+     */
     private final ValuePosition outerPosition;
 
     public static final int NO_SUBINDEX = -1;
     public static final ValuePosition ROOT_VALUE_POSITION = null;
 
-    public ValuePosition(Values values, int index, int subIndex, ValuePosition outerPosition) {
+    ValuePosition(Values values, int index, int subIndex, ValuePosition outerPosition) {
         this.values = values;
         this.index = index;
         this.subIndex = subIndex;
         this.outerPosition = outerPosition;
     }
 
+    /**
+     * @return True if the value denoted by this {@linkplain ValuePosition position} is part of a
+     *         {@link CompositeValue}.
+     */
     public boolean isCompositePosition() {
         return outerPosition != ROOT_VALUE_POSITION;
     }
 
-    public Value get(Object inst) {
+    /**
+     * @param inst The instruction this {@linkplain ValuePosition position} belongs to.
+     * @return The value denoted by this {@linkplain ValuePosition position}.
+     */
+    public Value get(LIRInstruction inst) {
         if (isCompositePosition()) {
             CompositeValue compValue = (CompositeValue) outerPosition.get(inst);
             return compValue.getValueClass().getValue(compValue, this);
         }
-        return getValue(inst);
+        if (index < values.getDirectCount()) {
+            return values.getValue(inst, index);
+        }
+        return values.getValueArray(inst, index)[subIndex];
     }
 
+    /**
+     * Sets the value denoted by this {@linkplain ValuePosition position}.
+     *
+     * @param inst The instruction this {@linkplain ValuePosition position} belongs to.
+     */
     public void set(LIRInstruction inst, Value value) {
         if (isCompositePosition()) {
             CompositeValue compValue = (CompositeValue) outerPosition.get(inst);
             CompositeValue newCompValue = compValue.getValueClass().createUpdatedValue(compValue, this, value);
             outerPosition.set(inst, newCompValue);
         } else {
-            setValue(inst, value);
+            if (index < values.getDirectCount()) {
+                values.setValue(inst, index, value);
+            } else {
+                values.getValueArray(inst, index)[subIndex] = value;
+            }
         }
     }
 
-    public int getSubIndex() {
+    int getSubIndex() {
         return subIndex;
     }
 
-    public int getIndex() {
+    int getIndex() {
         return index;
     }
 
+    /**
+     * @return The flags associated with the value denoted by this {@linkplain ValuePosition
+     *         position}.
+     */
     public EnumSet<OperandFlag> getFlags() {
         return values.getFlags(index);
     }
 
-    public Value getValue(Object obj) {
-        if (index < values.getDirectCount()) {
-            return values.getValue(obj, index);
-        }
-        return values.getValueArray(obj, index)[subIndex];
-    }
-
-    public void setValue(Object obj, Value value) {
-        if (index < values.getDirectCount()) {
-            values.setValue(obj, index, value);
-        } else {
-            values.getValueArray(obj, index)[subIndex] = value;
-        }
-    }
-
-    public ValuePosition getSuperPosition() {
+    /**
+     * @return The {@link ValuePosition} of the containing {@link CompositeValue} if this value is
+     *         part of a {@link CompositeValue}, otherwise {@link #ROOT_VALUE_POSITION}.
+     *
+     * @see #isCompositePosition()
+     */
+    public ValuePosition getOuterPosition() {
         return outerPosition;
     }
 
--- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/ContextSensitiveInlining.java	Thu Oct 02 10:59:03 2014 -0700
+++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/ContextSensitiveInlining.java	Fri Oct 03 09:56:14 2014 -0700
@@ -36,41 +36,54 @@
     }
 
     public ContextSensitiveInlining(OptimizedCallTarget sourceTarget, TruffleInliningPolicy policy) {
-        this(decideInlining(OptimizedCallUtils.countNonTrivialNodes(sourceTarget, false), exploreCallSites(new ArrayList<>(Arrays.asList(sourceTarget)), policy), policy));
+        this(createDecisions(sourceTarget, policy));
     }
 
-    private static List<InliningDecision> exploreCallSites(List<OptimizedCallTarget> stack, TruffleInliningPolicy policy) {
+    private static List<InliningDecision> createDecisions(OptimizedCallTarget sourceTarget, TruffleInliningPolicy policy) {
+        int nodeCount = OptimizedCallUtils.countNonTrivialNodes(sourceTarget, false);
+        List<InliningDecision> exploredCallSites = exploreCallSites(new ArrayList<>(Arrays.asList(sourceTarget)), nodeCount, policy);
+        return decideInlining(exploredCallSites, policy, nodeCount);
+    }
+
+    private static List<InliningDecision> exploreCallSites(List<OptimizedCallTarget> stack, int callStackNodeCount, TruffleInliningPolicy policy) {
         List<InliningDecision> exploredCallSites = new ArrayList<>();
         OptimizedCallTarget parentTarget = stack.get(stack.size() - 1);
         for (OptimizedDirectCallNode callNode : parentTarget.getCallNodes()) {
             OptimizedCallTarget currentTarget = callNode.getCurrentCallTarget();
             stack.add(currentTarget); // push
-            exploredCallSites.add(exploreCallSite(stack, policy, callNode));
+            exploredCallSites.add(exploreCallSite(stack, callStackNodeCount, policy, callNode));
             stack.remove(stack.size() - 1); // pop
         }
         return exploredCallSites;
     }
 
-    private static InliningDecision exploreCallSite(List<OptimizedCallTarget> callStack, TruffleInliningPolicy policy, OptimizedDirectCallNode callNode) {
+    private static InliningDecision exploreCallSite(List<OptimizedCallTarget> callStack, int callStackNodeCount, TruffleInliningPolicy policy, OptimizedDirectCallNode callNode) {
         OptimizedCallTarget parentTarget = callStack.get(callStack.size() - 2);
         OptimizedCallTarget currentTarget = callStack.get(callStack.size() - 1);
 
         boolean recursive = isRecursiveStack(callStack);
         boolean maxDepth = callStack.size() >= 15;
 
-        List<InliningDecision> childCallSites;
+        List<InliningDecision> childCallSites = Collections.emptyList();
         double frequency = TruffleInliningHandler.calculateFrequency(parentTarget, callNode);
         int nodeCount = OptimizedCallUtils.countNonTrivialNodes(callNode.getCurrentCallTarget(), false);
-        int deepNodeCount;
-        if (recursive || maxDepth) {
-            deepNodeCount = nodeCount;
-            childCallSites = Collections.emptyList();
-        } else {
-            childCallSites = decideInlining(nodeCount, exploreCallSites(callStack, policy), policy);
-            deepNodeCount = nodeCount;
-            for (InliningDecision childCallSite : childCallSites) {
-                if (childCallSite.isInline()) {
-                    deepNodeCount += childCallSite.getProfile().getDeepNodeCount();
+
+        int deepNodeCount = nodeCount;
+        if (!recursive && !maxDepth) {
+            /*
+             * We make a preliminary optimistic inlining decision with best possible characteristics
+             * to avoid the exploration of unnecessary pathes in the inlining tree.
+             */
+            if (policy.isAllowed(new TruffleInliningProfile(callNode, nodeCount, nodeCount, frequency, recursive, null), callStackNodeCount)) {
+                List<InliningDecision> exploredCallSites = exploreCallSites(callStack, callStackNodeCount + nodeCount, policy);
+                childCallSites = decideInlining(exploredCallSites, policy, nodeCount);
+                for (InliningDecision childCallSite : childCallSites) {
+                    if (childCallSite.isInline()) {
+                        deepNodeCount += childCallSite.getProfile().getDeepNodeCount();
+                    } else {
+                        /* we don't need those anymore. */
+                        childCallSite.getCallSites().clear();
+                    }
                 }
             }
         }
@@ -90,7 +103,7 @@
         return false;
     }
 
-    private static List<InliningDecision> decideInlining(int nodeCount, List<InliningDecision> callSites, TruffleInliningPolicy policy) {
+    private static List<InliningDecision> decideInlining(List<InliningDecision> callSites, TruffleInliningPolicy policy, int nodeCount) {
         int deepNodeCount = nodeCount;
         int index = 0;
         for (InliningDecision callSite : callSites.stream().sorted().collect(Collectors.toList())) {
@@ -195,6 +208,11 @@
             }
         }
 
+        @Override
+        public String toString() {
+            return String.format("InliningDecision(callNode=%s, inline=%b)", profile.getCallNode(), inline);
+        }
+
     }
 
 }
--- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/OptimizedDirectCallNode.java	Thu Oct 02 10:59:03 2014 -0700
+++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/OptimizedDirectCallNode.java	Fri Oct 03 09:56:14 2014 -0700
@@ -206,4 +206,9 @@
         splittingStrategy.forceSplitting();
         return true;
     }
+
+    @Override
+    public String toString() {
+        return String.format("OptimizedDirectCallNode(target=%s, parent=%s)", getCurrentCallTarget().toString(), getParent());
+    }
 }
--- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/PartialEvaluator.java	Thu Oct 02 10:59:03 2014 -0700
+++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/PartialEvaluator.java	Fri Oct 03 09:56:14 2014 -0700
@@ -23,6 +23,7 @@
 package com.oracle.graal.truffle;
 
 import static com.oracle.graal.compiler.common.GraalOptions.*;
+import static com.oracle.graal.truffle.OptimizedCallTargetLog.*;
 import static com.oracle.graal.truffle.TruffleCompilerOptions.*;
 
 import java.util.*;
@@ -59,9 +60,6 @@
 import com.oracle.graal.virtual.phases.ea.*;
 import com.oracle.truffle.api.*;
 import com.oracle.truffle.api.nodes.*;
-import com.oracle.truffle.api.nodes.Node.Child;
-import com.oracle.truffle.api.nodes.Node.Children;
-import static com.oracle.graal.truffle.OptimizedCallTargetLog.*;
 
 /**
  * Class performing the partial evaluation starting from the root node of an AST.
@@ -296,8 +294,9 @@
         InliningDecision decision = inlining.findByCall(callNode);
         if (decision == null) {
             if (TruffleCompilerOptions.PrintTrufflePerformanceWarnings.getValue()) {
-                logPerformanceWarning(String.format("%s '%s' is reached using partial evaluation but it is not reachable in the Truffle AST.  Did you miss @%s or @%s annotation on a node field?. ",
-                                DirectCallNode.class.getSimpleName(), callNode, Child.class.getSimpleName(), Children.class.getSimpleName()), callNode.getRootNode().getDebugProperties());
+                Map<String, Object> properties = new LinkedHashMap<>();
+                properties.put("callNode", callNode);
+                logPerformanceWarning("A direct call within the Truffle AST is not reachable anymore. Call node was not inlined.", properties);
             }
             return null;
         }
@@ -307,9 +306,10 @@
         OptimizedCallTarget currentTarget = decision.getProfile().getCallNode().getCurrentCallTarget();
         if (decision.getTarget() != currentTarget) {
             if (TruffleCompilerOptions.PrintTrufflePerformanceWarnings.getValue()) {
-                logPerformanceWarning(
-                                String.format("CallTarget '%s' changed to '%s' during compilation for call node '%s'. Call node was not inlined.", decision.getTarget(), currentTarget, callNode), null);
-
+                Map<String, Object> properties = new LinkedHashMap<>();
+                properties.put("originalTarget", decision.getTarget());
+                properties.put("callNode", callNode);
+                logPerformanceWarning(String.format("CallTarget changed during compilation. Call node was not inlined."), properties);
             }
             return null;
         }
--- a/mx/mx_graal.py	Thu Oct 02 10:59:03 2014 -0700
+++ b/mx/mx_graal.py	Fri Oct 03 09:56:14 2014 -0700
@@ -1857,7 +1857,7 @@
                 buildOutput.append(x)
         env = os.environ.copy()
         env['JAVA_HOME'] = _jdk(vmToCheck='server')
-        env['MAVEN_OPTS'] = '-server'
+        env['MAVEN_OPTS'] = '-server -XX:-UseGraalClassLoader'
         mx.log("Building benchmarks...")
         cmd = ['mvn']
         if args.settings:
@@ -1883,6 +1883,8 @@
         mx.abort(1)
 
     vmArgs, benchmarksAndJsons = _extract_VM_args(args)
+    if '-XX:-UseGraalClassLoader' not in vmArgs:
+        vmArgs = ['-XX:-UseGraalClassLoader'] + vmArgs
 
     benchmarks = [b for b in benchmarksAndJsons if not b.startswith('{')]
     jmhArgJsons = [b for b in benchmarksAndJsons if b.startswith('{')]