changeset 15876:8df3b6d4a035

Merge.
author Thomas Wuerthinger <thomas.wuerthinger@oracle.com>
date Tue, 13 May 2014 02:31:41 +0200
parents 2d5f9c7379c1 (current diff) d556971b409c (diff)
children f55153a2ca55
files
diffstat 21 files changed, 329 insertions(+), 261 deletions(-) [+]
line wrap: on
line diff
--- a/CHANGELOG.md	Tue May 13 02:31:20 2014 +0200
+++ b/CHANGELOG.md	Tue May 13 02:31:41 2014 +0200
@@ -2,9 +2,10 @@
 
 ## `tip`
 ### Graal
-* ...
+* Made initialization of Graal runtime lazy in hosted mode.
 
 ### Truffle
+* `truffle.jar`: strip out build-time only dependency into a seperated JAR file (`truffle-dsl-processor.jar`)
 * ...
 
 ## Version 0.3
@@ -74,4 +75,3 @@
 
 * Initial version of a multi-language framework on top of Graal.
 * Update of the [Truffle Inlining API](http://mail.openjdk.java.net/pipermail/graal-dev/2014-January/001516.html).
-
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotGraalRuntime.java	Tue May 13 02:31:20 2014 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotGraalRuntime.java	Tue May 13 02:31:41 2014 +0200
@@ -25,6 +25,7 @@
 import static com.oracle.graal.compiler.common.GraalOptions.*;
 import static com.oracle.graal.compiler.common.UnsafeAccess.*;
 import static com.oracle.graal.hotspot.HotSpotGraalRuntime.Options.*;
+import static sun.reflect.Reflection.*;
 
 import java.lang.reflect.*;
 import java.util.*;
@@ -54,9 +55,26 @@
  */
 public final class HotSpotGraalRuntime implements GraalRuntime, RuntimeProvider, StackIntrospection {
 
-    private static final HotSpotGraalRuntime instance = new HotSpotGraalRuntime();
+    private static final HotSpotGraalRuntime instance;
+
+    /**
+     * Initializes the native part of the Graal runtime.
+     */
+    private static native void init(Class<?> compilerToVMClass);
+
     static {
+        init(CompilerToVMImpl.class);
+
+        // The options must be processed before any code using them...
+        HotSpotOptions.initialize();
+
+        // ... including code in the constructor
+        instance = new HotSpotGraalRuntime();
+
+        // Why deferred initialization? See comment in completeInitialization().
         instance.completeInitialization();
+
+        registerFieldsToFilter(HotSpotGraalRuntime.class, "instance");
     }
 
     /**
@@ -75,10 +93,6 @@
         return instance;
     }
 
-    static {
-        Reflection.registerFieldsToFilter(HotSpotGraalRuntime.class, "instance");
-    }
-
     /**
      * Do deferred initialization.
      */
@@ -104,6 +118,8 @@
 
         this.vmToCompiler = toCompiler;
         this.compilerToVm = toVM;
+
+        this.vmToCompiler.startRuntime();
     }
 
     // Options must not be directly declared in HotSpotGraalRuntime - see VerifyOptionsPhase
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotOptions.java	Tue May 13 02:31:20 2014 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotOptions.java	Tue May 13 02:31:41 2014 +0200
@@ -87,7 +87,7 @@
             try {
                 for (String line : Files.readAllLines(graalDotOptions, Charset.defaultCharset())) {
                     if (!line.startsWith("#")) {
-                        if (!setOption(line)) {
+                        if (!parseOption(line, null)) {
                             throw new InternalError("Invalid option \"" + line + "\" specified in " + graalDotOptions);
                         }
                     }
@@ -98,14 +98,39 @@
         }
     }
 
+    /**
+     * Gets the Graal specific options specified to HotSpot (e.g., on the command line).
+     *
+     * @param timeCompilations (out) true if the CITime or CITimeEach HotSpot VM options are set
+     */
+    private static native String[] getVMOptions(boolean[] timeCompilations);
+
     static {
         initializeOptions();
         loadOptionOverrides();
+
+        boolean[] timeCompilations = {false};
+        for (String option : getVMOptions(timeCompilations)) {
+            if (!parseOption(option, null)) {
+                throw new InternalError("Invalid Graal option \"-G:" + option + "\"");
+            }
+        }
+
+        if (timeCompilations[0] || PrintCompRate.getValue() != 0) {
+            unconditionallyEnableTimerOrMetric(InliningUtil.class, "InlinedBytecodes");
+            unconditionallyEnableTimerOrMetric(CompilationTask.class, "CompilationTime");
+        }
+        assert !Debug.Initialization.isDebugInitialized() : "The class " + Debug.class.getName() + " must not be initialized before the Graal runtime has been initialized. " +
+                        "This can be fixed by placing a call to " + Graal.class.getName() + ".runtime() on the path that triggers initialization of " + Debug.class.getName();
+        if (areDebugScopePatternsEnabled()) {
+            System.setProperty(Debug.Initialization.INITIALIZER_PROPERTY_NAME, "true");
+        }
     }
 
-    // Called from VM code
-    public static boolean setOption(String option) {
-        return parseOption(option, null);
+    /**
+     * Ensures {@link HotSpotOptions} is initialized.
+     */
+    public static void initialize() {
     }
 
     interface OptionConsumer {
@@ -238,24 +263,6 @@
     }
 
     /**
-     * Called from VM code once all Graal command line options have been processed by
-     * {@link #setOption(String)}.
-     *
-     * @param timeCompilations true if the CITime or CITimeEach HotSpot VM options are set
-     */
-    public static void finalizeOptions(boolean timeCompilations) {
-        if (timeCompilations || PrintCompRate.getValue() != 0) {
-            unconditionallyEnableTimerOrMetric(InliningUtil.class, "InlinedBytecodes");
-            unconditionallyEnableTimerOrMetric(CompilationTask.class, "CompilationTime");
-        }
-        assert !Debug.Initialization.isDebugInitialized() : "The class " + Debug.class.getName() + " must not be initialized before the Graal runtime has been initialized. " +
-                        "This can be fixed by placing a call to " + Graal.class.getName() + ".runtime() on the path that triggers initialization of " + Debug.class.getName();
-        if (areDebugScopePatternsEnabled()) {
-            System.setProperty(Debug.Initialization.INITIALIZER_PROPERTY_NAME, "true");
-        }
-    }
-
-    /**
      * Wraps some given text to one or more lines of a given maximum width.
      *
      * @param text text to wrap
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/bridge/VMToCompiler.java	Tue May 13 02:31:20 2014 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/bridge/VMToCompiler.java	Tue May 13 02:31:41 2014 +0200
@@ -30,7 +30,7 @@
  */
 public interface VMToCompiler {
 
-    void startRuntime() throws Throwable;
+    void startRuntime();
 
     void startCompiler(boolean bootstrapEnabled) throws Throwable;
 
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/bridge/VMToCompilerImpl.java	Tue May 13 02:31:20 2014 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/bridge/VMToCompilerImpl.java	Tue May 13 02:31:41 2014 +0200
@@ -142,7 +142,7 @@
         this.runtime = runtime;
     }
 
-    public void startRuntime() throws Throwable {
+    public void startRuntime() {
 
         if (LogFile.getValue() != null) {
             try {
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/MemoryMapNode.java	Tue May 13 02:31:20 2014 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/MemoryMapNode.java	Tue May 13 02:31:41 2014 +0200
@@ -41,5 +41,5 @@
 
     public abstract Set<LocationIdentity> getLocations();
 
-    public abstract void replaceLastLocationAccess(MemoryNode oldNode, MemoryNode newNode);
+    public abstract boolean replaceLastLocationAccess(MemoryNode oldNode, MemoryNode newNode);
 }
--- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/FloatingReadPhase.java	Tue May 13 02:31:20 2014 +0200
+++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/FloatingReadPhase.java	Tue May 13 02:31:41 2014 +0200
@@ -92,12 +92,15 @@
         }
 
         @Override
-        public void replaceLastLocationAccess(MemoryNode oldNode, MemoryNode newNode) {
+        public boolean replaceLastLocationAccess(MemoryNode oldNode, MemoryNode newNode) {
+            boolean replaced = false;
             for (Map.Entry<LocationIdentity, MemoryNode> entry : lastMemorySnapshot.entrySet()) {
                 if (entry.getValue() == oldNode) {
                     entry.setValue(newNode);
+                    replaced = true;
                 }
             }
+            return replaced;
         }
     }
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/inlining/InliningIterator.java	Tue May 13 02:31:41 2014 +0200
@@ -0,0 +1,130 @@
+/*
+ * Copyright (c) 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.phases.common.inlining;
+
+import com.oracle.graal.graph.Node;
+import com.oracle.graal.graph.NodeBitMap;
+import com.oracle.graal.nodes.*;
+import com.oracle.graal.nodes.java.MethodCallTargetNode;
+
+import java.util.ArrayDeque;
+import java.util.Deque;
+import java.util.LinkedList;
+
+/**
+ * Given a graph, visit all fixed nodes in dominator-based order, collecting in the process the
+ * {@link Invoke} nodes with {@link MethodCallTargetNode}. Such list of callsites is returned by
+ * {@link #apply()}
+ */
+class InliningIterator {
+
+    private final StartNode start;
+    private final Deque<FixedNode> nodeQueue;
+    private final NodeBitMap queuedNodes;
+
+    public InliningIterator(StructuredGraph graph) {
+        this.start = graph.start();
+        this.nodeQueue = new ArrayDeque<>();
+        this.queuedNodes = graph.createNodeBitMap();
+        assert start.isAlive();
+    }
+
+    public LinkedList<Invoke> apply() {
+        LinkedList<Invoke> invokes = new LinkedList<>();
+        FixedNode current;
+        forcedQueue(start);
+
+        while ((current = nextQueuedNode()) != null) {
+            assert current.isAlive();
+
+            if (current instanceof Invoke && ((Invoke) current).callTarget() instanceof MethodCallTargetNode) {
+                if (current != start) {
+                    invokes.addLast((Invoke) current);
+                }
+                queueSuccessors(current);
+            } else if (current instanceof LoopBeginNode) {
+                queueSuccessors(current);
+            } else if (current instanceof LoopEndNode) {
+                // nothing to do
+            } else if (current instanceof MergeNode) {
+                queueSuccessors(current);
+            } else if (current instanceof FixedWithNextNode) {
+                queueSuccessors(current);
+            } else if (current instanceof EndNode) {
+                queueMerge((EndNode) current);
+            } else if (current instanceof ControlSinkNode) {
+                // nothing to do
+            } else if (current instanceof ControlSplitNode) {
+                queueSuccessors(current);
+            } else {
+                assert false : current;
+            }
+        }
+
+        return invokes;
+    }
+
+    private void queueSuccessors(FixedNode x) {
+        for (Node node : x.successors()) {
+            queue(node);
+        }
+    }
+
+    private void queue(Node node) {
+        if (node != null && !queuedNodes.isMarked(node)) {
+            forcedQueue(node);
+        }
+    }
+
+    private void forcedQueue(Node node) {
+        queuedNodes.mark(node);
+        nodeQueue.addFirst((FixedNode) node);
+    }
+
+    private FixedNode nextQueuedNode() {
+        if (nodeQueue.isEmpty()) {
+            return null;
+        }
+
+        FixedNode result = nodeQueue.removeFirst();
+        assert queuedNodes.isMarked(result);
+        return result;
+    }
+
+    private void queueMerge(AbstractEndNode end) {
+        MergeNode merge = end.merge();
+        if (!queuedNodes.isMarked(merge) && visitedAllEnds(merge)) {
+            queuedNodes.mark(merge);
+            nodeQueue.add(merge);
+        }
+    }
+
+    private boolean visitedAllEnds(MergeNode merge) {
+        for (int i = 0; i < merge.forwardEndCount(); i++) {
+            if (!queuedNodes.isMarked(merge.forwardEndAt(i))) {
+                return false;
+            }
+        }
+        return true;
+    }
+}
--- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/inlining/InliningPhase.java	Tue May 13 02:31:20 2014 +0200
+++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/inlining/InliningPhase.java	Tue May 13 02:31:41 2014 +0200
@@ -477,106 +477,13 @@
         }
     }
 
-    private static class InliningIterator {
-
-        private final FixedNode start;
-        private final Deque<FixedNode> nodeQueue;
-        private final NodeBitMap queuedNodes;
-
-        public InliningIterator(FixedNode start, NodeBitMap visitedFixedNodes) {
-            this.start = start;
-            this.nodeQueue = new ArrayDeque<>();
-            this.queuedNodes = visitedFixedNodes;
-            assert start.isAlive();
-        }
-
-        public LinkedList<Invoke> apply() {
-            LinkedList<Invoke> invokes = new LinkedList<>();
-            FixedNode current;
-            forcedQueue(start);
-
-            while ((current = nextQueuedNode()) != null) {
-                assert current.isAlive();
-
-                if (current instanceof Invoke && ((Invoke) current).callTarget() instanceof MethodCallTargetNode) {
-                    if (current != start) {
-                        invokes.addLast((Invoke) current);
-                    }
-                    queueSuccessors(current);
-                } else if (current instanceof LoopBeginNode) {
-                    queueSuccessors(current);
-                } else if (current instanceof LoopEndNode) {
-                    // nothing todo
-                } else if (current instanceof MergeNode) {
-                    queueSuccessors(current);
-                } else if (current instanceof FixedWithNextNode) {
-                    queueSuccessors(current);
-                } else if (current instanceof EndNode) {
-                    queueMerge((EndNode) current);
-                } else if (current instanceof ControlSinkNode) {
-                    // nothing todo
-                } else if (current instanceof ControlSplitNode) {
-                    queueSuccessors(current);
-                } else {
-                    assert false : current;
-                }
-            }
-
-            return invokes;
-        }
-
-        private void queueSuccessors(FixedNode x) {
-            for (Node node : x.successors()) {
-                queue(node);
-            }
-        }
-
-        private void queue(Node node) {
-            if (node != null && !queuedNodes.isMarked(node)) {
-                forcedQueue(node);
-            }
-        }
-
-        private void forcedQueue(Node node) {
-            queuedNodes.mark(node);
-            nodeQueue.addFirst((FixedNode) node);
-        }
-
-        private FixedNode nextQueuedNode() {
-            if (nodeQueue.isEmpty()) {
-                return null;
-            }
-
-            FixedNode result = nodeQueue.removeFirst();
-            assert queuedNodes.isMarked(result);
-            return result;
-        }
-
-        private void queueMerge(AbstractEndNode end) {
-            MergeNode merge = end.merge();
-            if (!queuedNodes.isMarked(merge) && visitedAllEnds(merge)) {
-                queuedNodes.mark(merge);
-                nodeQueue.add(merge);
-            }
-        }
-
-        private boolean visitedAllEnds(MergeNode merge) {
-            for (int i = 0; i < merge.forwardEndCount(); i++) {
-                if (!queuedNodes.isMarked(merge.forwardEndAt(i))) {
-                    return false;
-                }
-            }
-            return true;
-        }
-    }
-
     /**
      * Holds the data for building the callee graphs recursively: graphs and invocations (each
      * invocation can have multiple graphs).
      */
     static class InliningData {
 
-        private static final GraphInfo DummyGraphInfo = new GraphInfo(null, new LinkedList<Invoke>(), 1.0, 1.0);
+        private static final GraphInfo DummyGraphInfo = new GraphInfo(null, 1.0, 1.0);
 
         /**
          * Call hierarchy from outer most call (i.e., compilation unit) to inner most callee.
@@ -601,10 +508,7 @@
 
         public void pushGraph(StructuredGraph graph, double probability, double relevance) {
             assert !contains(graph);
-            NodeBitMap visitedFixedNodes = graph.createNodeBitMap();
-            LinkedList<Invoke> invokes = new InliningIterator(graph.start(), visitedFixedNodes).apply();
-            assert invokes.size() == count(graph.getInvokes());
-            graphQueue.push(new GraphInfo(graph, invokes, probability, relevance));
+            graphQueue.push(new GraphInfo(graph, probability, relevance));
             assert graphQueue.size() <= maxGraphs;
         }
 
@@ -712,16 +616,6 @@
             }
             return false;
         }
-
-        private static int count(Iterable<Invoke> invokes) {
-            int count = 0;
-            Iterator<Invoke> iterator = invokes.iterator();
-            while (iterator.hasNext()) {
-                iterator.next();
-                count++;
-            }
-            return count;
-        }
     }
 
     private static class MethodInvocation {
@@ -803,13 +697,19 @@
         private final ToDoubleFunction<FixedNode> probabilities;
         private final ComputeInliningRelevance computeInliningRelevance;
 
-        public GraphInfo(StructuredGraph graph, LinkedList<Invoke> invokes, double probability, double relevance) {
+        public GraphInfo(StructuredGraph graph, double probability, double relevance) {
             this.graph = graph;
-            this.remainingInvokes = invokes;
+            if (graph == null) {
+                this.remainingInvokes = new LinkedList<>();
+            } else {
+                LinkedList<Invoke> invokes = new InliningIterator(graph).apply();
+                assert invokes.size() == count(graph.getInvokes());
+                this.remainingInvokes = invokes;
+            }
             this.probability = probability;
             this.relevance = relevance;
 
-            if (graph != null && (graph.hasNode(InvokeNode.class) || graph.hasNode(InvokeWithExceptionNode.class))) {
+            if (graph != null && !remainingInvokes.isEmpty()) {
                 probabilities = new FixedNodeProbabilityCache();
                 computeInliningRelevance = new ComputeInliningRelevance(graph, probabilities);
                 computeProbabilities();
@@ -819,6 +719,16 @@
             }
         }
 
+        private static int count(Iterable<Invoke> invokes) {
+            int count = 0;
+            Iterator<Invoke> iterator = invokes.iterator();
+            while (iterator.hasNext()) {
+                iterator.next();
+                count++;
+            }
+            return count;
+        }
+
         /**
          * Gets the method associated with the {@linkplain #graph() graph} represented by this
          * object.
--- a/graal/com.oracle.graal.phases/src/com/oracle/graal/phases/schedule/SchedulePhase.java	Tue May 13 02:31:20 2014 +0200
+++ b/graal/com.oracle.graal.phases/src/com/oracle/graal/phases/schedule/SchedulePhase.java	Tue May 13 02:31:41 2014 +0200
@@ -83,32 +83,56 @@
     }
 
     private class KillSet implements Iterable<LocationIdentity> {
-        private final Set<LocationIdentity> set;
+        private List<LocationIdentity> list;
 
         public KillSet() {
-            this.set = new ArraySet<>();
+            list = null;
         }
 
         public KillSet(KillSet other) {
-            this.set = new HashSet<>(other.set);
+            if (other.list != null && other.list.size() > 0) {
+                list = new ArrayList<>(other.list);
+            }
+        }
+
+        private void initSet() {
+            if (list == null) {
+                list = new ArrayList<>(4);
+            }
         }
 
         public void add(LocationIdentity locationIdentity) {
-            set.add(locationIdentity);
+            if (list == null || !list.contains(locationIdentity)) {
+                initSet();
+                list.add(locationIdentity);
+            }
         }
 
         public void addAll(KillSet other) {
-            set.addAll(other.set);
+            if (other.list == null) {
+                return;
+            }
+            initSet();
+            for (LocationIdentity locationIdentity : other) {
+                if (!list.contains(locationIdentity)) {
+                    list.add(locationIdentity);
+                }
+            }
         }
 
         public Iterator<LocationIdentity> iterator() {
-            return set.iterator();
+            if (list == null) {
+                return Collections.emptyIterator();
+            }
+            return list.iterator();
         }
 
         public boolean isKilled(LocationIdentity locationIdentity) {
-            return set.contains(locationIdentity);
+            if (list == null) {
+                return false;
+            }
+            return list.contains(locationIdentity);
         }
-
     }
 
     private class NewMemoryScheduleClosure extends BlockIteratorClosure<KillSet> {
--- a/graal/com.oracle.graal.phases/src/com/oracle/graal/phases/util/ArraySet.java	Tue May 13 02:31:20 2014 +0200
+++ b/graal/com.oracle.graal.phases/src/com/oracle/graal/phases/util/ArraySet.java	Tue May 13 02:31:41 2014 +0200
@@ -47,7 +47,7 @@
     public boolean add(E e) {
         // avoid duplicated entries
         if (contains(e)) {
-            return true;
+            return false;
         }
         return super.add(e);
     }
--- a/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/SnippetTemplate.java	Tue May 13 02:31:20 2014 +0200
+++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/SnippetTemplate.java	Tue May 13 02:31:41 2014 +0200
@@ -643,11 +643,6 @@
 
         MemoryAnchorNode memoryAnchor = snippetCopy.add(new MemoryAnchorNode());
         snippetCopy.start().replaceAtUsages(InputType.Memory, memoryAnchor);
-        if (memoryAnchor.usages().isEmpty()) {
-            memoryAnchor.safeDelete();
-        } else {
-            snippetCopy.addAfterFixed(snippetCopy.start(), memoryAnchor);
-        }
 
         this.snippet = snippetCopy;
 
@@ -656,9 +651,10 @@
         List<ReturnNode> returnNodes = new ArrayList<>(4);
         List<MemoryMapNode> memMaps = new ArrayList<>(4);
         StartNode entryPointNode = snippet.start();
+        boolean anchorUsed = false;
         for (ReturnNode retNode : snippet.getNodes(ReturnNode.class)) {
             MemoryMapNode memMap = retNode.getMemoryMap();
-            memMap.replaceLastLocationAccess(snippetCopy.start(), memoryAnchor);
+            anchorUsed |= memMap.replaceLastLocationAccess(snippetCopy.start(), memoryAnchor);
             memMaps.add(memMap);
             retNode.setMemoryMap(null);
             returnNodes.add(retNode);
@@ -666,6 +662,11 @@
                 memMap.safeDelete();
             }
         }
+        if (memoryAnchor.usages().isEmpty() && !anchorUsed) {
+            memoryAnchor.safeDelete();
+        } else {
+            snippetCopy.addAfterFixed(snippetCopy.start(), memoryAnchor);
+        }
         assert snippet.getNodes().filter(MemoryMapNode.class).isEmpty();
         if (returnNodes.isEmpty()) {
             this.returnNode = null;
@@ -1009,7 +1010,7 @@
         }
 
         @Override
-        public void replaceLastLocationAccess(MemoryNode oldNode, MemoryNode newNode) {
+        public boolean replaceLastLocationAccess(MemoryNode oldNode, MemoryNode newNode) {
             throw GraalInternalError.shouldNotReachHere();
         }
     }
--- a/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/Truffle.java	Tue May 13 02:31:20 2014 +0200
+++ b/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/Truffle.java	Tue May 13 02:31:41 2014 +0200
@@ -33,7 +33,14 @@
 
     private static final TruffleRuntime RUNTIME;
 
-    private static native TruffleRuntime initializeRuntime();
+    /**
+     * Creates a new {@link TruffleRuntime} instance if the runtime has a specialized
+     * implementation.
+     *
+     * @throws UnsatisfiedLinkError if the runtime does not have a specialized implementation of
+     *             {@link TruffleRuntime}
+     */
+    private static native TruffleRuntime createRuntime();
 
     public static TruffleRuntime getRuntime() {
         return RUNTIME;
@@ -42,7 +49,7 @@
     static {
         TruffleRuntime runtime;
         try {
-            runtime = initializeRuntime();
+            runtime = createRuntime();
         } catch (UnsatisfiedLinkError e) {
             runtime = new DefaultTruffleRuntime();
         }
--- a/mx/projects	Tue May 13 02:31:20 2014 +0200
+++ b/mx/projects	Tue May 13 02:31:41 2014 +0200
@@ -87,7 +87,7 @@
 distribution@TRUFFLE-DSL-PROCESSOR@sourcesPath=truffle-dsl-processor-sources.jar
 distribution@TRUFFLE-DSL-PROCESSOR@dependencies=\
 com.oracle.truffle.dsl.processor
-distribution@TRUFFLE-DSL-PROCESSOR@exclude=com.oracle.truffle.api.dsl,com.oracle.truffle.api
+distribution@TRUFFLE-DSL-PROCESSOR@distDependency=TRUFFLE
 
 # graal.api.collections
 project@com.oracle.graal.api.collections@subDir=graal
--- a/mxtool/mx.py	Tue May 13 02:31:20 2014 +0200
+++ b/mxtool/mx.py	Tue May 13 02:31:41 2014 +0200
@@ -62,7 +62,7 @@
 A distribution is a jar or zip file containing the output from one or more Java projects.
 """
 class Distribution:
-    def __init__(self, suite, name, path, sourcesPath, deps, excludedDependencies):
+    def __init__(self, suite, name, path, sourcesPath, deps, excludedDependencies, distDependency):
         self.suite = suite
         self.name = name
         self.path = path.replace('/', os.sep)
@@ -71,6 +71,7 @@
         self.deps = deps
         self.update_listeners = set()
         self.excludedDependencies = excludedDependencies
+        self.distDependency = distDependency
 
     def sorted_deps(self, includeLibs=False):
         try:
@@ -124,6 +125,11 @@
                                 srcArc.zf.writestr(arcname, lp.read(arcname))
                 else:
                     p = dep
+
+                    if self.distDependency and p in _dists[self.distDependency].sorted_deps():
+                        logv("Excluding {0} from {1} because it's provided by the dependency {2}".format(p.name, self.path, self.distDependency))
+                        continue
+
                     # skip a  Java project if its Java compliance level is "higher" than the configured JDK
                     jdk = java(p.javaCompliance)
                     if not jdk:
@@ -749,7 +755,8 @@
             sourcesPath = attrs.pop('sourcesPath', None)
             deps = pop_list(attrs, 'dependencies')
             exclDeps = pop_list(attrs, 'exclude')
-            d = Distribution(self, name, path, sourcesPath, deps, exclDeps)
+            distDep = attrs.pop('distDependency', None)
+            d = Distribution(self, name, path, sourcesPath, deps, exclDeps, distDep)
             d.__dict__.update(attrs)
             self.dists.append(d)
 
--- a/src/share/vm/classfile/vmSymbols.hpp	Tue May 13 02:31:20 2014 +0200
+++ b/src/share/vm/classfile/vmSymbols.hpp	Tue May 13 02:31:41 2014 +0200
@@ -297,8 +297,6 @@
   template(com_oracle_graal_graph_NodeClass,                         "com/oracle/graal/graph/NodeClass")                              \
   /* graal.hotspot */                                                                                                                 \
   template(com_oracle_graal_hotspot_HotSpotGraalRuntime,             "com/oracle/graal/hotspot/HotSpotGraalRuntime")                  \
-  template(com_oracle_graal_hotspot_HotSpotKlassOop,                 "com/oracle/graal/hotspot/HotSpotKlassOop")                      \
-  template(com_oracle_graal_hotspot_HotSpotOptions,                  "com/oracle/graal/hotspot/HotSpotOptions")                       \
   template(com_oracle_graal_hotspot_HotSpotCompiledCode,             "com/oracle/graal/hotspot/HotSpotCompiledCode")                  \
   template(com_oracle_graal_hotspot_HotSpotCompiledCode_Comment,     "com/oracle/graal/hotspot/HotSpotCompiledCode$Comment")          \
   template(com_oracle_graal_hotspot_HotSpotCompiledNmethod,          "com/oracle/graal/hotspot/HotSpotCompiledNmethod")               \
--- a/src/share/vm/graal/graalCompiler.cpp	Tue May 13 02:31:20 2014 +0200
+++ b/src/share/vm/graal/graalCompiler.cpp	Tue May 13 02:31:41 2014 +0200
@@ -48,8 +48,6 @@
     return;
   }
 
-  GraalRuntime::initialize();
-
   BufferBlob* buffer_blob = GraalRuntime::initialize_buffer_blob();
   if (!UseGraalCompilationQueue) {
     // This path is used for initialization both by the native queue and the graal queue
@@ -68,7 +66,11 @@
     bool bootstrap = UseGraalCompilationQueue && (FLAG_IS_DEFAULT(BootstrapGraal) ? !TieredCompilation : BootstrapGraal);
     VMToCompiler::startCompiler(bootstrap);
     _started = true;
+
+    // Graal is considered as application code so we need to
+    // stop the VM deferring compilation now.
     CompilationPolicy::completed_vm_startup();
+
     if (bootstrap) {
       // Avoid -Xcomp and -Xbatch problems by turning on interpreter and background compilation for bootstrapping.
       FlagSetting a(UseInterpreter, true);
--- a/src/share/vm/graal/graalRuntime.cpp	Tue May 13 02:31:20 2014 +0200
+++ b/src/share/vm/graal/graalRuntime.cpp	Tue May 13 02:31:41 2014 +0200
@@ -37,97 +37,30 @@
 #include "utilities/debug.hpp"
 
 address GraalRuntime::_external_deopt_i2c_entry = NULL;
-volatile GraalRuntime::State GraalRuntime::_state = uninitialized;
-Thread* GraalRuntime::_initializingThread = NULL;
 
-bool GraalRuntime::should_perform_init() {
-  JavaThread* THREAD = JavaThread::current();
-  if (_state != initialized) {
-    if (THREAD == _initializingThread) {
-      return false;
-    }
-    MutexLocker locker(GraalInitialization_lock);
-    if (_state == uninitialized) {
-      _state = initializing;
-      _initializingThread = THREAD;
-      return true;
-    } else {
-      while (_state == initializing) {
-        GraalInitialization_lock->wait();
-      }
-    }
-  }
-  return false;
-}
-
-void GraalRuntime::initialize() {
-  if (!should_perform_init()) {
-    return;
-  }
-
+void GraalRuntime::initialize_natives(JNIEnv *env, jclass c2vmClass) {
   uintptr_t heap_end = (uintptr_t) Universe::heap()->reserved_region().end();
   uintptr_t allocation_end = heap_end + ((uintptr_t)16) * 1024 * 1024 * 1024;
   AMD64_ONLY(guarantee(heap_end < allocation_end, "heap end too close to end of address space (might lead to erroneous TLAB allocations)"));
   NOT_LP64(error("check TLAB allocation code for address space conflicts"));
 
   JavaThread* THREAD = JavaThread::current();
-  ThreadToNativeFromVM trans(THREAD);
-  TRACE_graal_1("GraalRuntime::initialize");
-
-  JNIEnv *env = ((JavaThread *) Thread::current())->jni_environment();
-  jclass klass = env->FindClass("com/oracle/graal/hotspot/bridge/CompilerToVMImpl");
-  if (klass == NULL) {
-    tty->print_cr("graal CompilerToVMImpl class not found");
-    vm_abort(false);
-  }
-  env->RegisterNatives(klass, CompilerToVM_methods, CompilerToVM_methods_count());
-
-  ResourceMark rm;
-  HandleMark hm;
   {
-    GRAAL_VM_ENTRY_MARK;
-    check_pending_exception("Could not register natives");
-  }
+    ThreadToNativeFromVM trans(THREAD);
 
-  graal_compute_offsets();
-
-  // Ensure _non_oop_bits is initialized
-  Universe::non_oop_word();
-
-  {
-    GRAAL_VM_ENTRY_MARK;
+    ResourceMark rm;
     HandleMark hm;
-    VMToCompiler::initOptions();
-    for (int i = 0; i < Arguments::num_graal_args(); ++i) {
-      const char* arg = Arguments::graal_args_array()[i];
-      Handle option = java_lang_String::create_from_str(arg, THREAD);
-      jboolean result = VMToCompiler::setOption(option);
-      if (!result) {
-        tty->print_cr("Invalid option for graal: -G:%s", arg);
-        vm_abort(false);
-      }
-    }
-    VMToCompiler::finalizeOptions(CITime || CITimeEach);
+
+    graal_compute_offsets();
 
     _external_deopt_i2c_entry = create_external_deopt_i2c();
 
-    VMToCompiler::startRuntime();
-
-    {
-      MutexLocker locker(GraalInitialization_lock);
-      _state = initialized;
-      _initializingThread = NULL;
-    }
+    // Ensure _non_oop_bits is initialized
+    Universe::non_oop_word();
 
-#if !defined(PRODUCT) && !defined(COMPILERGRAAL)
-    // In COMPILERGRAAL, we want to allow GraalBootstrap
-    // to happen first so GraalCompiler::initialize()
-    // duplicates the following code.
-    if (CompileTheWorld) {
-      VMToCompiler::compileTheWorld();
-    }
-#endif
+    env->RegisterNatives(c2vmClass, CompilerToVM_methods, CompilerToVM_methods_count());
   }
+  check_pending_exception("Could not register natives");
 }
 
 BufferBlob* GraalRuntime::initialize_buffer_blob() {
@@ -703,14 +636,32 @@
   }
 JRT_END
 
-// JVM_InitializeGraalRuntime
-JVM_ENTRY(jobject, JVM_InitializeGraalRuntime(JNIEnv *env, jclass graalclass))
-  GraalRuntime::initialize();
+// private static GraalRuntime Graal.initializeRuntime()
+JVM_ENTRY(jobject, JVM_GetGraalRuntime(JNIEnv *env, jclass c))
   return VMToCompiler::get_HotSpotGraalRuntime_jobject();
 JVM_END
 
-// JVM_InitializeTruffleRuntime
-JVM_ENTRY(jobject, JVM_InitializeTruffleRuntime(JNIEnv *env, jclass graalclass))
-  GraalRuntime::initialize();
+// private static TruffleRuntime Truffle.createRuntime()
+JVM_ENTRY(jobject, JVM_CreateTruffleRuntime(JNIEnv *env, jclass c))
   return JNIHandles::make_local(VMToCompiler::create_HotSpotTruffleRuntime()());
 JVM_END
+
+// private static void HotSpotGraalRuntime.init(Class compilerToVMClass)
+JVM_ENTRY(void, JVM_InitializeGraalNatives(JNIEnv *env, jclass c, jclass c2vmClass))
+  GraalRuntime::initialize_natives(env, c2vmClass);
+JVM_END
+
+// private static String[] HotSpotOptions.getVMOptions(boolean[] timeCompilations)
+JVM_ENTRY(jobject, JVM_GetGraalOptions(JNIEnv *env, jclass c, jobject timeCompilations))
+  HandleMark hm;
+  int numOptions = Arguments::num_graal_args();
+  objArrayOop options = oopFactory::new_objArray(SystemDictionary::String_klass(),
+      numOptions, CHECK_NULL);
+  objArrayHandle optionsHandle(THREAD, options);
+  for (int i = 0; i < numOptions; i++) {
+    Handle option = java_lang_String::create_from_str(Arguments::graal_args_array()[i], CHECK_NULL);
+    optionsHandle->obj_at_put(i, option());
+  }
+  ((typeArrayOop) JNIHandles::resolve(timeCompilations))->bool_at_put(0, CITime || CITimeEach);
+  return JNIHandles::make_local(THREAD, optionsHandle());
+JVM_END
--- a/src/share/vm/graal/graalRuntime.hpp	Tue May 13 02:31:20 2014 +0200
+++ b/src/share/vm/graal/graalRuntime.hpp	Tue May 13 02:31:41 2014 +0200
@@ -33,14 +33,9 @@
 
   static address   _external_deopt_i2c_entry;
 
-  enum State { uninitialized, initializing, initialized };
-  static volatile State _state;
-  static Thread* _initializingThread;
-  static bool should_perform_init();
-
  public:
 
-  static /*synchronized*/ void initialize();
+  static void initialize_natives(JNIEnv *env, jclass c2vmClass);
   static BufferBlob* initialize_buffer_blob();
   static BasicType kindToBasicType(jchar ch);
   static address create_external_deopt_i2c();
--- a/src/share/vm/prims/jni.cpp	Tue May 13 02:31:20 2014 +0200
+++ b/src/share/vm/prims/jni.cpp	Tue May 13 02:31:41 2014 +0200
@@ -35,6 +35,7 @@
 #include "utilities/macros.hpp"
 #ifdef GRAAL
 #include "graal/graalCompiler.hpp"
+#include "graal/graalVMToCompiler.hpp"
 #endif
 #if INCLUDE_ALL_GCS
 #include "gc_implementation/g1/g1SATBCardTableModRefBS.hpp"
@@ -5210,7 +5211,19 @@
   #endif
 
     // Check if we should compile all classes on bootclasspath
+#ifdef GRAAL
+#ifndef COMPILERGRAAL
+    if (CompileTheWorld) {
+      // Graal is considered as application code so we need to
+      // stop the VM deferring compilation now.
+      CompilationPolicy::completed_vm_startup();
+
+      VMToCompiler::compileTheWorld();
+    }
+#endif
+#else
     if (CompileTheWorld) ClassLoader::compile_the_world();
+#endif
     if (ReplayCompiles) ciReplay::replay(thread);
 
     // Some platforms (like Win*) need a wrapper around these test
--- a/src/share/vm/prims/nativeLookup.cpp	Tue May 13 02:31:20 2014 +0200
+++ b/src/share/vm/prims/nativeLookup.cpp	Tue May 13 02:31:41 2014 +0200
@@ -124,8 +124,10 @@
   void JNICALL JVM_RegisterPerfMethods(JNIEnv *env, jclass perfclass);
   void JNICALL JVM_RegisterWhiteBoxMethods(JNIEnv *env, jclass wbclass);
 #ifdef GRAAL
-  jobject JNICALL JVM_InitializeGraalRuntime(JNIEnv *env, jclass graalclass);
-  jobject JNICALL JVM_InitializeTruffleRuntime(JNIEnv *env, jclass graalclass);
+  void    JNICALL JVM_InitializeGraalNatives(JNIEnv *env, jclass c, jclass compilerToVMClass);
+  jobject JNICALL JVM_GetGraalRuntime(JNIEnv *env, jclass c);
+  jobject JNICALL JVM_CreateTruffleRuntime(JNIEnv *env, jclass c);
+  jobject JNICALL JVM_GetGraalOptions(JNIEnv *env, jclass hotspotOptionsClass, jobject timeCompilations);
 #endif
 }
 
@@ -138,8 +140,10 @@
   { CC"Java_sun_misc_Perf_registerNatives",                        NULL, FN_PTR(JVM_RegisterPerfMethods)         },
   { CC"Java_sun_hotspot_WhiteBox_registerNatives",                 NULL, FN_PTR(JVM_RegisterWhiteBoxMethods)     },
 #ifdef GRAAL
-  { CC"Java_com_oracle_graal_api_runtime_Graal_initializeRuntime", NULL, FN_PTR(JVM_InitializeGraalRuntime)      },
-  { CC"Java_com_oracle_truffle_api_Truffle_initializeRuntime",     NULL, FN_PTR(JVM_InitializeTruffleRuntime)    },
+  { CC"Java_com_oracle_graal_api_runtime_Graal_initializeRuntime", NULL, FN_PTR(JVM_GetGraalRuntime)             },
+  { CC"Java_com_oracle_truffle_api_Truffle_createRuntime",         NULL, FN_PTR(JVM_CreateTruffleRuntime)        },
+  { CC"Java_com_oracle_graal_hotspot_HotSpotGraalRuntime_init",    NULL, FN_PTR(JVM_InitializeGraalNatives)      },
+  { CC"Java_com_oracle_graal_hotspot_HotSpotOptions_getVMOptions", NULL, FN_PTR(JVM_GetGraalOptions)             },
 #endif
 };