changeset 15587:cad72380191d

Merge
author Miguel Garcia <miguel.m.garcia@oracle.com>
date Fri, 09 May 2014 20:22:05 +0200
parents 642bd083a5cc (current diff) 063ec2920d21 (diff)
children 9a63ccd66007
files
diffstat 38 files changed, 808 insertions(+), 371 deletions(-) [+]
line wrap: on
line diff
--- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/FlowSenReduTest.java	Fri May 09 20:05:41 2014 +0200
+++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/FlowSenReduTest.java	Fri May 09 20:22:05 2014 +0200
@@ -384,7 +384,7 @@
 
     public StructuredGraph visualize(StructuredGraph graph, String title) {
         DebugConfig debugConfig = DebugScope.getConfig();
-        DebugConfig fixedConfig = Debug.fixedConfig(false, true, false, false, debugConfig.dumpHandlers(), debugConfig.output());
+        DebugConfig fixedConfig = Debug.fixedConfig(false, true, false, false, false, debugConfig.dumpHandlers(), debugConfig.output());
         try (DebugConfigScope s = Debug.setConfig(fixedConfig)) {
             Debug.dump(graph, title);
 
--- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/TypeSystemTest.java	Fri May 09 20:05:41 2014 +0200
+++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/TypeSystemTest.java	Fri May 09 20:22:05 2014 +0200
@@ -25,6 +25,7 @@
 import java.io.*;
 
 import com.oracle.graal.phases.common.cfs.FlowSensitiveReductionPhase;
+
 import org.junit.*;
 
 import com.oracle.graal.api.code.*;
@@ -181,6 +182,19 @@
         return ((InputStream) o).available();
     }
 
+    @Test
+    public void test7() {
+        test("test7Snippet", "referenceSnippet7");
+    }
+
+    public static int test7Snippet(int x) {
+        return ((x & 0xff) << 10) == ((x & 0x1f) + 1) ? 0 : x;
+    }
+
+    public static int referenceSnippet7(int x) {
+        return x;
+    }
+
     private void test(String snippet, String referenceSnippet) {
         StructuredGraph graph = parse(snippet);
         Debug.dump(graph, "Graph");
--- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/GraalDebugConfig.java	Fri May 09 20:05:41 2014 +0200
+++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/GraalDebugConfig.java	Fri May 09 20:22:05 2014 +0200
@@ -42,6 +42,8 @@
     public static final OptionValue<String> Dump = new OptionValue<>(null);
     @Option(help = "Pattern for scope(s) to in which metering is enabled (see DebugFilter and Debug.metric)")
     public static final OptionValue<String> Meter = new OptionValue<>(null);
+    @Option(help = "Pattern for scope(s) to in which memory use tracking is enabled (see DebugFilter and Debug.metric)")
+    public static final OptionValue<String> TrackMemUse = new OptionValue<>(null);
     @Option(help = "Pattern for scope(s) to in which timing is enabled (see DebugFilter and Debug.timer)")
     public static final OptionValue<String> Time = new OptionValue<>(null);
     @Option(help = "Pattern for scope(s) to in which logging is enabled (see DebugFilter and Debug.log)")
@@ -79,11 +81,12 @@
     }
 
     public static boolean areMetricsOrTimersEnabled() {
-        return Meter.getValue() != null || Time.getValue() != null;
+        return Meter.getValue() != null || Time.getValue() != null || TrackMemUse.getValue() != null;
     }
 
     private final DebugFilter logFilter;
     private final DebugFilter meterFilter;
+    private final DebugFilter trackMemUseFilter;
     private final DebugFilter timerFilter;
     private final DebugFilter dumpFilter;
     private final MethodFilter[] methodFilter;
@@ -91,9 +94,11 @@
     private final PrintStream output;
     private final Set<Object> extraFilters = new HashSet<>();
 
-    public GraalDebugConfig(String logFilter, String meterFilter, String timerFilter, String dumpFilter, String methodFilter, PrintStream output, List<DebugDumpHandler> dumpHandlers) {
+    public GraalDebugConfig(String logFilter, String meterFilter, String trackMemUseFilter, String timerFilter, String dumpFilter, String methodFilter, PrintStream output,
+                    List<DebugDumpHandler> dumpHandlers) {
         this.logFilter = DebugFilter.parse(logFilter);
         this.meterFilter = DebugFilter.parse(meterFilter);
+        this.trackMemUseFilter = DebugFilter.parse(trackMemUseFilter);
         this.timerFilter = DebugFilter.parse(timerFilter);
         this.dumpFilter = DebugFilter.parse(dumpFilter);
         if (methodFilter == null || methodFilter.isEmpty()) {
@@ -122,6 +127,14 @@
         return isEnabled(meterFilter);
     }
 
+    public boolean isMetderEnabled() {
+        return isEnabled(meterFilter);
+    }
+
+    public boolean isMemUseTrackingEnabled() {
+        return isEnabled(trackMemUseFilter);
+    }
+
     public boolean isDumpEnabled() {
         return isEnabled(dumpFilter);
     }
@@ -218,7 +231,7 @@
         if (e instanceof BailoutException) {
             return null;
         }
-        Debug.setConfig(Debug.fixedConfig(true, true, false, false, dumpHandlers, output));
+        Debug.setConfig(Debug.fixedConfig(true, true, false, false, false, dumpHandlers, output));
         Debug.log(String.format("Exception occurred in scope: %s", Debug.currentScope()));
         for (Object o : Debug.context()) {
             if (o instanceof Graph) {
--- a/graal/com.oracle.graal.debug/src/com/oracle/graal/debug/Debug.java	Fri May 09 20:05:41 2014 +0200
+++ b/graal/com.oracle.graal.debug/src/com/oracle/graal/debug/Debug.java	Fri May 09 20:22:05 2014 +0200
@@ -94,6 +94,10 @@
         return ENABLED && DebugScope.getInstance().isTimeEnabled();
     }
 
+    public static boolean isMemUseTrackingEnabled() {
+        return ENABLED && DebugScope.getInstance().isMemUseTrackingEnabled();
+    }
+
     public static boolean isLogEnabledForMethod() {
         if (!ENABLED) {
             return false;
@@ -586,6 +590,69 @@
     }
 
     /**
+     * Creates a {@linkplain DebugMemUseTracker memory use tracker} that is enabled iff debugging is
+     * {@linkplain #isEnabled() enabled}.
+     * <p>
+     * A disabled tracker has virtually no overhead.
+     */
+    public static DebugMemUseTracker memUseTracker(CharSequence name) {
+        if (!ENABLED) {
+            return VOID_MEM_USE_TRACKER;
+        }
+        return createMemUseTracker("%s", name, null);
+    }
+
+    /**
+     * Creates a debug memory use tracker. Invoking this method is equivalent to:
+     *
+     * <pre>
+     * Debug.memUseTracker(format, arg, null)
+     * </pre>
+     *
+     * except that the string formatting only happens if metering is enabled.
+     *
+     * @see #metric(String, Object, Object)
+     */
+    public static DebugMemUseTracker memUseTracker(String format, Object arg) {
+        if (!ENABLED) {
+            return VOID_MEM_USE_TRACKER;
+        }
+        return createMemUseTracker(format, arg, null);
+    }
+
+    /**
+     * Creates a debug memory use tracker. Invoking this method is equivalent to:
+     *
+     * <pre>
+     * Debug.memUseTracker(String.format(format, arg1, arg2))
+     * </pre>
+     *
+     * except that the string formatting only happens if memory use tracking is enabled. In
+     * addition, each argument is subject to the following type based conversion before being passed
+     * as an argument to {@link String#format(String, Object...)}:
+     *
+     * <pre>
+     *     Type          | Conversion
+     * ------------------+-----------------
+     *  java.lang.Class  | arg.getSimpleName()
+     *                   |
+     * </pre>
+     *
+     * @see #memUseTracker(CharSequence)
+     */
+    public static DebugMemUseTracker memUseTracker(String format, Object arg1, Object arg2) {
+        if (!ENABLED) {
+            return VOID_MEM_USE_TRACKER;
+        }
+        return createMemUseTracker(format, arg1, arg2);
+    }
+
+    private static DebugMemUseTracker createMemUseTracker(String format, Object arg1, Object arg2) {
+        String name = formatDebugName(format, arg1, arg2);
+        return new MemUseTrackerImpl(name);
+    }
+
+    /**
      * Creates a {@linkplain DebugMetric metric} that is enabled iff debugging is
      * {@linkplain #isEnabled() enabled} or the system property whose name is formed by adding to
      * {@value #ENABLE_METRIC_PROPERTY_NAME_PREFIX} to {@code name} is
@@ -702,10 +769,10 @@
     }
 
     public static DebugConfig silentConfig() {
-        return fixedConfig(false, false, false, false, Collections.<DebugDumpHandler> emptyList(), System.out);
+        return fixedConfig(false, false, false, false, false, Collections.<DebugDumpHandler> emptyList(), System.out);
     }
 
-    public static DebugConfig fixedConfig(final boolean isLogEnabled, final boolean isDumpEnabled, final boolean isMeterEnabled, final boolean isTimerEnabled,
+    public static DebugConfig fixedConfig(final boolean isLogEnabled, final boolean isDumpEnabled, final boolean isMeterEnabled, final boolean isMemUseTrackingEnabled, final boolean isTimerEnabled,
                     final Collection<DebugDumpHandler> dumpHandlers, final PrintStream output) {
         return new DebugConfig() {
 
@@ -724,6 +791,11 @@
             }
 
             @Override
+            public boolean isMemUseTrackingEnabled() {
+                return isMemUseTrackingEnabled;
+            }
+
+            @Override
             public boolean isDumpEnabled() {
                 return isDumpEnabled;
             }
@@ -783,6 +855,17 @@
         }
     };
 
+    private static final DebugMemUseTracker VOID_MEM_USE_TRACKER = new DebugMemUseTracker() {
+
+        public Closeable start() {
+            return MemUseTrackerImpl.VOID_CLOSEABLE;
+        }
+
+        public long getCurrentValue() {
+            return 0;
+        }
+    };
+
     /**
      * @see #timer(CharSequence)
      */
@@ -875,7 +958,19 @@
 
     public static Object convertFormatArg(Object arg) {
         if (arg instanceof Class) {
-            return ((Class<?>) arg).getSimpleName();
+            Class<?> c = (Class<?>) arg;
+            final String simpleName = c.getSimpleName();
+            Class<?> enclosingClass = c.getEnclosingClass();
+            if (enclosingClass != null) {
+                String prefix = "";
+                while (enclosingClass != null) {
+                    prefix = enclosingClass.getSimpleName() + "_" + prefix;
+                    enclosingClass = enclosingClass.getEnclosingClass();
+                }
+                return prefix + simpleName;
+            } else {
+                return simpleName;
+            }
         }
         return arg;
     }
--- a/graal/com.oracle.graal.debug/src/com/oracle/graal/debug/DebugConfig.java	Fri May 09 20:05:41 2014 +0200
+++ b/graal/com.oracle.graal.debug/src/com/oracle/graal/debug/DebugConfig.java	Fri May 09 20:22:05 2014 +0200
@@ -47,6 +47,14 @@
     boolean isMeterEnabled();
 
     /**
+     * Determines if memory use tracking is enabled in the {@linkplain Debug#currentScope() current
+     * debug scope}.
+     *
+     * @see Debug#memUseTracker(CharSequence)
+     */
+    boolean isMemUseTrackingEnabled();
+
+    /**
      * Determines if dumping is enabled in the {@linkplain Debug#currentScope() current debug scope}
      * .
      *
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.debug/src/com/oracle/graal/debug/DebugMemUseTracker.java	Fri May 09 20:22:05 2014 +0200
@@ -0,0 +1,56 @@
+/*
+ * Copyright (c) 2012, 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.debug;
+
+import com.sun.management.*;
+
+/**
+ * Tracks memory usage within a scope using {@link ThreadMXBean}. This facility should be employed
+ * using the try-with-resources pattern:
+ *
+ * <pre>
+ * try (DebugMemUseTracker.Closeable a = memUseTracker.start()) {
+ *     // the code to measure
+ * }
+ * </pre>
+ */
+public interface DebugMemUseTracker {
+
+    public interface Closeable extends AutoCloseable {
+        void close();
+    }
+
+    /**
+     * Creates a point from which memory usage will be recorded if memory use tracking is
+     * {@linkplain Debug#isMemUseTrackingEnabled() enabled}.
+     *
+     * @return an object that must be closed once the activity has completed to add the memory used
+     *         since this call to the total for this tracker
+     */
+    Closeable start();
+
+    /**
+     * Gets the current value of this tracker.
+     */
+    long getCurrentValue();
+}
--- a/graal/com.oracle.graal.debug/src/com/oracle/graal/debug/DebugTimer.java	Fri May 09 20:05:41 2014 +0200
+++ b/graal/com.oracle.graal.debug/src/com/oracle/graal/debug/DebugTimer.java	Fri May 09 20:22:05 2014 +0200
@@ -29,7 +29,7 @@
 /**
  * A timer for some activity of interest. A timer should be deployed using the try-with-resources
  * pattern:
- * 
+ *
  * <pre>
  * try (TimerCloseable a = timer.start()) {
  *     // the code to time
@@ -41,21 +41,20 @@
     /**
      * Starts this timer if timing is {@linkplain Debug#isTimeEnabled() enabled} or this is an
      * {@linkplain #isConditional() unconditional} timer.
-     * 
+     *
      * @return an object that must be closed once the activity has completed to add the elapsed time
      *         since this call to the total for this timer
      */
     TimerCloseable start();
 
     /**
-     * Sets a flag determining if this timer is only enabled if metering is
-     * {@link Debug#isMeterEnabled() enabled}.
+     * Sets a flag determining if this timer is only enabled if timing is
+     * {@link Debug#isTimeEnabled() enabled}.
      */
     void setConditional(boolean flag);
 
     /**
-     * Determines if this timer is only enabled if metering is {@link Debug#isMeterEnabled()
-     * enabled}.
+     * Determines if this timer is only enabled if timing is {@link Debug#isTimeEnabled() enabled}.
      */
     boolean isConditional();
 
--- a/graal/com.oracle.graal.debug/src/com/oracle/graal/debug/DelegatingDebugConfig.java	Fri May 09 20:05:41 2014 +0200
+++ b/graal/com.oracle.graal.debug/src/com/oracle/graal/debug/DelegatingDebugConfig.java	Fri May 09 20:22:05 2014 +0200
@@ -59,6 +59,10 @@
          */
         METER,
         /**
+         * @see Debug#isMemUseTrackingEnabled()
+         */
+        TRACK_MEM_USE,
+        /**
          * @see Debug#isTimeEnabled()
          */
         TIME,
@@ -125,6 +129,14 @@
         return fs.booleanValue();
     }
 
+    public boolean isMemUseTrackingEnabled() {
+        Boolean fs = featureState.get(Feature.TRACK_MEM_USE);
+        if (fs == null) {
+            return delegate.isMemUseTrackingEnabled();
+        }
+        return fs.booleanValue();
+    }
+
     @Override
     public boolean isDumpEnabled() {
         Boolean fs = featureState.get(Feature.DUMP);
--- a/graal/com.oracle.graal.debug/src/com/oracle/graal/debug/internal/DebugScope.java	Fri May 09 20:05:41 2014 +0200
+++ b/graal/com.oracle.graal.debug/src/com/oracle/graal/debug/internal/DebugScope.java	Fri May 09 20:22:05 2014 +0200
@@ -93,6 +93,7 @@
 
     private boolean meterEnabled;
     private boolean timeEnabled;
+    private boolean memUseTrackingEnabled;
     private boolean dumpEnabled;
     private boolean logEnabled;
 
@@ -169,6 +170,10 @@
         return timeEnabled;
     }
 
+    public boolean isMemUseTrackingEnabled() {
+        return memUseTrackingEnabled;
+    }
+
     public void log(String msg, Object... args) {
         lastUsedIndent.log(msg, args);
     }
@@ -261,6 +266,7 @@
         DebugConfig config = getConfig();
         if (config == null) {
             meterEnabled = false;
+            memUseTrackingEnabled = false;
             timeEnabled = false;
             dumpEnabled = false;
 
@@ -269,6 +275,7 @@
             output = System.out;
         } else {
             meterEnabled = config.isMeterEnabled();
+            memUseTrackingEnabled = config.isMemUseTrackingEnabled();
             timeEnabled = config.isTimeEnabled();
             dumpEnabled = config.isDumpEnabled();
             logEnabled = config.isLogEnabled();
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.debug/src/com/oracle/graal/debug/internal/MemUseTrackerImpl.java	Fri May 09 20:22:05 2014 +0200
@@ -0,0 +1,102 @@
+/*
+ * Copyright (c) 2012, 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.debug.internal;
+
+import java.lang.management.*;
+
+import com.oracle.graal.debug.*;
+import com.sun.management.ThreadMXBean;
+
+public final class MemUseTrackerImpl extends DebugValue implements DebugMemUseTracker {
+
+    private static final ThreadMXBean threadMXBean = (ThreadMXBean) ManagementFactory.getThreadMXBean();
+
+    public static final Closeable VOID_CLOSEABLE = new Closeable() {
+
+        @Override
+        public void close() {
+        }
+    };
+
+    /**
+     * Records the most recent active tracker.
+     */
+    private static final ThreadLocal<CloseableImpl> currentTracker = new ThreadLocal<>();
+
+    private final DebugValue flat;
+
+    public MemUseTrackerImpl(String name) {
+        super(name + "_Accm", false);
+        this.flat = new DebugValue(name + "_Flat", false) {
+
+            @Override
+            public String toString(long value) {
+                return valueToString(value);
+            }
+        };
+    }
+
+    @Override
+    public Closeable start() {
+        if (!isConditional() || Debug.isTimeEnabled()) {
+            CloseableImpl result = new CloseableImpl();
+            currentTracker.set(result);
+            return result;
+        } else {
+            return VOID_CLOSEABLE;
+        }
+    }
+
+    public static String valueToString(long value) {
+        return String.format("%d bytes", value);
+    }
+
+    @Override
+    public String toString(long value) {
+        return valueToString(value);
+    }
+
+    private final class CloseableImpl implements Closeable {
+
+        private final CloseableImpl parent;
+        private final long start;
+        private long nestedAmountToSubtract;
+
+        private CloseableImpl() {
+            this.parent = currentTracker.get();
+            this.start = threadMXBean.getThreadAllocatedBytes(Thread.currentThread().getId());
+        }
+
+        @Override
+        public void close() {
+            long end = threadMXBean.getThreadAllocatedBytes(Thread.currentThread().getId());
+            long allocated = end - start;
+            if (parent != null) {
+                parent.nestedAmountToSubtract += allocated;
+            }
+            currentTracker.set(parent);
+            MemUseTrackerImpl.this.addToCurrentValue(allocated);
+            flat.addToCurrentValue(allocated - nestedAmountToSubtract);
+        }
+    }
+}
--- a/graal/com.oracle.graal.hotspot.test/src/com/oracle/graal/hotspot/test/WriteBarrierVerificationTest.java	Fri May 09 20:05:41 2014 +0200
+++ b/graal/com.oracle.graal.hotspot.test/src/com/oracle/graal/hotspot/test/WriteBarrierVerificationTest.java	Fri May 09 20:22:05 2014 +0200
@@ -692,7 +692,7 @@
             };
 
             DebugConfig debugConfig = DebugScope.getConfig();
-            DebugConfig fixedConfig = Debug.fixedConfig(false, false, false, false, debugConfig.dumpHandlers(), debugConfig.output());
+            DebugConfig fixedConfig = Debug.fixedConfig(false, false, false, false, false, debugConfig.dumpHandlers(), debugConfig.output());
             try (DebugConfigScope s = Debug.setConfig(fixedConfig)) {
                 ReentrantNodeIterator.apply(closure, graph.start(), false);
                 new WriteBarrierVerificationPhase().apply(graph);
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/bridge/VMToCompiler.java	Fri May 09 20:05:41 2014 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/bridge/VMToCompiler.java	Fri May 09 20:22:05 2014 +0200
@@ -30,6 +30,12 @@
  */
 public interface VMToCompiler {
 
+    void startRuntime() throws Throwable;
+
+    void startCompiler(boolean bootstrapEnabled) throws Throwable;
+
+    void bootstrap() throws Throwable;
+
     /**
      * Compiles a method to machine code. This method is called from the VM
      * (VMToCompiler::compileMethod).
@@ -40,9 +46,7 @@
 
     void shutdownCompiler() throws Exception;
 
-    void startCompiler(boolean bootstrapEnabled) throws Throwable;
-
-    void bootstrap() throws Throwable;
+    void shutdownRuntime() throws Throwable;
 
     void compileTheWorld() throws Throwable;
 
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/bridge/VMToCompilerImpl.java	Fri May 09 20:05:41 2014 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/bridge/VMToCompilerImpl.java	Fri May 09 20:22:05 2014 +0200
@@ -136,15 +136,13 @@
 
     private PrintStream log = System.out;
 
-    private long compilerStartTime;
+    private long runtimeStartTime;
 
     public VMToCompilerImpl(HotSpotGraalRuntime runtime) {
         this.runtime = runtime;
     }
 
-    public void startCompiler(boolean bootstrapEnabled) throws Throwable {
-
-        bootstrapRunning = bootstrapEnabled;
+    public void startRuntime() throws Throwable {
 
         if (LogFile.getValue() != null) {
             try {
@@ -192,6 +190,15 @@
             }
         }
 
+        BenchmarkCounters.initialize(runtime.getCompilerToVM());
+
+        runtimeStartTime = System.nanoTime();
+    }
+
+    public void startCompiler(boolean bootstrapEnabled) throws Throwable {
+
+        bootstrapRunning = bootstrapEnabled;
+
         if (runtime.getConfig().useGraalCompilationQueue) {
 
             // Create compilation queue.
@@ -243,9 +250,6 @@
                 t.start();
             }
         }
-        BenchmarkCounters.initialize(runtime.getCompilerToVM());
-
-        compilerStartTime = System.nanoTime();
     }
 
     /**
@@ -274,7 +278,7 @@
             TTY.flush();
         }
 
-        long startTime = System.currentTimeMillis();
+        long boostrapStartTime = System.currentTimeMillis();
 
         boolean firstRun = true;
         do {
@@ -310,12 +314,12 @@
                 // Are we out of time?
                 final int timedBootstrap = TimedBootstrap.getValue();
                 if (timedBootstrap != -1) {
-                    if ((System.currentTimeMillis() - startTime) > timedBootstrap) {
+                    if ((System.currentTimeMillis() - boostrapStartTime) > timedBootstrap) {
                         break;
                     }
                 }
             }
-        } while ((System.currentTimeMillis() - startTime) <= TimedBootstrap.getValue());
+        } while ((System.currentTimeMillis() - boostrapStartTime) <= TimedBootstrap.getValue());
 
         if (ResetDebugValuesAfterBootstrap.getValue()) {
             printDebugValues("bootstrap", true);
@@ -326,7 +330,7 @@
         bootstrapRunning = false;
 
         if (PrintBootstrap.getValue()) {
-            TTY.println(" in %d ms (compiled %d methods)", System.currentTimeMillis() - startTime, compileQueue.getCompletedTaskCount());
+            TTY.println(" in %d ms (compiled %d methods)", System.currentTimeMillis() - boostrapStartTime, compileQueue.getCompletedTaskCount());
         }
 
         System.gc();
@@ -366,11 +370,14 @@
                 });
             }
         }
+    }
+
+    public void shutdownRuntime() throws Exception {
         printDebugValues(ResetDebugValuesAfterBootstrap.getValue() ? "application" : null, false);
         phaseTransition("final");
 
         SnippetCounter.printGroups(TTY.out().out());
-        BenchmarkCounters.shutdown(runtime.getCompilerToVM(), compilerStartTime);
+        BenchmarkCounters.shutdown(runtime.getCompilerToVM(), runtimeStartTime);
     }
 
     private void printDebugValues(String phase, boolean reset) throws GraalInternalError {
--- a/graal/com.oracle.graal.nodes.test/src/com/oracle/graal/nodes/test/IntegerStampTest.java	Fri May 09 20:05:41 2014 +0200
+++ b/graal/com.oracle.graal.nodes.test/src/com/oracle/graal/nodes/test/IntegerStampTest.java	Fri May 09 20:22:05 2014 +0200
@@ -293,4 +293,10 @@
         testZeroExtendShort(-1, 1, 0, 0xFFFF);
         testZeroExtendShort(Short.MIN_VALUE, Short.MAX_VALUE, 0, 0xFFFF);
     }
+
+    @Test
+    public void testIllegalJoin() {
+        assertFalse(new IntegerStamp(32, 0, 0xff00, 0, 0xff00).join(new IntegerStamp(32, 1, 0xff, 0x00, 0xff)).isLegal());
+        assertFalse(new IntegerStamp(32, 0x100, 0xff00, 0, 0xff00).join(new IntegerStamp(32, 0, 0xff, 0x00, 0xff)).isLegal());
+    }
 }
--- a/graal/com.oracle.graal.phases/src/com/oracle/graal/phases/BasePhase.java	Fri May 09 20:05:41 2014 +0200
+++ b/graal/com.oracle.graal.phases/src/com/oracle/graal/phases/BasePhase.java	Fri May 09 20:22:05 2014 +0200
@@ -26,6 +26,7 @@
 
 import com.oracle.graal.debug.*;
 import com.oracle.graal.debug.Debug.Scope;
+import com.oracle.graal.debug.DebugMemUseTracker.Closeable;
 import com.oracle.graal.debug.internal.*;
 import com.oracle.graal.nodes.*;
 
@@ -40,6 +41,7 @@
 
     private final DebugTimer phaseTimer;
     private final DebugMetric phaseMetric;
+    private final DebugMemUseTracker phaseMemUseTracker;
 
     private static final Pattern NAME_PATTERN = Pattern.compile("[A-Z][A-Za-z0-9]+");
 
@@ -51,6 +53,7 @@
     protected BasePhase() {
         phaseTimer = Debug.timer("PhaseTime_%s", getClass());
         phaseMetric = Debug.metric("PhaseCount_%s", getClass());
+        phaseMemUseTracker = Debug.memUseTracker("PhaseMemUse_%s", getClass());
     }
 
     protected BasePhase(String name) {
@@ -58,6 +61,7 @@
         this.name = name;
         phaseTimer = Debug.timer("PhaseTime_%s", getClass());
         phaseMetric = Debug.metric("PhaseCount_%s", getClass());
+        phaseMemUseTracker = Debug.memUseTracker("PhaseMemUse_%s", getClass());
     }
 
     protected CharSequence getDetailedName() {
@@ -69,7 +73,7 @@
     }
 
     public final void apply(final StructuredGraph graph, final C context, final boolean dumpGraph) {
-        try (TimerCloseable a = phaseTimer.start(); Scope s = Debug.scope(getClass(), this)) {
+        try (TimerCloseable a = phaseTimer.start(); Scope s = Debug.scope(getClass(), this); Closeable c = phaseMemUseTracker.start()) {
             BasePhase.this.run(graph, context);
             phaseMetric.increment();
             if (dumpGraph && Debug.isDumpEnabled()) {
--- a/graal/com.oracle.graal.printer/src/com/oracle/graal/printer/DebugEnvironment.java	Fri May 09 20:05:41 2014 +0200
+++ b/graal/com.oracle.graal.printer/src/com/oracle/graal/printer/DebugEnvironment.java	Fri May 09 20:22:05 2014 +0200
@@ -49,7 +49,7 @@
         if (DecompileAfterPhase.getValue() != null) {
             dumpHandlers.add(new DecompilerDebugDumpHandler());
         }
-        GraalDebugConfig debugConfig = new GraalDebugConfig(Log.getValue(), Meter.getValue(), Time.getValue(), Dump.getValue(), MethodFilter.getValue(), log, dumpHandlers);
+        GraalDebugConfig debugConfig = new GraalDebugConfig(Log.getValue(), Meter.getValue(), TrackMemUse.getValue(), Time.getValue(), Dump.getValue(), MethodFilter.getValue(), log, dumpHandlers);
         Debug.setConfig(debugConfig);
         return debugConfig;
     }
--- a/graal/com.oracle.graal.truffle.hotspot/src/com/oracle/graal/truffle/hotspot/HotSpotFrameInstance.java	Fri May 09 20:05:41 2014 +0200
+++ b/graal/com.oracle.graal.truffle.hotspot/src/com/oracle/graal/truffle/hotspot/HotSpotFrameInstance.java	Fri May 09 20:22:05 2014 +0200
@@ -42,8 +42,6 @@
 
     protected abstract int getNotifyIndex();
 
-    protected abstract int getCallTargetIndex();
-
     protected abstract int getFrameIndex();
 
     @SlowPath
@@ -86,15 +84,7 @@
 
     public abstract CallTarget getCallTarget();
 
-    public abstract CallTarget getTargetCallTarget();
-
-    public Node getCallNode() {
-        Object receiver = stackFrame.getLocal(getNotifyIndex());
-        if (receiver instanceof DirectCallNode || receiver instanceof IndirectCallNode) {
-            return (Node) receiver;
-        }
-        return null;
-    }
+    public abstract Node getCallNode();
 
     /**
      * This class represents a frame that is taken from the
@@ -111,7 +101,6 @@
             }
         }
         private static final int NOTIFY_INDEX = 0;
-        private static final int CALL_TARGET_INDEX = 1;
         private static final int FRAME_INDEX = 2;
 
         public CallNodeFrame(InspectedFrame stackFrame) {
@@ -124,11 +113,6 @@
         }
 
         @Override
-        protected int getCallTargetIndex() {
-            return CALL_TARGET_INDEX;
-        }
-
-        @Override
         protected int getFrameIndex() {
             return FRAME_INDEX;
         }
@@ -139,8 +123,12 @@
         }
 
         @Override
-        public CallTarget getTargetCallTarget() {
-            return (CallTarget) stackFrame.getLocal(getCallTargetIndex());
+        public Node getCallNode() {
+            Object receiver = stackFrame.getLocal(getNotifyIndex());
+            if (receiver instanceof DirectCallNode || receiver instanceof IndirectCallNode) {
+                return (Node) receiver;
+            }
+            return null;
         }
     }
 
@@ -181,22 +169,17 @@
         }
 
         @Override
-        protected int getCallTargetIndex() {
-            return CALL_TARGET_INDEX;
-        }
-
-        @Override
         protected int getFrameIndex() {
             return FRAME_INDEX;
         }
 
         @Override
         public CallTarget getCallTarget() {
-            return (CallTarget) stackFrame.getLocal(getCallTargetIndex());
+            return (CallTarget) stackFrame.getLocal(CALL_TARGET_INDEX);
         }
 
         @Override
-        public CallTarget getTargetCallTarget() {
+        public Node getCallNode() {
             return null;
         }
     }
--- a/mx/mx_graal.py	Fri May 09 20:05:41 2014 +0200
+++ b/mx/mx_graal.py	Fri May 09 20:22:05 2014 +0200
@@ -26,7 +26,7 @@
 #
 # ----------------------------------------------------------------------------------------------------
 
-import os, sys, shutil, zipfile, tarfile, tempfile, re, time, datetime, platform, subprocess, multiprocessing, StringIO, socket
+import os, stat, errno, sys, shutil, zipfile, tarfile, tempfile, re, time, datetime, platform, subprocess, multiprocessing, StringIO, socket
 from os.path import join, exists, dirname, basename, getmtime
 from argparse import ArgumentParser, RawDescriptionHelpFormatter, REMAINDER
 from outputparser import OutputParser, ValuesMatcher
@@ -150,10 +150,19 @@
 def clean(args):
     """clean the GraalVM source tree"""
     opts = mx.clean(args, parser=ArgumentParser(prog='mx clean'))
+
     if opts.native:
+        def handleRemoveReadonly(func, path, exc):
+            excvalue = exc[1]
+            if mx.get_os() == 'windows' and func in (os.rmdir, os.remove) and excvalue.errno == errno.EACCES:
+                os.chmod(path, stat.S_IRWXU | stat.S_IRWXG | stat.S_IRWXO) # 0777
+                func(path)
+            else:
+                raise
+
         def rmIfExists(name):
             if os.path.isdir(name):
-                shutil.rmtree(name)
+                shutil.rmtree(name, ignore_errors=False, onerror=handleRemoveReadonly)
             elif os.path.isfile(name):
                 os.unlink(name)
 
@@ -959,15 +968,18 @@
         (_, testfile) = tempfile.mkstemp(".testclasses", "graal")
         os.close(_)
     corecp = mx.classpath(['com.oracle.graal.test'])
+
+    if not exists(javaClass) or getmtime(javaClass) < getmtime(javaSource):
+        subprocess.check_call([mx.java().javac, '-cp', corecp, '-d', mxdir, javaSource])
+
     coreArgs = []
     if verbose:
         coreArgs.append('-JUnitVerbose')
     if enable_timing:
         coreArgs.append('-JUnitEnableTiming')
 
+
     def harness(projectscp, vmArgs):
-        if not exists(javaClass) or getmtime(javaClass) < getmtime(javaSource):
-            subprocess.check_call([mx.java().javac, '-cp', projectscp, '-d', mxdir, javaSource])
         if _get_vm() != 'graal':
             prefixArgs = ['-esa', '-ea']
         else:
@@ -1524,7 +1536,7 @@
                     if not mx.library(name, fatalIfMissing=False):
                         mx.log('Skipping ' + groupId + '.' + artifactId + '.jar as ' + name + ' cannot be resolved')
                         return
-        d = mx.Distribution(graalSuite, name=artifactId, path=path, sourcesPath=path, deps=deps, excludedLibs=[])
+        d = mx.Distribution(graalSuite, name=artifactId, path=path, sourcesPath=path, deps=deps, excludedDependencies=[])
         d.make_archive()
         cmd = ['mvn', 'install:install-file', '-DgroupId=' + groupId, '-DartifactId=' + artifactId,
                '-Dversion=1.0-SNAPSHOT', '-Dpackaging=jar', '-Dfile=' + d.path]
@@ -1796,20 +1808,6 @@
     vmArgs, slArgs = _extract_VM_args(args)
     vm(vmArgs + ['-cp', mx.classpath("com.oracle.truffle.sl"), "com.oracle.truffle.sl.SLMain"] + slArgs)
 
-def trufflejar(args=None):
-    """make truffle.jar"""
-
-    # Test with the built classes
-    _unittest(["com.oracle.truffle.api.test", "com.oracle.truffle.api.dsl.test"], ['@Test', '@Parameters'])
-
-    # We use the DSL processor as the starting point for the classpath - this
-    # therefore includes the DSL processor, the DSL and the API.
-    packagejar(mx.classpath("com.oracle.truffle.dsl.processor").split(os.pathsep), "truffle.jar", None, "com.oracle.truffle.dsl.processor.TruffleProcessor")
-
-    # Test with the JAR
-    _unittest(["com.oracle.truffle.api.test", "com.oracle.truffle.api.dsl.test"], ['@Test', '@Parameters'], "truffle.jar:")
-
-
 def isGraalEnabled(vm):
     return vm != 'original' and not vm.endswith('nograal')
 
@@ -2039,8 +2037,7 @@
         'vmfg': [vmfg, '[-options] class [args...]'],
         'deoptalot' : [deoptalot, '[n]'],
         'longtests' : [longtests, ''],
-        'sl' : [sl, '[SL args|@VM options]'],
-        'trufflejar' : [trufflejar, '']
+        'sl' : [sl, '[SL args|@VM options]']
     }
 
     mx.add_argument('--jacoco', help='instruments com.oracle.* classes using JaCoCo', default='off', choices=['off', 'on', 'append'])
--- a/mx/projects	Fri May 09 20:05:41 2014 +0200
+++ b/mx/projects	Fri May 09 20:22:05 2014 +0200
@@ -76,7 +76,18 @@
 com.oracle.graal.hotspot.sparc,\
 com.oracle.graal.hotspot,\
 com.oracle.graal.hotspot.hsail
-distribution@GRAAL@excludeLibs=FINDBUGS
+distribution@GRAAL@exclude=FINDBUGS
+
+distribution@TRUFFLE@path=truffle.jar
+distribution@TRUFFLE@sourcesPath=truffle-sources.jar
+distribution@TRUFFLE@dependencies=\
+com.oracle.truffle.api.dsl
+
+distribution@TRUFFLE-DSL-PROCESSOR@path=truffle-dsl-processor.jar
+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
 
 # graal.api.collections
 project@com.oracle.graal.api.collections@subDir=graal
--- a/mxtool/mx.py	Fri May 09 20:05:41 2014 +0200
+++ b/mxtool/mx.py	Fri May 09 20:22:05 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, excludedLibs):
+    def __init__(self, suite, name, path, sourcesPath, deps, excludedDependencies):
         self.suite = suite
         self.name = name
         self.path = path.replace('/', os.sep)
@@ -70,13 +70,13 @@
         self.sourcesPath = _make_absolute(sourcesPath.replace('/', os.sep), suite.dir) if sourcesPath else None
         self.deps = deps
         self.update_listeners = set()
-        self.excludedLibs = excludedLibs
+        self.excludedDependencies = excludedDependencies
 
     def sorted_deps(self, includeLibs=False):
         try:
-            excl = [library(d) for d in self.excludedLibs]
+            excl = [dependency(d) for d in self.excludedDependencies]
         except SystemExit as e:
-            abort('invalid excluded library for {} distribution: {}'.format(self.name, e))
+            abort('invalid excluded dependency for {} distribution: {}'.format(self.name, e))
         return [d for d in sorted_deps(self.deps, includeLibs=includeLibs) if d not in excl]
 
     def __str__(self):
@@ -748,8 +748,8 @@
             path = attrs.pop('path')
             sourcesPath = attrs.pop('sourcesPath', None)
             deps = pop_list(attrs, 'dependencies')
-            exclLibs = pop_list(attrs, 'excludeLibs')
-            d = Distribution(self, name, path, sourcesPath, deps, exclLibs)
+            exclDeps = pop_list(attrs, 'exclude')
+            d = Distribution(self, name, path, sourcesPath, deps, exclDeps)
             d.__dict__.update(attrs)
             self.dists.append(d)
 
@@ -2719,6 +2719,12 @@
 
     args = parser.parse_args(args)
 
+    def _rmtree(dirPath):
+        path = dirPath
+        if get_os() == 'windows':
+            path = unicode("\\\\?\\" + dirPath)
+        shutil.rmtree(path)
+
     for p in projects_opt_limit_to_suites():
         if p.native:
             if args.native:
@@ -2729,13 +2735,13 @@
                 if genDir != '' and exists(genDir):
                     log('Clearing {0}...'.format(genDir))
                     for f in os.listdir(genDir):
-                        shutil.rmtree(join(genDir, f))
+                        _rmtree(join(genDir, f))
 
 
                 outputDir = p.output_dir()
                 if outputDir != '' and exists(outputDir):
                     log('Removing {0}...'.format(outputDir))
-                    shutil.rmtree(outputDir)
+                    _rmtree(outputDir)
 
             for configName in ['netbeans-config.zip', 'eclipse-config.zip']:
                 config = TimeStampFile(join(p.suite.mxDir, configName))
--- a/src/cpu/sparc/vm/graalCodeInstaller_sparc.cpp	Fri May 09 20:05:41 2014 +0200
+++ b/src/cpu/sparc/vm/graalCodeInstaller_sparc.cpp	Fri May 09 20:22:05 2014 +0200
@@ -22,7 +22,7 @@
  */
 
 #include "graal/graalCodeInstaller.hpp"
-#include "graal/graalCompiler.hpp"
+#include "graal/graalRuntime.hpp"
 #include "graal/graalCompilerToVM.hpp"
 #include "graal/graalJavaAccess.hpp"
 
--- a/src/cpu/x86/vm/graalCodeInstaller_x86.cpp	Fri May 09 20:05:41 2014 +0200
+++ b/src/cpu/x86/vm/graalCodeInstaller_x86.cpp	Fri May 09 20:22:05 2014 +0200
@@ -25,7 +25,6 @@
 #include "compiler/disassembler.hpp"
 #include "runtime/javaCalls.hpp"
 #include "graal/graalEnv.hpp"
-#include "graal/graalCompiler.hpp"
 #include "graal/graalCodeInstaller.hpp"
 #include "graal/graalJavaAccess.hpp"
 #include "graal/graalCompilerToVM.hpp"
--- a/src/gpu/hsail/vm/gpu_hsail.cpp	Fri May 09 20:05:41 2014 +0200
+++ b/src/gpu/hsail/vm/gpu_hsail.cpp	Fri May 09 20:22:05 2014 +0200
@@ -33,7 +33,7 @@
 #include "utilities/globalDefinitions.hpp"
 #include "utilities/ostream.hpp"
 #include "graal/graalEnv.hpp"
-#include "graal/graalCompiler.hpp"
+#include "graal/graalRuntime.hpp"
 #include "graal/graalJavaAccess.hpp"
 #include "hsailKernelArguments.hpp"
 #include "hsailJavaCallArguments.hpp"
--- a/src/gpu/ptx/vm/gpu_ptx.cpp	Fri May 09 20:05:41 2014 +0200
+++ b/src/gpu/ptx/vm/gpu_ptx.cpp	Fri May 09 20:22:05 2014 +0200
@@ -34,7 +34,7 @@
 #include "runtime/interfaceSupport.hpp"
 #include "runtime/vframe.hpp"
 #include "graal/graalEnv.hpp"
-#include "graal/graalCompiler.hpp"
+#include "graal/graalRuntime.hpp"
 
 #define T_BYTE_SIZE        1
 #define T_BOOLEAN_SIZE     4
--- a/src/share/vm/classfile/vmSymbols.hpp	Fri May 09 20:05:41 2014 +0200
+++ b/src/share/vm/classfile/vmSymbols.hpp	Fri May 09 20:22:05 2014 +0200
@@ -360,27 +360,13 @@
   template(com_oracle_graal_api_code_SpeculationLog,                 "com/oracle/graal/api/code/SpeculationLog")                      \
   /* graal.gpu */                                                                                                                     \
   template(com_oracle_graal_gpu_ExternalCompilationResult,           "com/oracle/graal/gpu/ExternalCompilationResult")                \
-  /* graal.truffle */                                                                                                                 \
-  template(com_oracle_graal_truffle_hotspot_HotSpotTruffleRuntime,   "com/oracle/graal/truffle/hotspot/HotSpotTruffleRuntime")        \
-  template(startCompiler_name,                    "startCompiler")                                                                    \
-  template(bootstrap_name,                        "bootstrap")                                                                        \
-  template(compileTheWorld_name,                  "compileTheWorld")                                                                  \
-  template(shutdownCompiler_name,                 "shutdownCompiler")                                                                 \
+  /* graal method and field names */                                                                                                  \
   template(compileMethod_name,                    "compileMethod")                                                                    \
   template(compileMethod_signature,               "(JIJZ)V")                                                                          \
   template(setOption_name,                        "setOption")                                                                        \
   template(setOption_signature,                   "(Ljava/lang/String;)Z")                                                            \
-  template(finalizeOptions_name,                  "finalizeOptions")                                                                  \
   template(getVMToCompiler_name,                  "getVMToCompiler")                                                                  \
   template(getVMToCompiler_signature,             "()Lcom/oracle/graal/hotspot/bridge/VMToCompiler;")                                 \
-  template(runtime_name,                          "runtime")                                                                          \
-  template(runtime_signature,                     "()Lcom/oracle/graal/hotspot/HotSpotGraalRuntime;")                                 \
-  template(makeInstance_name,                     "makeInstance")                                                                     \
-  template(makeInstance_signature,                "()Lcom/oracle/graal/truffle/hotspot/HotSpotTruffleRuntime;")                       \
-  template(initialize_name,                       "initialize")                                                                       \
-  template(forObject_name,                        "forObject")                                                                        \
-  template(callbackInternal_name,                 "callbackInternal")                                                                 \
-  template(callback_signature,                    "(Ljava/lang/Object;)Ljava/lang/Object;")                                           \
                                                                       \
   /* common method and field names */                                                             \
   template(object_initializer_name,                   "<init>")                                   \
--- a/src/share/vm/graal/graalCodeInstaller.cpp	Fri May 09 20:05:41 2014 +0200
+++ b/src/share/vm/graal/graalCodeInstaller.cpp	Fri May 09 20:22:05 2014 +0200
@@ -202,7 +202,7 @@
     return new LocationValue(Location::new_stk_loc(Location::invalid, 0));
   }
 
-  BasicType type = GraalCompiler::kindToBasicType(Kind::typeChar(Value::kind(value)));
+  BasicType type = GraalRuntime::kindToBasicType(Kind::typeChar(Value::kind(value)));
   Location::Type locationType = Location::normal;
   if (type == T_OBJECT || type == T_ARRAY) locationType = Location::oop;
 
@@ -382,7 +382,7 @@
 
 // constructor used to create a method
 GraalEnv::CodeInstallResult CodeInstaller::install(Handle& compiled_code, CodeBlob*& cb, Handle installed_code, Handle speculation_log) {
-  BufferBlob* buffer_blob = GraalCompiler::initialize_buffer_blob();
+  BufferBlob* buffer_blob = GraalRuntime::initialize_buffer_blob();
   if (buffer_blob == NULL) {
     return GraalEnv::cache_full;
   }
--- a/src/share/vm/graal/graalCompiler.cpp	Fri May 09 20:05:41 2014 +0200
+++ b/src/share/vm/graal/graalCompiler.cpp	Fri May 09 20:22:05 2014 +0200
@@ -25,39 +25,35 @@
 #include "memory/oopFactory.hpp"
 #include "runtime/javaCalls.hpp"
 #include "graal/graalCompiler.hpp"
-#include "graal/graalJavaAccess.hpp"
 #include "graal/graalVMToCompiler.hpp"
-#include "graal/graalCompilerToVM.hpp"
 #include "graal/graalEnv.hpp"
 #include "graal/graalRuntime.hpp"
-#include "runtime/arguments.hpp"
 #include "runtime/compilationPolicy.hpp"
 #include "runtime/globals_extension.hpp"
 
 GraalCompiler* GraalCompiler::_instance = NULL;
 
 GraalCompiler::GraalCompiler() : AbstractCompiler(graal) {
-  _initialized = false;
+#ifdef COMPILERGRAAL
+  _started = false;
+#endif
   assert(_instance == NULL, "only one instance allowed");
   _instance = this;
 }
 
 // Initialization
 void GraalCompiler::initialize() {
-  if (!should_perform_init()) {
+#ifdef COMPILERGRAAL
+  if (!UseCompiler || !should_perform_init()) {
     return;
   }
 
-  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"));
+  GraalRuntime::initialize();
 
-  BufferBlob* buffer_blob = initialize_buffer_blob();
-#ifdef COMPILERGRAAL
+  BufferBlob* buffer_blob = GraalRuntime::initialize_buffer_blob();
   if (!UseGraalCompilationQueue) {
     // This path is used for initialization both by the native queue and the graal queue
-    // but set_state acquired a lock which might not be safe during JVM_CreateJavaVM, so
+    // but set_state acquires a lock which might not be safe during JVM_CreateJavaVM, so
     // only update the state flag for the native queue.
     if (buffer_blob == NULL) {
       set_state(failed);
@@ -65,144 +61,61 @@
       set_state(initialized);
     }
   }
-#endif
-
-  ThreadToNativeFromVM trans(JavaThread::current());
-  JavaThread* THREAD = JavaThread::current();
-  TRACE_graal_1("GraalCompiler::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");
-  }
-
-  graal_compute_offsets();
-
-  // Ensure _non_oop_bits is initialized
-  Universe::non_oop_word();
 
   {
-    GRAAL_VM_ENTRY_MARK;
     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);
 
-    if (UseCompiler) {
-      _external_deopt_i2c_entry = create_external_deopt_i2c();
-#ifdef COMPILERGRAAL
-      bool bootstrap = UseGraalCompilationQueue && (FLAG_IS_DEFAULT(BootstrapGraal) ? !TieredCompilation : BootstrapGraal);
-#else
-      bool bootstrap = false;
+    bool bootstrap = UseGraalCompilationQueue && (FLAG_IS_DEFAULT(BootstrapGraal) ? !TieredCompilation : BootstrapGraal);
+    VMToCompiler::startCompiler(bootstrap);
+    _started = true;
+    CompilationPolicy::completed_vm_startup();
+    if (bootstrap) {
+      // Avoid -Xcomp and -Xbatch problems by turning on interpreter and background compilation for bootstrapping.
+      FlagSetting a(UseInterpreter, true);
+      FlagSetting b(BackgroundCompilation, true);
+#ifndef PRODUCT
+      // Turn off CompileTheWorld during bootstrap so that a counter overflow event
+      // triggers further compilation (see NonTieredCompPolicy::event()) hence
+      // allowing a complete bootstrap
+      FlagSetting c(CompileTheWorld, false);
 #endif
-      VMToCompiler::startCompiler(bootstrap);
-      _initialized = true;
-      CompilationPolicy::completed_vm_startup();
-      if (bootstrap) {
-        // Avoid -Xcomp and -Xbatch problems by turning on interpreter and background compilation for bootstrapping.
-        FlagSetting a(UseInterpreter, true);
-        FlagSetting b(BackgroundCompilation, true);
-#ifndef PRODUCT
-        // Turn off CompileTheWorld during bootstrap so that a counter overflow event
-        // triggers further compilation (see NonTieredCompPolicy::event()) hence
-        // allowing a complete bootstrap
-        FlagSetting c(CompileTheWorld, false);
-#endif
-        VMToCompiler::bootstrap();
-      }
+      VMToCompiler::bootstrap();
+    }
 
 #ifndef PRODUCT
-      if (CompileTheWorld) {
-        // We turn off CompileTheWorld so that Graal can
-        // be compiled by C1/C2 when Graal does a CTW.
-        CompileTheWorld = false;
-        VMToCompiler::compileTheWorld();
-      }
+    if (CompileTheWorld) {
+      VMToCompiler::compileTheWorld();
+    }
 #endif
-    }
   }
+#endif // COMPILERGRAAL
 }
 
-address GraalCompiler::create_external_deopt_i2c() {
-  ResourceMark rm;
-  BufferBlob* buffer = BufferBlob::create("externalDeopt", 1*K);
-  CodeBuffer cb(buffer);
-  short buffer_locs[20];
-  cb.insts()->initialize_shared_locs((relocInfo*)buffer_locs, sizeof(buffer_locs)/sizeof(relocInfo));
-  MacroAssembler masm(&cb);
-
-  int total_args_passed = 5;
-
-  BasicType* sig_bt = NEW_RESOURCE_ARRAY(BasicType, total_args_passed);
-  VMRegPair* regs   = NEW_RESOURCE_ARRAY(VMRegPair, total_args_passed);
-  int i = 0;
-  sig_bt[i++] = T_INT;
-  sig_bt[i++] = T_LONG;
-  sig_bt[i++] = T_VOID; // long stakes 2 slots
-  sig_bt[i++] = T_INT;
-  sig_bt[i++] = T_OBJECT;
-
-  int comp_args_on_stack = SharedRuntime::java_calling_convention(sig_bt, regs, total_args_passed, false);
-
-  SharedRuntime::gen_i2c_adapter(&masm, total_args_passed, comp_args_on_stack, sig_bt, regs);
-  masm.flush();
-
-  return AdapterBlob::create(&cb)->content_begin();
-}
-
-
-BufferBlob* GraalCompiler::initialize_buffer_blob() {
-  JavaThread* THREAD = JavaThread::current();
-  BufferBlob* buffer_blob = THREAD->get_buffer_blob();
-  if (buffer_blob == NULL) {
-    buffer_blob = BufferBlob::create("Graal thread-local CodeBuffer", GraalNMethodSizeLimit);
-    if (buffer_blob != NULL) {
-      THREAD->set_buffer_blob(buffer_blob);
-    }
-  }
-  return buffer_blob;
-}
-
+#ifdef COMPILERGRAAL
 void GraalCompiler::compile_method(methodHandle method, int entry_bci, CompileTask* task, jboolean blocking) {
   GRAAL_EXCEPTION_CONTEXT
-  if (!_initialized) {
+  if (!_started) {
     CompilationPolicy::policy()->delay_compilation(method());
     return;
   }
 
-  assert(_initialized, "must already be initialized");
+  assert(_started, "must already be started");
   ResourceMark rm;
   thread->set_is_graal_compiling(true);
   VMToCompiler::compileMethod(method(), entry_bci, (jlong) (address) task, blocking);
   thread->set_is_graal_compiling(false);
 }
 
+
 // Compilation entry point for methods
 void GraalCompiler::compile_method(ciEnv* env, ciMethod* target, int entry_bci) {
   ShouldNotReachHere();
 }
 
-void GraalCompiler::exit() {
-  if (_initialized) {
+void GraalCompiler::shutdown() {
+  if (_started) {
     VMToCompiler::shutdownCompiler();
+    _started = false;
   }
 }
 
@@ -211,22 +124,4 @@
   TRACE_graal_1("GraalCompiler::print_timers");
 }
 
-BasicType GraalCompiler::kindToBasicType(jchar ch) {
-  switch(ch) {
-    case 'z': return T_BOOLEAN;
-    case 'b': return T_BYTE;
-    case 's': return T_SHORT;
-    case 'c': return T_CHAR;
-    case 'i': return T_INT;
-    case 'f': return T_FLOAT;
-    case 'j': return T_LONG;
-    case 'd': return T_DOUBLE;
-    case 'a': return T_OBJECT;
-    case 'r': return T_ADDRESS;
-    case '-': return T_ILLEGAL;
-    default:
-      fatal(err_msg("unexpected Kind: %c", ch));
-      break;
-  }
-  return T_ILLEGAL;
-}
+#endif // COMPILERGRAAL
--- a/src/share/vm/graal/graalCompiler.hpp	Fri May 09 20:05:41 2014 +0200
+++ b/src/share/vm/graal/graalCompiler.hpp	Fri May 09 20:22:05 2014 +0200
@@ -26,23 +26,23 @@
 
 #include "compiler/abstractCompiler.hpp"
 
-#define LEAF_GRAPH_ARRAY_SIZE (8192)
-
 class GraalCompiler : public AbstractCompiler {
 
 private:
 
-  bool                  _initialized;
+#ifdef COMPILERGRAAL
+  // Set to true once VMToCompiler.startCompiler() returns
+  bool _started;
+#endif
 
   static GraalCompiler* _instance;
-  address               _external_deopt_i2c_entry;
+ 
 public:
 
   GraalCompiler();
 
   static GraalCompiler* instance() { return _instance; }
 
-
   virtual const char* name() { return "Graal"; }
 
   virtual bool supports_native()                 { return true; }
@@ -57,6 +57,7 @@
   // Initialization
   virtual void initialize();
 
+#ifdef COMPILERGRAAL
   // Compilation entry point for methods
   virtual void compile_method(ciEnv* env, ciMethod* target, int entry_bci);
 
@@ -65,31 +66,8 @@
   // Print compilation timers and statistics
   virtual void print_timers();
 
-  void exit();
-
-  address get_external_deopt_i2c_entry() {return _external_deopt_i2c_entry;}
-
-  static BasicType kindToBasicType(jchar ch);
-
-  static BufferBlob* initialize_buffer_blob();
-
-  static address create_external_deopt_i2c();
+  void shutdown();
+#endif
 };
 
-// Tracing macros
-
-#define IF_TRACE_graal_1 if (!(TraceGraal >= 1)) ; else
-#define IF_TRACE_graal_2 if (!(TraceGraal >= 2)) ; else
-#define IF_TRACE_graal_3 if (!(TraceGraal >= 3)) ; else
-#define IF_TRACE_graal_4 if (!(TraceGraal >= 4)) ; else
-#define IF_TRACE_graal_5 if (!(TraceGraal >= 5)) ; else
-
-// using commas and else to keep one-instruction semantics
-
-#define TRACE_graal_1 if (!(TraceGraal >= 1 && (tty->print("TraceGraal-1: "), true))) ; else tty->print_cr
-#define TRACE_graal_2 if (!(TraceGraal >= 2 && (tty->print("   TraceGraal-2: "), true))) ; else tty->print_cr
-#define TRACE_graal_3 if (!(TraceGraal >= 3 && (tty->print("      TraceGraal-3: "), true))) ; else tty->print_cr
-#define TRACE_graal_4 if (!(TraceGraal >= 4 && (tty->print("         TraceGraal-4: "), true))) ; else tty->print_cr
-#define TRACE_graal_5 if (!(TraceGraal >= 5 && (tty->print("            TraceGraal-5: "), true))) ; else tty->print_cr
-
 #endif // SHARE_VM_GRAAL_GRAAL_COMPILER_HPP
--- a/src/share/vm/graal/graalRuntime.cpp	Fri May 09 20:05:41 2014 +0200
+++ b/src/share/vm/graal/graalRuntime.cpp	Fri May 09 20:22:05 2014 +0200
@@ -25,13 +25,156 @@
 #include "asm/codeBuffer.hpp"
 #include "graal/graalRuntime.hpp"
 #include "graal/graalVMToCompiler.hpp"
+#include "graal/graalCompilerToVM.hpp"
+#include "graal/graalJavaAccess.hpp"
+#include "graal/graalEnv.hpp"
 #include "memory/oopFactory.hpp"
 #include "prims/jvm.h"
 #include "runtime/biasedLocking.hpp"
 #include "runtime/interfaceSupport.hpp"
+#include "runtime/arguments.hpp"
 #include "runtime/reflection.hpp"
 #include "utilities/debug.hpp"
 
+address GraalRuntime::_external_deopt_i2c_entry = NULL;
+volatile int GraalRuntime::_state = uninitialized;
+
+void GraalRuntime::initialize() {
+  {
+    MutexLocker locker(GraalInitialization_lock);
+    if (_state == uninitialized) {
+      _state = initializing;
+    } else {
+      while (_state == initializing) {
+        GraalInitialization_lock->wait();
+      }
+      return;
+    }
+  }
+
+  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"));
+
+  ThreadToNativeFromVM trans(JavaThread::current());
+  JavaThread* THREAD = JavaThread::current();
+  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");
+  }
+
+  graal_compute_offsets();
+
+  // Ensure _non_oop_bits is initialized
+  Universe::non_oop_word();
+
+  {
+    GRAAL_VM_ENTRY_MARK;
+    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);
+
+    _external_deopt_i2c_entry = create_external_deopt_i2c();
+
+    VMToCompiler::startRuntime();
+
+    {
+      MutexLocker locker(GraalInitialization_lock);
+      _state = initialized;
+    }
+
+#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
+  }
+}
+
+BufferBlob* GraalRuntime::initialize_buffer_blob() {
+  JavaThread* THREAD = JavaThread::current();
+  BufferBlob* buffer_blob = THREAD->get_buffer_blob();
+  if (buffer_blob == NULL) {
+    buffer_blob = BufferBlob::create("Graal thread-local CodeBuffer", GraalNMethodSizeLimit);
+    if (buffer_blob != NULL) {
+      THREAD->set_buffer_blob(buffer_blob);
+    }
+  }
+  return buffer_blob;
+}
+
+address GraalRuntime::create_external_deopt_i2c() {
+  ResourceMark rm;
+  BufferBlob* buffer = BufferBlob::create("externalDeopt", 1*K);
+  CodeBuffer cb(buffer);
+  short buffer_locs[20];
+  cb.insts()->initialize_shared_locs((relocInfo*)buffer_locs, sizeof(buffer_locs)/sizeof(relocInfo));
+  MacroAssembler masm(&cb);
+
+  int total_args_passed = 5;
+
+  BasicType* sig_bt = NEW_RESOURCE_ARRAY(BasicType, total_args_passed);
+  VMRegPair* regs   = NEW_RESOURCE_ARRAY(VMRegPair, total_args_passed);
+  int i = 0;
+  sig_bt[i++] = T_INT;
+  sig_bt[i++] = T_LONG;
+  sig_bt[i++] = T_VOID; // long stakes 2 slots
+  sig_bt[i++] = T_INT;
+  sig_bt[i++] = T_OBJECT;
+
+  int comp_args_on_stack = SharedRuntime::java_calling_convention(sig_bt, regs, total_args_passed, false);
+
+  SharedRuntime::gen_i2c_adapter(&masm, total_args_passed, comp_args_on_stack, sig_bt, regs);
+  masm.flush();
+
+  return AdapterBlob::create(&cb)->content_begin();
+}
+
+BasicType GraalRuntime::kindToBasicType(jchar ch) {
+  switch(ch) {
+    case 'z': return T_BOOLEAN;
+    case 'b': return T_BYTE;
+    case 's': return T_SHORT;
+    case 'c': return T_CHAR;
+    case 'i': return T_INT;
+    case 'f': return T_FLOAT;
+    case 'j': return T_LONG;
+    case 'd': return T_DOUBLE;
+    case 'a': return T_OBJECT;
+    case 'r': return T_ADDRESS;
+    case '-': return T_ILLEGAL;
+    default:
+      fatal(err_msg("unexpected Kind: %c", ch));
+      break;
+  }
+  return T_ILLEGAL;
+}
+
 // Simple helper to see if the caller of a runtime stub which
 // entered the VM has been deoptimized
 
@@ -548,10 +691,12 @@
 
 // JVM_InitializeGraalRuntime
 JVM_ENTRY(jobject, JVM_InitializeGraalRuntime(JNIEnv *env, jclass graalclass))
-  return VMToCompiler::graalRuntimePermObject();
+  GraalRuntime::initialize();
+  return VMToCompiler::get_HotSpotGraalRuntime_jobject();
 JVM_END
 
 // JVM_InitializeTruffleRuntime
 JVM_ENTRY(jobject, JVM_InitializeTruffleRuntime(JNIEnv *env, jclass graalclass))
-  return JNIHandles::make_local(VMToCompiler::truffleRuntime()());
+  GraalRuntime::initialize();
+  return JNIHandles::make_local(VMToCompiler::create_HotSpotTruffleRuntime()());
 JVM_END
--- a/src/share/vm/graal/graalRuntime.hpp	Fri May 09 20:05:41 2014 +0200
+++ b/src/share/vm/graal/graalRuntime.hpp	Fri May 09 20:22:05 2014 +0200
@@ -28,8 +28,24 @@
 #include "memory/allocation.hpp"
 #include "runtime/deoptimization.hpp"
 
-class GraalRuntime: public AllStatic {
+class GraalRuntime: public CHeapObj<mtCompiler> {
+ private:
+
+  static address   _external_deopt_i2c_entry;
+
+  enum { uninitialized, initializing, initialized };
+  static volatile int _state;
+
  public:
+
+  static /*synchronized*/ void initialize();
+  static BufferBlob* initialize_buffer_blob();
+  static BasicType kindToBasicType(jchar ch);
+  static address create_external_deopt_i2c();
+  static address get_external_deopt_i2c_entry() {return _external_deopt_i2c_entry;}
+
+  // The following routines are all called from compiled Graal code
+
   static void new_instance(JavaThread* thread, Klass* klass);
   static void new_array(JavaThread* thread, Klass* klass, jint length);
   static void new_multi_array(JavaThread* thread, Klass* klass, int rank, jint* dims);
@@ -60,4 +76,20 @@
   static void new_store_pre_barrier(JavaThread* thread);
 };
 
+// Tracing macros
+
+#define IF_TRACE_graal_1 if (!(TraceGraal >= 1)) ; else
+#define IF_TRACE_graal_2 if (!(TraceGraal >= 2)) ; else
+#define IF_TRACE_graal_3 if (!(TraceGraal >= 3)) ; else
+#define IF_TRACE_graal_4 if (!(TraceGraal >= 4)) ; else
+#define IF_TRACE_graal_5 if (!(TraceGraal >= 5)) ; else
+
+// using commas and else to keep one-instruction semantics
+
+#define TRACE_graal_1 if (!(TraceGraal >= 1 && (tty->print("TraceGraal-1: "), true))) ; else tty->print_cr
+#define TRACE_graal_2 if (!(TraceGraal >= 2 && (tty->print("   TraceGraal-2: "), true))) ; else tty->print_cr
+#define TRACE_graal_3 if (!(TraceGraal >= 3 && (tty->print("      TraceGraal-3: "), true))) ; else tty->print_cr
+#define TRACE_graal_4 if (!(TraceGraal >= 4 && (tty->print("         TraceGraal-4: "), true))) ; else tty->print_cr
+#define TRACE_graal_5 if (!(TraceGraal >= 5 && (tty->print("            TraceGraal-5: "), true))) ; else tty->print_cr
+
 #endif // SHARE_VM_GRAAL_GRAAL_RUNTIME_HPP
--- a/src/share/vm/graal/graalVMToCompiler.cpp	Fri May 09 20:05:41 2014 +0200
+++ b/src/share/vm/graal/graalVMToCompiler.cpp	Fri May 09 20:22:05 2014 +0200
@@ -26,10 +26,10 @@
 #include "graal/graalVMToCompiler.hpp"
 #include "runtime/gpu.hpp"
 
-// this is a *global* handle
-jobject VMToCompiler::_graalRuntimePermObject = NULL;
-jobject VMToCompiler::_vmToCompilerPermObject = NULL;
-Klass* VMToCompiler::_vmToCompilerPermKlass = NULL;
+// these are *global* handles
+jobject VMToCompiler::_HotSpotGraalRuntime_instance = NULL;
+jobject VMToCompiler::_VMToCompiler_instance = NULL;
+Klass* VMToCompiler::_VMToCompiler_klass = NULL;
 
 static Klass* loadClass(Symbol* name) {
   Klass* klass = SystemDictionary::resolve_or_null(name, SystemDictionary::java_system_loader(), Handle(), Thread::current());
@@ -40,135 +40,184 @@
   return klass;
 }
 
-KlassHandle VMToCompiler::vmToCompilerKlass() {
-  if (_vmToCompilerPermKlass == NULL) {
-    Klass* result = loadClass(vmSymbols::com_oracle_graal_hotspot_bridge_VMToCompiler());
-    _vmToCompilerPermKlass = result;
+KlassHandle VMToCompiler::VMToCompiler_klass() {
+  if (_VMToCompiler_klass == NULL) {
+    TempNewSymbol VMToCompiler = SymbolTable::new_symbol("com/oracle/graal/hotspot/bridge/VMToCompiler", Thread::current());
+    Klass* result = loadClass(VMToCompiler);
+    _VMToCompiler_klass = result;
   }
-  return _vmToCompilerPermKlass;
+  return _VMToCompiler_klass;
 }
 
-Handle VMToCompiler::truffleRuntime() {
-  Symbol* name = vmSymbols::com_oracle_graal_truffle_hotspot_HotSpotTruffleRuntime();
+Handle VMToCompiler::create_HotSpotTruffleRuntime() {
+  Thread* THREAD = Thread::current();
+  TempNewSymbol name = SymbolTable::new_symbol("com/oracle/graal/truffle/hotspot/HotSpotTruffleRuntime", THREAD);
   KlassHandle klass = loadClass(name);
 
+  TempNewSymbol makeInstance = SymbolTable::new_symbol("makeInstance", THREAD);
+  TempNewSymbol sig = SymbolTable::new_symbol("()Lcom/oracle/graal/truffle/hotspot/HotSpotTruffleRuntime;", THREAD);
   JavaValue result(T_OBJECT);
-  JavaCalls::call_static(&result, klass, vmSymbols::makeInstance_name(), vmSymbols::makeInstance_signature(), Thread::current());
+  JavaCalls::call_static(&result, klass, makeInstance, sig, THREAD);
   check_pending_exception("Couldn't initialize HotSpotTruffleRuntime");
   return Handle((oop) result.get_jobject());
 }
 
-Handle VMToCompiler::graalRuntime() {
-  if (JNIHandles::resolve(_graalRuntimePermObject) == NULL) {
-    KlassHandle klass = loadClass(vmSymbols::com_oracle_graal_hotspot_HotSpotGraalRuntime());
+Handle VMToCompiler::get_HotSpotGraalRuntime() {
+  if (JNIHandles::resolve(_HotSpotGraalRuntime_instance) == NULL) {
+    Thread* THREAD = Thread::current();
+    TempNewSymbol name = SymbolTable::new_symbol("com/oracle/graal/hotspot/HotSpotGraalRuntime", THREAD);
+    KlassHandle klass = loadClass(name);
+    TempNewSymbol runtime = SymbolTable::new_symbol("runtime", THREAD);
+    TempNewSymbol sig = SymbolTable::new_symbol("()Lcom/oracle/graal/hotspot/HotSpotGraalRuntime;", THREAD);
     JavaValue result(T_OBJECT);
-    JavaCalls::call_static(&result, klass, vmSymbols::runtime_name(), vmSymbols::runtime_signature(), Thread::current());
+    JavaCalls::call_static(&result, klass, runtime, sig, THREAD);
     check_pending_exception("Couldn't initialize HotSpotGraalRuntime");
-    _graalRuntimePermObject = JNIHandles::make_global((oop) result.get_jobject());
+    _HotSpotGraalRuntime_instance = JNIHandles::make_global((oop) result.get_jobject());
   }
-  return Handle(JNIHandles::resolve_non_null(_graalRuntimePermObject));
+  return Handle(JNIHandles::resolve_non_null(_HotSpotGraalRuntime_instance));
 }
 
-Handle VMToCompiler::instance() {
-  if (JNIHandles::resolve(_vmToCompilerPermObject) == NULL) {
-    KlassHandle compilerKlass = loadClass(vmSymbols::com_oracle_graal_hotspot_HotSpotGraalRuntime());
-
+Handle VMToCompiler::VMToCompiler_instance() {
+  if (JNIHandles::resolve(_VMToCompiler_instance) == NULL) {
+    Thread* THREAD = Thread::current();
+    TempNewSymbol name = SymbolTable::new_symbol("com/oracle/graal/hotspot/HotSpotGraalRuntime", THREAD);
+    KlassHandle klass = loadClass(name);
+    TempNewSymbol getVMToCompiler = SymbolTable::new_symbol("getVMToCompiler", THREAD);
+    TempNewSymbol sig = SymbolTable::new_symbol("()Lcom/oracle/graal/hotspot/bridge/VMToCompiler;", THREAD);
     JavaValue result(T_OBJECT);
     JavaCallArguments args;
-    args.set_receiver(graalRuntime());
-    JavaCalls::call_virtual(&result, compilerKlass, vmSymbols::getVMToCompiler_name(), vmSymbols::getVMToCompiler_signature(), &args, Thread::current());
+    args.set_receiver(get_HotSpotGraalRuntime());
+    JavaCalls::call_virtual(&result, klass, getVMToCompiler, sig, &args, THREAD);
     check_pending_exception("Couldn't get VMToCompiler");
-    _vmToCompilerPermObject = JNIHandles::make_global((oop) result.get_jobject());
+    _VMToCompiler_instance = JNIHandles::make_global((oop) result.get_jobject());
   }
-  return Handle(JNIHandles::resolve_non_null(_vmToCompilerPermObject));
+  return Handle(JNIHandles::resolve_non_null(_VMToCompiler_instance));
 }
 
 void VMToCompiler::initOptions() {
-  KlassHandle optionsKlass = loadClass(vmSymbols::com_oracle_graal_hotspot_HotSpotOptions());
   Thread* THREAD = Thread::current();
+  TempNewSymbol name = SymbolTable::new_symbol("com/oracle/graal/hotspot/HotSpotOptions", THREAD);
+  KlassHandle optionsKlass = loadClass(name);
   optionsKlass->initialize(THREAD);
   check_pending_exception("Error while calling initOptions");
 }
 
 jboolean VMToCompiler::setOption(Handle option) {
   assert(!option.is_null(), "");
-  KlassHandle optionsKlass = loadClass(vmSymbols::com_oracle_graal_hotspot_HotSpotOptions());
-
   Thread* THREAD = Thread::current();
+  TempNewSymbol name = SymbolTable::new_symbol("com/oracle/graal/hotspot/HotSpotOptions", THREAD);
+  TempNewSymbol setOption = SymbolTable::new_symbol("setOption", THREAD);
+  TempNewSymbol sig = SymbolTable::new_symbol("(Ljava/lang/String;)Z", THREAD);
+  KlassHandle optionsKlass = loadClass(name);
   JavaValue result(T_BOOLEAN);
-  JavaCalls::call_static(&result, optionsKlass, vmSymbols::setOption_name(), vmSymbols::setOption_signature(), option, THREAD);
+  JavaCalls::call_static(&result, optionsKlass, setOption, sig, option, THREAD);
   check_pending_exception("Error while calling setOption");
   return result.get_jboolean();
 }
 
 void VMToCompiler::finalizeOptions(jboolean ciTime) {
-  KlassHandle optionsKlass = loadClass(vmSymbols::com_oracle_graal_hotspot_HotSpotOptions());
   Thread* THREAD = Thread::current();
+  TempNewSymbol name = SymbolTable::new_symbol("com/oracle/graal/hotspot/HotSpotOptions", THREAD);
+  TempNewSymbol finalizeOptions = SymbolTable::new_symbol("finalizeOptions", THREAD);
+  TempNewSymbol sig = SymbolTable::new_symbol("(Ljava/lang/String;)Z", THREAD);
+  KlassHandle optionsKlass = loadClass(name);
   JavaValue result(T_VOID);
   JavaCallArguments args;
   args.push_int(ciTime);
-  JavaCalls::call_static(&result, optionsKlass, vmSymbols::finalizeOptions_name(), vmSymbols::bool_void_signature(), &args, THREAD);
+  JavaCalls::call_static(&result, optionsKlass, finalizeOptions, vmSymbols::bool_void_signature(), &args, THREAD);
   check_pending_exception("Error while calling finalizeOptions");
 }
 
+void VMToCompiler::startRuntime() {
+  JavaThread* THREAD = JavaThread::current();
+  JavaValue result(T_VOID);
+  JavaCallArguments args;
+  TempNewSymbol startRuntime = SymbolTable::new_symbol("startRuntime", THREAD);
+  args.push_oop(VMToCompiler_instance());
+  JavaCalls::call_interface(&result, VMToCompiler_klass(), startRuntime, vmSymbols::void_method_signature(), &args, THREAD);
+  check_pending_exception("Error while calling startRuntime");
+}
+
+#ifdef COMPILERGRAAL
+void VMToCompiler::bootstrap() {
+  JavaThread* THREAD = JavaThread::current();
+  JavaValue result(T_VOID);
+  JavaCallArguments args;
+  TempNewSymbol bootstrap = SymbolTable::new_symbol("bootstrap", THREAD);
+  args.push_oop(VMToCompiler_instance());
+  JavaCalls::call_interface(&result, VMToCompiler_klass(), bootstrap, vmSymbols::void_method_signature(), &args, THREAD);
+  check_pending_exception("Error while calling bootstrap");
+}
+
+void VMToCompiler::startCompiler(jboolean bootstrap_enabled) {
+  JavaThread* THREAD = JavaThread::current();
+  JavaValue result(T_VOID);
+  JavaCallArguments args;
+  TempNewSymbol startCompiler = SymbolTable::new_symbol("startCompiler", THREAD);
+  args.push_oop(VMToCompiler_instance());
+  args.push_int(bootstrap_enabled);
+  JavaCalls::call_interface(&result, VMToCompiler_klass(), startCompiler, vmSymbols::bool_void_signature(), &args, THREAD);
+  check_pending_exception("Error while calling startCompiler");
+}
+
 void VMToCompiler::compileMethod(Method* method, int entry_bci, jlong ctask, jboolean blocking) {
   assert(method != NULL, "just checking");
   Thread* THREAD = Thread::current();
   JavaValue result(T_VOID);
   JavaCallArguments args;
-  args.push_oop(instance());
+  args.push_oop(VMToCompiler_instance());
   args.push_long((jlong) (address) method);
   args.push_int(entry_bci);
   args.push_long(ctask);
   args.push_int(blocking);
-  JavaCalls::call_interface(&result, vmToCompilerKlass(), vmSymbols::compileMethod_name(), vmSymbols::compileMethod_signature(), &args, THREAD);
+  JavaCalls::call_interface(&result, VMToCompiler_klass(), vmSymbols::compileMethod_name(), vmSymbols::compileMethod_signature(), &args, THREAD);
   check_pending_exception("Error while calling compileMethod");
 }
 
 void VMToCompiler::shutdownCompiler() {
-  if (_graalRuntimePermObject != NULL) {
-    HandleMark hm;
+  JavaThread* THREAD = JavaThread::current();
+  HandleMark hm(THREAD);
+  TempNewSymbol shutdownCompiler = SymbolTable::new_symbol("shutdownCompiler", THREAD);
+  JavaValue result(T_VOID);
+  JavaCallArguments args;
+  args.push_oop(VMToCompiler_instance());
+  JavaCalls::call_interface(&result, VMToCompiler_klass(), shutdownCompiler, vmSymbols::void_method_signature(), &args, THREAD);
+  check_pending_exception("Error while calling shutdownCompiler");
+}
+#endif // COMPILERGRAAL
+
+void VMToCompiler::shutdownRuntime() {
+  if (_HotSpotGraalRuntime_instance != NULL) {
     JavaThread* THREAD = JavaThread::current();
+    HandleMark hm(THREAD);
+    TempNewSymbol shutdownRuntime = SymbolTable::new_symbol("shutdownRuntime", THREAD);
     JavaValue result(T_VOID);
     JavaCallArguments args;
-    args.push_oop(instance());
-    JavaCalls::call_interface(&result, vmToCompilerKlass(), vmSymbols::shutdownCompiler_name(), vmSymbols::void_method_signature(), &args, THREAD);
-    check_pending_exception("Error while calling shutdownCompiler");
+    args.push_oop(VMToCompiler_instance());
+    JavaCalls::call_interface(&result, VMToCompiler_klass(), shutdownRuntime, vmSymbols::void_method_signature(), &args, THREAD);
+    check_pending_exception("Error while calling shutdownRuntime");
 
-    JNIHandles::destroy_global(_graalRuntimePermObject);
-    JNIHandles::destroy_global(_vmToCompilerPermObject);
-    //JNIHandles::destroy_global(_vmToCompilerPermKlass);
+    JNIHandles::destroy_global(_HotSpotGraalRuntime_instance);
+    JNIHandles::destroy_global(_VMToCompiler_instance);
 
-    _graalRuntimePermObject = NULL;
-    _vmToCompilerPermObject = NULL;
-    _vmToCompilerPermKlass = NULL;
+    _HotSpotGraalRuntime_instance = NULL;
+    _VMToCompiler_instance = NULL;
+    _VMToCompiler_klass = NULL;
   }
 }
 
-void VMToCompiler::startCompiler(jboolean bootstrap_enabled) {
+#ifndef PRODUCT
+void VMToCompiler::compileTheWorld() {
+  // We turn off CompileTheWorld so that Graal can
+  // be compiled by C1/C2 when Graal does a CTW.
+  CompileTheWorld = false;
+
   JavaThread* THREAD = JavaThread::current();
-  JavaValue result(T_VOID);
-  JavaCallArguments args;
-  args.push_oop(instance());
-  args.push_int(bootstrap_enabled);
-  JavaCalls::call_interface(&result, vmToCompilerKlass(), vmSymbols::startCompiler_name(), vmSymbols::bool_void_signature(), &args, THREAD);
-  check_pending_exception("Error while calling startCompiler");
-}
-
-void VMToCompiler::bootstrap() {
-  JavaThread* THREAD = JavaThread::current();
+  TempNewSymbol compileTheWorld = SymbolTable::new_symbol("compileTheWorld", THREAD);
   JavaValue result(T_VOID);
   JavaCallArguments args;
-  args.push_oop(instance());
-  JavaCalls::call_interface(&result, vmToCompilerKlass(), vmSymbols::bootstrap_name(), vmSymbols::void_method_signature(), &args, THREAD);
-  check_pending_exception("Error while calling bootstrap");
-}
-
-void VMToCompiler::compileTheWorld() {
-  JavaThread* THREAD = JavaThread::current();
-  JavaValue result(T_VOID);
-  JavaCallArguments args;
-  args.push_oop(instance());
-  JavaCalls::call_interface(&result, vmToCompilerKlass(), vmSymbols::compileTheWorld_name(), vmSymbols::void_method_signature(), &args, THREAD);
+  args.push_oop(VMToCompiler_instance());
+  JavaCalls::call_interface(&result, VMToCompiler_klass(), compileTheWorld, vmSymbols::void_method_signature(), &args, THREAD);
   check_pending_exception("Error while calling compileTheWorld");
 }
+#endif
--- a/src/share/vm/graal/graalVMToCompiler.hpp	Fri May 09 20:05:41 2014 +0200
+++ b/src/share/vm/graal/graalVMToCompiler.hpp	Fri May 09 20:22:05 2014 +0200
@@ -35,20 +35,24 @@
 class VMToCompiler : public AllStatic {
 
 private:
-  static jobject _graalRuntimePermObject;
-  static jobject _vmToCompilerPermObject;
-  static Klass* _vmToCompilerPermKlass;
+  static jobject _HotSpotGraalRuntime_instance;
+  static jobject _VMToCompiler_instance;
 
-  static KlassHandle vmToCompilerKlass();
-  static Handle instance();
+  static Klass* _VMToCompiler_klass;
+
+  static KlassHandle VMToCompiler_klass();
+  static Handle VMToCompiler_instance();
 
 public:
-  static Handle graalRuntime();
-  static Handle truffleRuntime();
+  // Gets the singleton HotSpotGraalRuntime instance, initializing it if necessary
+  static Handle get_HotSpotGraalRuntime();
 
-  static jobject graalRuntimePermObject() {
-    graalRuntime();
-    return _graalRuntimePermObject;
+  // Creates a new HotSpotTruffleRuntime object
+  static Handle create_HotSpotTruffleRuntime();
+
+  static jobject get_HotSpotGraalRuntime_jobject() {
+    get_HotSpotGraalRuntime();
+    return _HotSpotGraalRuntime_instance;
   }
 
   // public static boolean HotSpotOptions.<clinit>();
@@ -60,20 +64,30 @@
   // public static void HotSpotOptions.finalizeOptions(boolean ciTime);
   static void finalizeOptions(jboolean ciTime);
 
+  // public abstract void startRuntime();
+  static void startRuntime();
+
+#ifdef COMPILERGRAAL
+  // public abstract void startCompiler(boolean bootstrapEnabled);
+  static void startCompiler(jboolean bootstrap_enabled);
+
+  // public abstract void bootstrap();
+  static void bootstrap();
+
   // public abstract boolean compileMethod(long metaspaceMethod, int entryBCI, long ctask, boolean blocking);
   static void compileMethod(Method* method, int entry_bci, jlong ctask, jboolean blocking);
 
   // public abstract void shutdownCompiler();
   static void shutdownCompiler();
-  
-  // public abstract void startCompiler(boolean bootstrapEnabled);
-  static void startCompiler(jboolean bootstrap_enabled);
+#endif
   
-  // public abstract void bootstrap();
-  static void bootstrap();
-
+  // public abstract void shutdownRuntime();
+  static void shutdownRuntime();
+  
+#ifndef PRODUCT
   // public abstract void compileTheWorld();
   static void compileTheWorld();
+#endif
 };
 
 inline void check_pending_exception(const char* message, bool dump_core = false) {
--- a/src/share/vm/prims/jni.cpp	Fri May 09 20:05:41 2014 +0200
+++ b/src/share/vm/prims/jni.cpp	Fri May 09 20:22:05 2014 +0200
@@ -5173,9 +5173,9 @@
     *vm = (JavaVM *)(&main_vm);
     *(JNIEnv**)penv = thread->jni_environment();
 
-#ifdef GRAAL
-    if (COMPILERGRAAL_PRESENT(UseGraalCompilationQueue) NOT_COMPILERGRAAL(true)) {
-      // GraalCompiler needs to have been created in compileBroker.cpp
+#ifdef COMPILERGRAAL
+    if (UseGraalCompilationQueue) {
+      // GraalCompiler may have been created in compileBroker.cpp
       GraalCompiler* graal_compiler = GraalCompiler::instance();
       if (ForceGraalInitialization && graal_compiler == NULL) {
         graal_compiler = new GraalCompiler();
--- a/src/share/vm/runtime/deoptimization.cpp	Fri May 09 20:05:41 2014 +0200
+++ b/src/share/vm/runtime/deoptimization.cpp	Fri May 09 20:22:05 2014 +0200
@@ -88,7 +88,7 @@
 #endif
 
 #ifdef GRAAL
-#include "graal/graalCompiler.hpp"
+#include "graal/graalRuntime.hpp"
 #include "graal/graalJavaAccess.hpp"
 #endif
 
--- a/src/share/vm/runtime/java.cpp	Fri May 09 20:05:41 2014 +0200
+++ b/src/share/vm/runtime/java.cpp	Fri May 09 20:22:05 2014 +0200
@@ -32,6 +32,7 @@
 #include "interpreter/bytecodeHistogram.hpp"
 #ifdef GRAAL
 #include "graal/graalCompiler.hpp"
+#include "graal/graalVMToCompiler.hpp"
 #endif
 #include "memory/genCollectedHeap.hpp"
 #include "memory/oopFactory.hpp"
@@ -462,10 +463,13 @@
   static jint volatile _before_exit_status = BEFORE_EXIT_NOT_RUN;
 
 #ifdef GRAAL
+#ifdef COMPILERGRAAL
   if (GraalCompiler::instance() != NULL) {
-    GraalCompiler::instance()->exit();
+    GraalCompiler::instance()->shutdown();
   }
 #endif
+  VMToCompiler::shutdownRuntime();
+#endif
 
   // Note: don't use a Mutex to guard the entire before_exit(), as
   // JVMTI post_thread_end_event and post_vm_death_event will run native code.
--- a/src/share/vm/runtime/javaCalls.cpp	Fri May 09 20:05:41 2014 +0200
+++ b/src/share/vm/runtime/javaCalls.cpp	Fri May 09 20:22:05 2014 +0200
@@ -41,7 +41,7 @@
 #include "runtime/stubRoutines.hpp"
 #include "runtime/thread.inline.hpp"
 #include "graal/graalJavaAccess.hpp"
-#include "graal/graalCompiler.hpp"
+#include "graal/graalRuntime.hpp"
 
 // -----------------------------------------------------
 // Implementation of JavaCallWrapper
@@ -413,7 +413,7 @@
       ((JavaThread*) THREAD)->set_graal_alternate_call_target(nm->verified_entry_point());
       oop graalInstalledCode = nm->graal_installed_code();
       if (graalInstalledCode != NULL && graalInstalledCode->is_a(HotSpotNmethod::klass()) && HotSpotNmethod::isExternal(graalInstalledCode)) {
-        entry_point = GraalCompiler::instance()->get_external_deopt_i2c_entry();
+        entry_point = GraalRuntime::get_external_deopt_i2c_entry();
       } else {
       entry_point = method->adapter()->get_i2c_entry();
       }
--- a/src/share/vm/runtime/mutexLocker.cpp	Fri May 09 20:05:41 2014 +0200
+++ b/src/share/vm/runtime/mutexLocker.cpp	Fri May 09 20:22:05 2014 +0200
@@ -133,6 +133,10 @@
 Mutex*   JfrThreadGroups_lock         = NULL;
 #endif
 
+#ifdef GRAAL
+Monitor* GraalInitialization_lock     = NULL;
+#endif
+
 #define MAX_NUM_MUTEX 128
 static Monitor * _mutex_array[MAX_NUM_MUTEX];
 static int _num_mutex;
@@ -281,6 +285,9 @@
   def(JfrStacktrace_lock           , Mutex,   special,     true );
 #endif
 
+#ifdef GRAAL
+  def(GraalInitialization_lock     , Monitor, nonleaf+5,   false);
+#endif
 }
 
 GCMutexLocker::GCMutexLocker(Monitor * mutex) {
--- a/src/share/vm/runtime/mutexLocker.hpp	Fri May 09 20:05:41 2014 +0200
+++ b/src/share/vm/runtime/mutexLocker.hpp	Fri May 09 20:22:05 2014 +0200
@@ -146,6 +146,10 @@
 extern Mutex*   JfrThreadGroups_lock;            // protects JFR access to Thread Groups
 #endif
 
+#ifdef GRAAL
+extern Monitor* GraalInitialization_lock;        // ensures exactly 1 thread initializes Graal
+#endif
+
 // A MutexLocker provides mutual exclusion with respect to a given mutex
 // for the scope which contains the locker.  The lock is an OS lock, not
 // an object lock, and the two do not interoperate.  Do not use Mutex-based