changeset 13209:b96cc3b87e87

Merge
author Andreas Woess <andreas.woess@jku.at>
date Mon, 02 Dec 2013 13:46:05 +0100
parents bef512e42262 (diff) 66d793d06465 (current diff)
children 862a5d60a58a d862cb983214 78c808233ff1
files graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/PartialEvaluator.java
diffstat 6 files changed, 225 insertions(+), 11 deletions(-) [+]
line wrap: on
line diff
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/phases/WriteBarrierAdditionPhase.java	Sat Nov 30 18:41:35 2013 +0100
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/phases/WriteBarrierAdditionPhase.java	Mon Dec 02 13:46:05 2013 +0100
@@ -98,7 +98,9 @@
             }
         } else if (barrierType == BarrierType.IMPRECISE) {
             if (useG1GC()) {
-                addG1PreWriteBarrier(node, node.object(), null, node.location(), true, node.getNullCheck(), graph);
+                if (!node.isInitialization()) {
+                    addG1PreWriteBarrier(node, node.object(), null, node.location(), true, node.getNullCheck(), graph);
+                }
                 addG1PostWriteBarrier(node, node.object(), node.value(), node.location(), false, graph);
             } else {
                 addSerialPostWriteBarrier(node, node.object(), node.value(), node.location(), false, graph);
--- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/FrameWithoutBoxing.java	Sat Nov 30 18:41:35 2013 +0100
+++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/FrameWithoutBoxing.java	Mon Dec 02 13:46:05 2013 +0100
@@ -239,7 +239,9 @@
         int slotIndex = slot.getIndex();
         if (slotIndex >= getTags().length) {
             CompilerDirectives.transferToInterpreter();
-            resize();
+            if (!resize()) {
+                throw new IllegalArgumentException(String.format("The frame slot '%s' is not known by the frame descriptor.", slot));
+            }
         }
         getTags()[slotIndex] = (byte) accessKind.ordinal();
     }
@@ -248,7 +250,9 @@
         int slotIndex = slot.getIndex();
         if (slotIndex >= getTags().length) {
             CompilerDirectives.transferToInterpreter();
-            resize();
+            if (!resize()) {
+                throw new IllegalArgumentException(String.format("The frame slot '%s' is not known by the frame descriptor.", slot));
+            }
         }
         byte tag = this.getTags()[slotIndex];
         if (tag != accessKind.ordinal()) {
@@ -289,7 +293,7 @@
         }
     }
 
-    private void resize() {
+    private boolean resize() {
         int oldSize = tags.length;
         int newSize = descriptor.getSize();
         if (newSize > oldSize) {
@@ -297,7 +301,9 @@
             Arrays.fill(locals, oldSize, newSize, descriptor.getTypeConversion().getDefaultValue());
             primitiveLocals = Arrays.copyOf(primitiveLocals, newSize);
             tags = Arrays.copyOf(tags, newSize);
+            return true;
         }
+        return false;
     }
 
     private byte getTag(FrameSlot slot) {
--- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/PartialEvaluator.java	Sat Nov 30 18:41:35 2013 +0100
+++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/PartialEvaluator.java	Mon Dec 02 13:46:05 2013 +0100
@@ -80,7 +80,6 @@
         this.skippedExceptionTypes = TruffleCompilerImpl.getSkippedExceptionTypes(providers.getMetaAccess());
         this.cache = runtime.getGraphCache();
         this.truffleCache = truffleCache;
-
         try {
             executeHelperMethod = providers.getMetaAccess().lookupJavaMethod(OptimizedCallTarget.class.getDeclaredMethod("executeHelper", PackedFrame.class, Arguments.class));
         } catch (NoSuchMethodException ex) {
@@ -180,6 +179,10 @@
 
     private void expandTree(StructuredGraph graph, Assumptions assumptions) {
         PhaseContext phaseContext = new PhaseContext(providers, assumptions);
+        TruffleExpansionLogger expansionLogger = null;
+        if (TraceTruffleExpansion.getValue()) {
+            expansionLogger = new TruffleExpansionLogger(graph);
+        }
         boolean changed;
         do {
             changed = false;
@@ -210,7 +213,13 @@
                     if (inlineGraph != null) {
                         int nodeCountBefore = graph.getNodeCount();
                         Mark mark = graph.getMark();
-                        InliningUtil.inline(methodCallTargetNode.invoke(), inlineGraph, false);
+                        if (TraceTruffleExpansion.getValue()) {
+                            expansionLogger.preExpand(methodCallTargetNode, inlineGraph);
+                        }
+                        Map<Node, Node> inlined = InliningUtil.inline(methodCallTargetNode.invoke(), inlineGraph, false);
+                        if (TraceTruffleExpansion.getValue()) {
+                            expansionLogger.postExpand(inlined);
+                        }
                         if (Debug.isDumpEnabled()) {
                             int nodeCountAfter = graph.getNodeCount();
                             Debug.dump(graph, "After inlining %s %+d (%d)", methodCallTargetNode.targetMethod().toString(), nodeCountAfter - nodeCountBefore, nodeCountAfter);
@@ -229,6 +238,10 @@
                 }
             }
         } while (changed);
+
+        if (TraceTruffleExpansion.getValue()) {
+            expansionLogger.print();
+        }
     }
 
     private StructuredGraph parseGraph(final ResolvedJavaMethod targetMethod, final NodeInputList<ValueNode> arguments, final Assumptions assumptions, final PhaseContext phaseContext) {
--- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/TruffleCompilerOptions.java	Sat Nov 30 18:41:35 2013 +0100
+++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/TruffleCompilerOptions.java	Mon Dec 02 13:46:05 2013 +0100
@@ -82,6 +82,10 @@
     @Option(help = "")
     public static final OptionValue<Boolean> TraceTruffleCompilationDetails = new OptionValue<>(false);
     @Option(help = "")
+    public static final OptionValue<Boolean> TraceTruffleExpansion = new OptionValue<>(false);
+    @Option(help = "")
+    public static final OptionValue<Boolean> TraceTruffleExpansionSource = new OptionValue<>(false);
+    @Option(help = "")
     public static final OptionValue<Boolean> TraceTruffleCacheDetails = new OptionValue<>(false);
     @Option(help = "")
     public static final OptionValue<Boolean> TraceTruffleCompilationExceptions = new OptionValue<>(true);
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/TruffleExpansionLogger.java	Mon Dec 02 13:46:05 2013 +0100
@@ -0,0 +1,179 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.graal.truffle;
+
+import java.io.*;
+import java.lang.reflect.*;
+import java.util.*;
+import java.util.Map.Entry;
+
+import com.oracle.graal.api.meta.*;
+import com.oracle.graal.graph.*;
+import com.oracle.graal.nodes.*;
+import com.oracle.graal.nodes.java.*;
+
+public class TruffleExpansionLogger {
+
+    private final ExpansionTree root;
+    private final Map<MethodCallTargetNode, ExpansionTree> callToParentTree = new HashMap<>();
+
+    public TruffleExpansionLogger(StructuredGraph graph) {
+        root = new ExpansionTree(null, null, graph.method(), -1);
+        registerParentInCalls(root, graph);
+    }
+
+    public void preExpand(MethodCallTargetNode callTarget, StructuredGraph inliningGraph) {
+        ResolvedJavaMethod sourceMethod = callTarget.invoke().getState().method();
+
+        int sourceMethodBci = callTarget.invoke().bci();
+        ResolvedJavaMethod targetMethod = callTarget.targetMethod();
+        Object targetReceiver = null;
+        if (!Modifier.isStatic(sourceMethod.getModifiers())) {
+            targetReceiver = callTarget.arguments().first().asConstant().asObject();
+        }
+
+        ExpansionTree parent = callToParentTree.get(callTarget);
+        assert parent != null;
+        callToParentTree.remove(callTarget);
+        ExpansionTree tree = new ExpansionTree(parent, targetReceiver, targetMethod, sourceMethodBci);
+        registerParentInCalls(tree, inliningGraph);
+    }
+
+    @SuppressWarnings("unchecked")
+    public void postExpand(Map<Node, Node> states) {
+        Iterable<Entry<Node, Node>> entries;
+        if (states instanceof NodeMap) {
+            entries = ((NodeMap<Node>) states).entries();
+        } else {
+            entries = states.entrySet();
+        }
+
+        for (Entry<Node, Node> entry : entries) {
+            Node key = entry.getKey();
+            Node value = entry.getValue();
+
+            if (value instanceof MethodCallTargetNode && callToParentTree.containsKey(key)) {
+                callToParentTree.put((MethodCallTargetNode) value, callToParentTree.get(key));
+                callToParentTree.remove(key);
+            }
+        }
+    }
+
+    private void registerParentInCalls(ExpansionTree parentTree, StructuredGraph graph) {
+        for (MethodCallTargetNode target : graph.getNodes(MethodCallTargetNode.class)) {
+            callToParentTree.put(target, parentTree);
+        }
+    }
+
+    public void print() {
+        root.print(System.out);
+    }
+
+    private static final class ExpansionTree implements Comparable<ExpansionTree> {
+
+        private final ExpansionTree parent;
+        private final Object targetReceiver;
+        private final ResolvedJavaMethod targetMethod;
+        private final int parentBci;
+        private final List<ExpansionTree> children = new ArrayList<>();
+
+        public ExpansionTree(ExpansionTree parent, Object receiver, ResolvedJavaMethod targetMethod, int parentBci) {
+            this.parent = parent;
+            this.targetReceiver = receiver;
+            this.targetMethod = targetMethod;
+            this.parentBci = parentBci;
+            if (parent != null) {
+                parent.children.add(this);
+            }
+        }
+
+        public int compareTo(ExpansionTree o) {
+            if (parent == o.parent) {
+                return parentBci - o.parentBci;
+            }
+            return 0;
+        }
+
+        public void print(PrintStream p) {
+            print(p, "");
+        }
+
+        private void print(PrintStream p, String indent) {
+            StackTraceElement targetElement = targetMethod.asStackTraceElement(0);
+            StackTraceElement sourceElement = null;
+
+            ExpansionTree currentParent = this.parent;
+            if (currentParent != null) {
+                sourceElement = currentParent.targetMethod.asStackTraceElement(parentBci);
+            }
+
+            String className = targetElement.getClassName();
+            int lastIndex = className.lastIndexOf('.');
+            if (lastIndex != -1) {
+                className = className.substring(lastIndex + 1, className.length());
+            }
+
+            lastIndex = className.lastIndexOf('$');
+            if (lastIndex != -1) {
+                className = className.substring(lastIndex + 1, className.length());
+            }
+
+            String constantType = "";
+            if (targetReceiver != null) {
+                if (!targetReceiver.getClass().getSimpleName().equals(className)) {
+                    constantType = "<" + targetReceiver.getClass().getSimpleName() + ">";
+                }
+            }
+
+            String sourceSource = "";
+            String targetSource = "";
+            if (TruffleCompilerOptions.TraceTruffleExpansionSource.getValue()) {
+                sourceSource = formatSource(sourceElement);
+                targetSource = formatSource(targetElement);
+            }
+            p.printf("%s%s %s%s.%s%s%n", indent, sourceSource, className, constantType, targetMethod.getName(), targetSource);
+
+            Collections.sort(children);
+
+            for (ExpansionTree child : children) {
+                child.print(p, indent + "  ");
+            }
+        }
+
+        private static String formatSource(StackTraceElement e) {
+            if (e == null) {
+                return "";
+            }
+            if (e.getFileName() != null) {
+                if (e.getLineNumber() >= 0) {
+                    return String.format("(%s:%d)", e.getFileName(), e.getLineNumber());
+                } else {
+                    return String.format("(%s)", e.getFileName(), e.getLineNumber());
+                }
+            } else {
+                return String.format("(Unknown Source)", e.getFileName(), e.getLineNumber());
+            }
+        }
+    }
+
+}
--- a/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/impl/DefaultVirtualFrame.java	Sat Nov 30 18:41:35 2013 +0100
+++ b/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/impl/DefaultVirtualFrame.java	Mon Dec 02 13:46:05 2013 +0100
@@ -160,7 +160,9 @@
     public Object getValue(FrameSlot slot) {
         int slotIndex = slot.getIndex();
         if (slotIndex >= tags.length) {
-            resize();
+            if (!resize()) {
+                throw new IllegalArgumentException(String.format("The frame slot '%s' is not known by the frame descriptor.", slot));
+            }
         }
         return locals[slotIndex];
     }
@@ -168,7 +170,9 @@
     private void verifySet(FrameSlot slot, FrameSlotKind accessKind) {
         int slotIndex = slot.getIndex();
         if (slotIndex >= tags.length) {
-            resize();
+            if (!resize()) {
+                throw new IllegalArgumentException(String.format("The frame slot '%s' is not known by the frame descriptor.", slot));
+            }
         }
         tags[slotIndex] = (byte) accessKind.ordinal();
     }
@@ -176,7 +180,9 @@
     private void verifyGet(FrameSlot slot, FrameSlotKind accessKind) throws FrameSlotTypeException {
         int slotIndex = slot.getIndex();
         if (slotIndex >= tags.length) {
-            resize();
+            if (!resize()) {
+                throw new IllegalArgumentException(String.format("The frame slot '%s' is not known by the frame descriptor.", slot));
+            }
         }
         byte tag = tags[slotIndex];
         if (accessKind == FrameSlotKind.Object ? tag != 0 : tag != accessKind.ordinal()) {
@@ -190,20 +196,24 @@
         }
     }
 
-    private void resize() {
+    private boolean resize() {
         int oldSize = tags.length;
         int newSize = descriptor.getSize();
         if (newSize > oldSize) {
             locals = Arrays.copyOf(locals, newSize);
             Arrays.fill(locals, oldSize, newSize, descriptor.getTypeConversion().getDefaultValue());
             tags = Arrays.copyOf(tags, newSize);
+            return true;
         }
+        return false;
     }
 
     private byte getTag(FrameSlot slot) {
         int slotIndex = slot.getIndex();
         if (slotIndex >= tags.length) {
-            resize();
+            if (!resize()) {
+                throw new IllegalArgumentException(String.format("The frame slot '%s' is not known by the frame descriptor.", slot));
+            }
         }
         return tags[slotIndex];
     }