changeset 13810:44bcfc983adb

Merge.
author Christian Humer <christian.humer@gmail.com>
date Wed, 29 Jan 2014 12:19:03 +0100
parents 030e75d4d7dc (current diff) 8cd953e97e2d (diff)
children 641f22b1c6b8
files graal/com.oracle.graal.hotspot.hsail/src/com/oracle/graal/hotspot/hsail/HSAILCompilationResult.java graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/TruffleCompilerImpl.java
diffstat 38 files changed, 534 insertions(+), 378 deletions(-) [+]
line wrap: on
line diff
--- a/graal/com.oracle.graal.asm.ptx/src/com/oracle/graal/asm/ptx/PTXAssembler.java	Tue Jan 28 19:37:26 2014 +0100
+++ b/graal/com.oracle.graal.asm.ptx/src/com/oracle/graal/asm/ptx/PTXAssembler.java	Wed Jan 29 12:19:03 2014 +0100
@@ -397,13 +397,17 @@
     }
 
     // Checkstyle: stop method name check
-    public final void bra(String tgt, int pred) {
+    /*
+     * Emit conditional branch to target 'tgt' guarded by predicate register 'pred' whose state is
+     * tested to be 'predCheck'.
+     */
+    public final void bra(String tgt, int pred, boolean predCheck) {
         assert pred >= 0;
 
         if (tgt.equals("?")) {
             Thread.dumpStack();
         }
-        emitString("@%p" + pred + " " + "bra" + " " + tgt + ";");
+        emitString("@" + (predCheck ? "%p" : "!%p") + pred + " " + "bra" + " " + tgt + ";");
     }
 
     public final void bra(String src) {
--- a/graal/com.oracle.graal.compiler.hsail.test.infra/src/com/oracle/graal/compiler/hsail/test/infra/GraalKernelTester.java	Tue Jan 28 19:37:26 2014 +0100
+++ b/graal/com.oracle.graal.compiler.hsail.test.infra/src/com/oracle/graal/compiler/hsail/test/infra/GraalKernelTester.java	Wed Jan 29 12:19:03 2014 +0100
@@ -27,33 +27,46 @@
  * This class extends KernelTester and provides a base class
  * for which the HSAIL code comes from the Graal compiler.
  */
+import static com.oracle.graal.hotspot.HotSpotGraalRuntime.*;
 import static com.oracle.graal.phases.GraalOptions.*;
 
 import java.io.*;
 import java.lang.reflect.*;
 
+import org.junit.*;
+
 import com.oracle.graal.api.code.*;
+import com.oracle.graal.api.meta.*;
+import com.oracle.graal.compiler.target.*;
 import com.oracle.graal.debug.*;
 import com.oracle.graal.graph.*;
 import com.oracle.graal.hotspot.hsail.*;
 import com.oracle.graal.hotspot.meta.*;
+import com.oracle.graal.hsail.*;
 import com.oracle.graal.options.*;
-
-import com.oracle.graal.phases.GraalOptions;
-import static com.oracle.graal.options.OptionValue.OverrideScope;
+import com.oracle.graal.options.OptionValue.OverrideScope;
+import com.oracle.graal.phases.*;
 
 public abstract class GraalKernelTester extends KernelTester {
 
-    HSAILCompilationResult hsailCompResult;
+    private static HSAILHotSpotBackend getHSAILBackend() {
+        Backend backend = runtime().getBackend(HSAIL.class);
+        Assume.assumeTrue(backend instanceof HSAILHotSpotBackend);
+        return (HSAILHotSpotBackend) backend;
+    }
+
+    ExternalCompilationResult hsailCode;
     private boolean showHsailSource = false;
     private boolean saveInFile = false;
 
     @Override
     public String getCompiledHSAILSource(Method method) {
-        if (hsailCompResult == null) {
-            hsailCompResult = HSAILCompilationResult.getHSAILCompilationResult(method);
+        if (hsailCode == null) {
+            HSAILHotSpotBackend backend = getHSAILBackend();
+            ResolvedJavaMethod javaMethod = backend.getProviders().getMetaAccess().lookupJavaMethod(method);
+            hsailCode = backend.compileKernel(javaMethod, false);
         }
-        String hsailSource = hsailCompResult.getHSAILCode();
+        String hsailSource = hsailCode.getCodeString();
         if (showHsailSource) {
             logger.severe(hsailSource);
         }
@@ -86,8 +99,8 @@
 
     @Override
     protected void dispatchKernelOkra(int range, Object... args) {
-        HSAILCompilationResult hcr = HSAILCompilationResult.getHSAILCompilationResult(testMethod);
-        HotSpotNmethod code = (HotSpotNmethod) hcr.getInstalledCode();
+        HSAILHotSpotBackend backend = getHSAILBackend();
+        HotSpotNmethod code = backend.compileAndInstallKernel(testMethod);
 
         if (code != null) {
             try {
--- a/graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/BasicHSAILTest.java	Tue Jan 28 19:37:26 2014 +0100
+++ b/graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/BasicHSAILTest.java	Wed Jan 29 12:19:03 2014 +0100
@@ -22,14 +22,17 @@
  */
 package com.oracle.graal.compiler.hsail.test;
 
+import java.lang.reflect.*;
+
 import org.junit.*;
 
+import com.oracle.graal.api.code.*;
+import com.oracle.graal.compiler.target.*;
 import com.oracle.graal.compiler.test.*;
 import com.oracle.graal.debug.*;
 import com.oracle.graal.debug.Debug.Scope;
 import com.oracle.graal.hotspot.hsail.*;
 import com.oracle.graal.hsail.*;
-import com.oracle.graal.nodes.*;
 
 /**
  * Test class for small Java methods compiled to HSAIL kernels.
@@ -332,11 +335,18 @@
         out[gid] = val;
     }
 
+    @Override
+    protected HSAILHotSpotBackend getBackend() {
+        Backend backend = super.getBackend();
+        Assume.assumeTrue(backend instanceof HSAILHotSpotBackend);
+        return (HSAILHotSpotBackend) backend;
+    }
+
     private void test(final String snippet) {
         try (Scope s = Debug.scope("HSAILCodeGen")) {
-            StructuredGraph graph = parse(snippet);
-            HSAILCompilationResult compResult = HSAILCompilationResult.getHSAILCompilationResult(graph);
-            Debug.log("HSAIL code generated for %s:%n%s", snippet, compResult.getHSAILCode());
+            Method method = getMethod(snippet);
+            ExternalCompilationResult hsailCode = getBackend().compileKernel(getMetaAccess().lookupJavaMethod(method), false);
+            Debug.log("HSAIL code generated for %s:%n%s", snippet, hsailCode.getCodeString());
         } catch (Throwable e) {
             throw Debug.handle(e);
         }
--- a/graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/StaticMethod16InArraysTest.java	Tue Jan 28 19:37:26 2014 +0100
+++ b/graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/StaticMethod16InArraysTest.java	Wed Jan 29 12:19:03 2014 +0100
@@ -62,6 +62,7 @@
      * there are registers.
      */
     @Test(expected = java.lang.ClassCastException.class)
+    @Ignore("until GPU backends can co-exist")
     public void test() {
         DebugConfig debugConfig = DebugScope.getConfig();
         DebugConfig noInterceptConfig = new DelegatingDebugConfig(debugConfig) {
--- a/graal/com.oracle.graal.compiler.ptx.test/src/com/oracle/graal/compiler/ptx/test/ControlPTXTest.java	Tue Jan 28 19:37:26 2014 +0100
+++ b/graal/com.oracle.graal.compiler.ptx.test/src/com/oracle/graal/compiler/ptx/test/ControlPTXTest.java	Wed Jan 29 12:19:03 2014 +0100
@@ -26,18 +26,26 @@
 
 public class ControlPTXTest extends PTXTest {
 
-    @Ignore("[CUDA] *** Error (status=702): Synchronize kernel")
     @Test
-    public void testControl() {
+    public void testControl1() {
         test("testLoop", 42);
         test("testSwitchDefault1I", 3);
         test("testSwitch1I", 2);
         test("testIfElse1I", 222);
         test("testIfElse2I", 19, 64);
+    }
 
-        test("testIntegerTestBranch2I", 0xff00, 0x00ff);
+    @Test
+    public void testControl2() {
         compileKernel("testStatic");
         compileKernel("testCall");
+    }
+
+    @Ignore("[CUDA] Check for malformed PTX kernel or incorrect PTX compilation options")
+    @Test
+    public void testControl3() {
+        // test("testIntegerTestBranch2I", 0xff00, 0x00ff);
+        compileKernel("testIntegerTestBranch2I");
         compileKernel("testLookupSwitch1I");
     }
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ShortCircuitNodeTest.java	Wed Jan 29 12:19:03 2014 +0100
@@ -0,0 +1,65 @@
+/*
+ * 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.compiler.test;
+
+import org.junit.*;
+
+import com.oracle.graal.compiler.test.ea.EATestBase.TestClassInt;
+
+public class ShortCircuitNodeTest extends GraalCompilerTest {
+
+    @Test
+    public void test1() {
+        // only executeActual, to avoid creating profiling information
+        executeActual(getMethod("test1Snippet"), 1, 2);
+    }
+
+    public static final TestClassInt field = null;
+    public static TestClassInt field2 = null;
+
+    @SuppressWarnings("unused")
+    public static void test1Snippet(int a, int b) {
+        /*
+         * if a ShortCircuitOrNode is created for the check inside test2, then faulty handling of
+         * guards can create a cycle in the graph.
+         */
+        int v;
+        if (a == 1) {
+            if (b != 1) {
+                int i = field.x;
+            }
+            field2 = null;
+            v = 0;
+        } else {
+            v = 1;
+        }
+
+        if (test2(v, b)) {
+            int i = field.x;
+        }
+    }
+
+    public static boolean test2(int a, int b) {
+        return a != 0 || b != 1;
+    }
+}
--- a/graal/com.oracle.graal.hotspot.hsail/src/com/oracle/graal/hotspot/hsail/ForEachToGraal.java	Tue Jan 28 19:37:26 2014 +0100
+++ b/graal/com.oracle.graal.hotspot.hsail/src/com/oracle/graal/hotspot/hsail/ForEachToGraal.java	Wed Jan 29 12:19:03 2014 +0100
@@ -23,10 +23,24 @@
 
 package com.oracle.graal.hotspot.hsail;
 
+import static com.oracle.graal.hotspot.HotSpotGraalRuntime.*;
+
+import java.lang.reflect.*;
+import java.util.*;
+
 import com.oracle.graal.api.code.*;
+import com.oracle.graal.api.meta.*;
 import com.oracle.graal.compiler.hsail.*;
+import com.oracle.graal.compiler.target.*;
 import com.oracle.graal.debug.*;
+import com.oracle.graal.graph.iterators.*;
 import com.oracle.graal.hotspot.meta.*;
+import com.oracle.graal.hsail.*;
+import com.oracle.graal.java.*;
+import com.oracle.graal.nodes.*;
+import com.oracle.graal.nodes.java.*;
+import com.oracle.graal.phases.*;
+import com.oracle.graal.phases.util.*;
 
 /**
  * Implements compile and dispatch of Java code containing lambda constructs. Currently only used by
@@ -34,18 +48,53 @@
  */
 public class ForEachToGraal implements CompileAndDispatch {
 
-    private static HSAILCompilationResult getCompiledLambda(Class consumerClass) {
-        return HSAILCompilationResult.getCompiledLambda(consumerClass);
+    private static HSAILHotSpotBackend getHSAILBackend() {
+        Backend backend = runtime().getBackend(HSAIL.class);
+        return (HSAILHotSpotBackend) backend;
     }
 
-    // Implementations of the CompileAndDispatch interface.
+    /**
+     * Gets a compiled and installed kernel for the lambda called by the {@code accept(int value)}
+     * method in a class implementing {@code java.util.function.IntConsumer}.
+     * 
+     * @param intConsumerClass a class implementing {@code java.util.function.IntConsumer}
+     * @return a {@link HotSpotNmethod} handle to the compiled and installed kernel
+     */
+    private static HotSpotNmethod getCompiledLambda(Class intConsumerClass) {
+        Method acceptMethod = null;
+        for (Method m : intConsumerClass.getMethods()) {
+            if (m.getName().equals("accept") && Arrays.equals(new Class[]{int.class}, m.getParameterTypes())) {
+                assert acceptMethod == null : "found more than one implementation of accept(int) in " + intConsumerClass;
+                acceptMethod = m;
+            }
+        }
+
+        HSAILHotSpotBackend backend = getHSAILBackend();
+        Providers providers = backend.getProviders();
+        StructuredGraph graph = new StructuredGraph(((HotSpotMetaAccessProvider) providers.getMetaAccess()).lookupJavaMethod(acceptMethod));
+        new GraphBuilderPhase.Instance(providers.getMetaAccess(), GraphBuilderConfiguration.getDefault(), OptimisticOptimizations.ALL).apply(graph);
+        NodeIterable<MethodCallTargetNode> calls = graph.getNodes(MethodCallTargetNode.class);
+        assert calls.count() == 1;
+        ResolvedJavaMethod lambdaMethod = calls.first().targetMethod();
+        assert lambdaMethod.getName().startsWith("lambda$");
+        Debug.log("target ... " + lambdaMethod);
+
+        if (lambdaMethod == null) {
+            Debug.log("Did not find call in accept()");
+            return null;
+        }
+
+        ExternalCompilationResult hsailCode = backend.compileKernel(lambdaMethod, true);
+        return backend.installKernel(lambdaMethod, hsailCode);
+    }
+
     @Override
     public Object createKernel(Class<?> consumerClass) {
         try {
             return getCompiledLambda(consumerClass);
         } catch (Throwable e) {
-            // Note: Graal throws Errors. We want to revert to regular Java in these cases.
-            Debug.log("WARNING:Graal compilation failed.");
+            // If Graal compilation throws an exception, we want to revert to regular Java
+            Debug.log("WARNING: Graal compilation failed");
             e.printStackTrace();
             return null;
         }
@@ -53,16 +102,14 @@
 
     @Override
     public boolean dispatchKernel(Object kernel, int jobSize, Object[] args) {
-        // kernel is an HSAILCompilationResult
-        HotSpotNmethod code = (HotSpotNmethod) ((HSAILCompilationResult) kernel).getInstalledCode();
-
+        HotSpotNmethod code = (HotSpotNmethod) kernel;
         if (code != null) {
             try {
                 // No return value from HSAIL kernels
                 code.executeParallel(jobSize, 0, 0, args);
                 return true;
             } catch (InvalidInstalledCodeException iice) {
-                Debug.log("WARNING:Invalid installed code at exec time." + iice);
+                Debug.log("WARNING: Invalid installed code at exec time." + iice);
                 iice.printStackTrace();
                 return false;
             }
--- a/graal/com.oracle.graal.hotspot.hsail/src/com/oracle/graal/hotspot/hsail/HSAILCompilationResult.java	Tue Jan 28 19:37:26 2014 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,182 +0,0 @@
-/*
- * Copyright (c) 2009, 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.hotspot.hsail;
-
-import static com.oracle.graal.compiler.GraalCompiler.*;
-import static com.oracle.graal.hotspot.HotSpotGraalRuntime.*;
-
-import java.lang.reflect.*;
-
-import com.oracle.graal.api.code.*;
-import com.oracle.graal.api.code.CallingConvention.Type;
-import com.oracle.graal.api.meta.*;
-import com.oracle.graal.api.runtime.*;
-import com.oracle.graal.debug.*;
-import com.oracle.graal.graph.*;
-import com.oracle.graal.graph.iterators.*;
-import com.oracle.graal.hotspot.*;
-import com.oracle.graal.hotspot.bridge.*;
-import com.oracle.graal.hotspot.meta.*;
-import com.oracle.graal.hsail.*;
-import com.oracle.graal.java.*;
-import com.oracle.graal.lir.asm.*;
-import com.oracle.graal.nodes.*;
-import com.oracle.graal.nodes.java.*;
-import com.oracle.graal.phases.*;
-import com.oracle.graal.phases.common.*;
-import com.oracle.graal.phases.tiers.*;
-import com.oracle.graal.phases.util.*;
-import com.oracle.graal.runtime.*;
-
-/**
- * Class that represents a HSAIL compilation result. Includes the compiled HSAIL code.
- */
-public class HSAILCompilationResult extends ExternalCompilationResult {
-
-    private static final long serialVersionUID = -4178700465275724625L;
-
-    private static CompilerToGPU toGPU = HotSpotGraalRuntime.runtime().getCompilerToGPU();
-    private static boolean validDevice = toGPU.deviceInit();
-
-    // The installedCode is the executable representation of the kernel in the code cache
-    private InstalledCode installedCode;
-
-    public void setInstalledCode(InstalledCode newCode) {
-        installedCode = newCode;
-    }
-
-    public InstalledCode getInstalledCode() {
-        return installedCode;
-    }
-
-    static final HSAILHotSpotBackend backend;
-    static {
-        // Look for installed HSAIL backend
-        RuntimeProvider runtime = Graal.getRequiredCapability(RuntimeProvider.class);
-        HSAILHotSpotBackend b = (HSAILHotSpotBackend) runtime.getBackend(HSAIL.class);
-        if (b == null) {
-            // Fall back to a new instance
-            b = new HSAILHotSpotBackendFactory().createBackend(runtime(), runtime().getHostBackend());
-            b.completeInitialization();
-        }
-        backend = b;
-    }
-
-    public static HSAILCompilationResult getHSAILCompilationResult(Method meth) {
-        HotSpotMetaAccessProvider metaAccess = backend.getProviders().getMetaAccess();
-        ResolvedJavaMethod javaMethod = metaAccess.lookupJavaMethod(meth);
-        return getHSAILCompilationResult(javaMethod);
-    }
-
-    public static HSAILCompilationResult getHSAILCompilationResult(ResolvedJavaMethod javaMethod) {
-        HotSpotMetaAccessProvider metaAccess = backend.getProviders().getMetaAccess();
-        StructuredGraph graph = new StructuredGraph(javaMethod);
-        new GraphBuilderPhase.Instance(metaAccess, GraphBuilderConfiguration.getEagerDefault(), OptimisticOptimizations.ALL).apply(graph);
-        return getHSAILCompilationResult(graph);
-    }
-
-    public static HSAILCompilationResult getCompiledLambda(Class consumerClass) {
-        /**
-         * Find the accept() method in the IntConsumer, then use Graal API to find the target lambda
-         * that accept will call.
-         */
-        Method[] icMethods = consumerClass.getMethods();
-        Method acceptMethod = null;
-        for (Method m : icMethods) {
-            if (m.getName().equals("accept") && acceptMethod == null) {
-                acceptMethod = m;
-                break;
-            }
-        }
-
-        Providers providers = backend.getProviders();
-        HotSpotMetaAccessProvider metaAccess = (HotSpotMetaAccessProvider) providers.getMetaAccess();
-        ResolvedJavaMethod rm = metaAccess.lookupJavaMethod(acceptMethod);
-        StructuredGraph graph = new StructuredGraph(rm);
-        new GraphBuilderPhase.Instance(providers.getMetaAccess(), GraphBuilderConfiguration.getDefault(), OptimisticOptimizations.ALL).apply(graph);
-        NodeIterable<Node> nin = graph.getNodes();
-        ResolvedJavaMethod lambdaMethod = null;
-        for (Node n : nin) {
-            if (n instanceof MethodCallTargetNode) {
-                lambdaMethod = ((MethodCallTargetNode) n).targetMethod();
-                Debug.log("target ... " + lambdaMethod);
-                break;
-            }
-        }
-        if (lambdaMethod == null) {
-            // Did not find call in Consumer.accept.
-            Debug.log("Should not Reach here, did not find call in accept()");
-            return null;
-        }
-        // Now that we have the target lambda, compile it.
-        HSAILCompilationResult hsailCompResult = HSAILCompilationResult.getHSAILCompilationResult(lambdaMethod);
-        return hsailCompResult;
-    }
-
-    public static HSAILCompilationResult getHSAILCompilationResult(StructuredGraph graph) {
-        Debug.dump(graph, "Graph");
-        Providers providers = backend.getProviders();
-        TargetDescription target = providers.getCodeCache().getTarget();
-        PhaseSuite<HighTierContext> graphBuilderSuite = backend.getSuites().getDefaultGraphBuilderSuite().copy();
-        graphBuilderSuite.appendPhase(new NonNullParametersPhase());
-        CallingConvention cc = CodeUtil.getCallingConvention(providers.getCodeCache(), Type.JavaCallee, graph.method(), false);
-        SuitesProvider suitesProvider = backend.getSuites();
-        try {
-            HSAILCompilationResult compResult = compileGraph(graph, cc, graph.method(), providers, backend, target, null, graphBuilderSuite, OptimisticOptimizations.NONE, getProfilingInfo(graph),
-                            null, suitesProvider.getDefaultSuites(), true, new HSAILCompilationResult(), CompilationResultBuilderFactory.Default);
-            if ((validDevice) && (compResult.getTargetCode() != null)) {
-                long kernel = toGPU.generateKernel(compResult.getTargetCode(), graph.method().getName());
-
-                if (kernel == 0) {
-                    throw new GraalInternalError("Failed to compile kernel.");
-                }
-
-                ((ExternalCompilationResult) compResult).setEntryPoint(kernel);
-                HotSpotResolvedJavaMethod compiledMethod = (HotSpotResolvedJavaMethod) graph.method();
-                InstalledCode installedCode = ((HotSpotCodeCacheProvider) providers.getCodeCache()).addExternalMethod(compiledMethod, compResult);
-                compResult.setInstalledCode(installedCode);
-            }
-            return compResult;
-        } catch (InvalidInstalledCodeException e) {
-            e.printStackTrace();
-            return null;
-        } catch (GraalInternalError e) {
-            String partialCode = backend.getPartialCodeString();
-            if (partialCode != null && !partialCode.equals("")) {
-                Debug.log("-------------------\nPartial Code Generation:\n--------------------");
-                Debug.log(partialCode);
-                Debug.log("-------------------\nEnd of Partial Code Generation\n--------------------");
-            }
-            throw e;
-        }
-    }
-
-    protected HSAILCompilationResult() {
-    }
-
-    public String getHSAILCode() {
-        return new String(getTargetCode(), 0, getTargetCodeSize());
-    }
-
-}
--- a/graal/com.oracle.graal.hotspot.hsail/src/com/oracle/graal/hotspot/hsail/HSAILHotSpotBackend.java	Tue Jan 28 19:37:26 2014 +0100
+++ b/graal/com.oracle.graal.hotspot.hsail/src/com/oracle/graal/hotspot/hsail/HSAILHotSpotBackend.java	Wed Jan 29 12:19:03 2014 +0100
@@ -23,25 +23,34 @@
 package com.oracle.graal.hotspot.hsail;
 
 import static com.oracle.graal.api.code.CallingConvention.Type.*;
+import static com.oracle.graal.api.code.CodeUtil.*;
 import static com.oracle.graal.api.code.ValueUtil.*;
+import static com.oracle.graal.compiler.GraalCompiler.*;
 
 import java.lang.reflect.*;
 import java.util.*;
 
 import com.oracle.graal.api.code.*;
+import com.oracle.graal.api.code.CallingConvention.Type;
 import com.oracle.graal.api.meta.*;
 import com.oracle.graal.asm.*;
 import com.oracle.graal.asm.hsail.*;
 import com.oracle.graal.compiler.gen.*;
 import com.oracle.graal.debug.*;
+import com.oracle.graal.debug.Debug.Scope;
+import com.oracle.graal.graph.*;
 import com.oracle.graal.hotspot.*;
 import com.oracle.graal.hotspot.meta.*;
 import com.oracle.graal.hsail.*;
+import com.oracle.graal.java.*;
 import com.oracle.graal.lir.*;
 import com.oracle.graal.lir.asm.*;
 import com.oracle.graal.lir.hsail.*;
 import com.oracle.graal.nodes.*;
-import com.oracle.graal.nodes.spi.Replacements;
+import com.oracle.graal.nodes.spi.*;
+import com.oracle.graal.phases.*;
+import com.oracle.graal.phases.common.*;
+import com.oracle.graal.phases.tiers.*;
 import com.oracle.graal.replacements.hsail.*;
 
 /**
@@ -85,6 +94,60 @@
     }
 
     /**
+     * Compiles and installs a given method to a GPU binary.
+     */
+    public HotSpotNmethod compileAndInstallKernel(Method method) {
+        ResolvedJavaMethod javaMethod = getProviders().getMetaAccess().lookupJavaMethod(method);
+        return installKernel(javaMethod, compileKernel(javaMethod, true));
+    }
+
+    /**
+     * Compiles a given method to HSAIL code.
+     * 
+     * @param makeBinary specifies whether a GPU binary should also be generated for the HSAIL code.
+     *            If true, the returned value is guaranteed to have a non-zero
+     *            {@linkplain ExternalCompilationResult#getEntryPoint() entry point}.
+     * @return the HSAIL code compiled from {@code method}'s bytecode
+     */
+    public ExternalCompilationResult compileKernel(ResolvedJavaMethod method, boolean makeBinary) {
+        StructuredGraph graph = new StructuredGraph(method);
+        HotSpotProviders providers = getProviders();
+        new GraphBuilderPhase.Instance(providers.getMetaAccess(), GraphBuilderConfiguration.getEagerDefault(), OptimisticOptimizations.ALL).apply(graph);
+        PhaseSuite<HighTierContext> graphBuilderSuite = providers.getSuites().getDefaultGraphBuilderSuite();
+        graphBuilderSuite.appendPhase(new NonNullParametersPhase());
+        CallingConvention cc = getCallingConvention(providers.getCodeCache(), Type.JavaCallee, graph.method(), false);
+        Suites suites = providers.getSuites().getDefaultSuites();
+        ExternalCompilationResult hsailCode = compileGraph(graph, cc, method, providers, this, this.getTarget(), null, graphBuilderSuite, OptimisticOptimizations.NONE, getProfilingInfo(graph),
+                        new SpeculationLog(), suites, true, new ExternalCompilationResult(), CompilationResultBuilderFactory.Default);
+
+        if (makeBinary) {
+            try (Scope ds = Debug.scope("GeneratingKernelBinary")) {
+                long kernel = getRuntime().getCompilerToGPU().generateKernel(hsailCode.getTargetCode(), method.getName());
+                if (kernel == 0) {
+                    throw new GraalInternalError("Failed to compile HSAIL kernel");
+                }
+                hsailCode.setEntryPoint(kernel);
+            } catch (Throwable e) {
+                throw Debug.handle(e);
+            }
+        }
+        return hsailCode;
+    }
+
+    /**
+     * Installs the {@linkplain ExternalCompilationResult#getEntryPoint() GPU binary} associated
+     * with some given HSAIL code in the code cache and returns a {@link HotSpotNmethod} handle to
+     * the installed code.
+     * 
+     * @param hsailCode HSAIL compilation result for which a GPU binary has been generated
+     * @return a handle to the binary as installed in the HotSpot code cache
+     */
+    public final HotSpotNmethod installKernel(ResolvedJavaMethod method, ExternalCompilationResult hsailCode) {
+        assert hsailCode.getEntryPoint() != 0L;
+        return getProviders().getCodeCache().addExternalMethod(method, hsailCode);
+    }
+
+    /**
      * Use the HSAIL register set when the compilation target is HSAIL.
      */
     @Override
--- a/graal/com.oracle.graal.hotspot.hsail/src/com/oracle/graal/hotspot/hsail/HSAILHotSpotBackendFactory.java	Tue Jan 28 19:37:26 2014 +0100
+++ b/graal/com.oracle.graal.hotspot.hsail/src/com/oracle/graal/hotspot/hsail/HSAILHotSpotBackendFactory.java	Wed Jan 29 12:19:03 2014 +0100
@@ -28,6 +28,7 @@
 import com.oracle.graal.hotspot.*;
 import com.oracle.graal.hotspot.meta.*;
 import com.oracle.graal.hsail.*;
+import com.oracle.graal.java.*;
 import com.oracle.graal.nodes.spi.*;
 import com.oracle.graal.phases.tiers.*;
 import com.oracle.graal.phases.util.*;
@@ -51,7 +52,7 @@
         Providers p = new Providers(metaAccess, codeCache, constantReflection, foreignCalls, lowerer, null);
         Replacements replacements = new HSAILHotSpotReplacementsImpl(p, assumptions, codeCache.getTarget(), host.getReplacements());
         HotSpotDisassemblerProvider disassembler = host.getDisassembler();
-        SuitesProvider suites = host.getSuites();
+        SuitesProvider suites = new DefaultSuitesProvider();
         HotSpotProviders providers = new HotSpotProviders(metaAccess, codeCache, constantReflection, foreignCalls, lowerer, replacements, disassembler, suites, registers);
 
         return new HSAILHotSpotBackend(runtime, providers);
--- a/graal/com.oracle.graal.hotspot.ptx/src/com/oracle/graal/hotspot/ptx/PTXHotSpotBackend.java	Tue Jan 28 19:37:26 2014 +0100
+++ b/graal/com.oracle.graal.hotspot.ptx/src/com/oracle/graal/hotspot/ptx/PTXHotSpotBackend.java	Wed Jan 29 12:19:03 2014 +0100
@@ -155,7 +155,8 @@
             }
 
             private boolean canOffloadToGPU(ResolvedJavaMethod method) {
-                return method.getName().contains("lambda$") & method.isSynthetic();
+                HotSpotVMConfig config = getRuntime().getConfig();
+                return config.gpuOffload && method.getName().contains("lambda$") & method.isSynthetic();
             }
         };
     }
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotVMConfig.java	Tue Jan 28 19:37:26 2014 +0100
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotVMConfig.java	Wed Jan 29 12:19:03 2014 +0100
@@ -39,12 +39,19 @@
 
     private static final long serialVersionUID = -4744897993263044184L;
 
-    private static boolean containsString(String[] array, String item) {
-        if (array == null) {
-            return false;
+    /**
+     * Determines if the current architecture is included in a given architecture set specification.
+     * 
+     * @param currentArch
+     * @param archsSpecification specifies a set of architectures. A zero length value implies all
+     *            architectures.
+     */
+    private static boolean isRequired(String currentArch, String[] archsSpecification) {
+        if (archsSpecification.length == 0) {
+            return true;
         }
-        for (String arch : array) {
-            if (arch.equals(item)) {
+        for (String arch : archsSpecification) {
+            if (arch.equals(currentArch)) {
                 return true;
             }
         }
@@ -90,7 +97,7 @@
                 String type = annotation.type();
                 VMFields.Field entry = vmFields.get(name);
                 if (entry == null) {
-                    if (annotation.optional() || !containsString(annotation.archs(), currentArch)) {
+                    if (annotation.optional() || !isRequired(currentArch, annotation.archs())) {
                         continue;
                     }
                     throw new IllegalArgumentException("field not found: " + name);
@@ -135,11 +142,10 @@
                 String name = annotation.name();
                 AbstractConstant entry = vmConstants.get(name);
                 if (entry == null) {
-                    if (!containsString(annotation.archs(), currentArch)) {
+                    if (!isRequired(currentArch, annotation.archs())) {
                         continue;
-                    } else {
-                        throw new IllegalArgumentException("constant not found: " + name);
                     }
+                    throw new IllegalArgumentException("constant not found: " + name);
                 }
                 setField(f, entry.getValue());
             } else if (f.isAnnotationPresent(HotSpotVMFlag.class)) {
@@ -147,11 +153,11 @@
                 String name = annotation.name();
                 Flags.Flag entry = flags.get(name);
                 if (entry == null) {
-                    if (annotation.optional() || !containsString(annotation.archs(), currentArch)) {
+                    if (!isRequired(currentArch, annotation.archs())) {
                         continue;
-                    } else {
-                        throw new IllegalArgumentException("flag not found: " + name);
                     }
+                    throw new IllegalArgumentException("flag not found: " + name);
+
                 }
                 setField(f, entry.getValue());
             }
@@ -712,6 +718,7 @@
     @HotSpotVMFlag(name = "PrintInlining") @Stable public boolean printInlining;
     @HotSpotVMFlag(name = "GraalUseFastLocking") @Stable public boolean useFastLocking;
     @HotSpotVMFlag(name = "ForceUnreachable") @Stable public boolean forceUnreachable;
+    @HotSpotVMFlag(name = "GPUOffload") @Stable public boolean gpuOffload;
 
     @HotSpotVMFlag(name = "UseTLAB") @Stable public boolean useTLAB;
     @HotSpotVMFlag(name = "UseBiasedLocking") @Stable public boolean useBiasedLocking;
@@ -832,8 +839,6 @@
     @HotSpotVMField(name = "JavaThread::_vm_result", type = "oop", get = HotSpotVMField.Type.OFFSET) @Stable public int threadObjectResultOffset;
     @HotSpotVMField(name = "JavaThread::_graal_counters[0]", type = "jlong", get = HotSpotVMField.Type.OFFSET, optional = true) @Stable public int graalCountersThreadOffset;
 
-    @HotSpotVMConstant(name = "GRAAL_COUNTERS_SIZE") @Stable public int graalCountersSize;
-
     /**
      * This field is used to pass exception objects into and out of the runtime system during
      * exception handling for compiled code.
@@ -1267,6 +1272,8 @@
     @Stable public long arithmeticTanAddress;
     @Stable public long loadAndClearExceptionAddress;
 
+    @Stable public int graalCountersSize;
+
     @HotSpotVMConstant(name = "Deoptimization::Reason_none") @Stable public int deoptReasonNone;
     @HotSpotVMConstant(name = "Deoptimization::Reason_null_check") @Stable public int deoptReasonNullCheck;
     @HotSpotVMConstant(name = "Deoptimization::Reason_range_check") @Stable public int deoptReasonRangeCheck;
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotVMConstant.java	Tue Jan 28 19:37:26 2014 +0100
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotVMConstant.java	Wed Jan 29 12:19:03 2014 +0100
@@ -32,7 +32,8 @@
 
     /**
      * List of architectures where this constant is required. Names are derived from
-     * {@link HotSpotVMConfig#getHostArchitectureName()}.
+     * {@link HotSpotVMConfig#getHostArchitectureName()}. An empty list implies that the constant is
+     * required on all architectures.
      */
     String[] archs() default {};
 
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotVMField.java	Tue Jan 28 19:37:26 2014 +0100
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotVMField.java	Wed Jan 29 12:19:03 2014 +0100
@@ -40,7 +40,8 @@
 
     /**
      * List of architectures where this constant is required. Names are derived from
-     * {@link HotSpotVMConfig#getHostArchitectureName()}.
+     * {@link HotSpotVMConfig#getHostArchitectureName()}. An empty list implies that the constant is
+     * required on all architectures.
      */
     String[] archs() default {};
 
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotVMFlag.java	Tue Jan 28 19:37:26 2014 +0100
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotVMFlag.java	Wed Jan 29 12:19:03 2014 +0100
@@ -32,7 +32,8 @@
 
     /**
      * List of architectures where this constant is required. Names are derived from
-     * {@link HotSpotVMConfig#getHostArchitectureName()}.
+     * {@link HotSpotVMConfig#getHostArchitectureName()}. An empty list implies that the constant is
+     * required on all architectures.
      */
     String[] archs() default {};
 
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/debug/BenchmarkCounters.java	Tue Jan 28 19:37:26 2014 +0100
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/debug/BenchmarkCounters.java	Wed Jan 29 12:19:03 2014 +0100
@@ -107,7 +107,7 @@
 
     public static int getIndex(DynamicCounterNode counter) {
         if (!enabled) {
-            throw new GraalInternalError("counter nodes shouldn't exist when counters are not enabled");
+            throw new GraalInternalError("counter nodes shouldn't exist when counters are not enabled: " + counter.getGroup() + ", " + counter.getName());
         }
         String name = counter.getName();
         String group = counter.getGroup();
@@ -332,12 +332,15 @@
             if (index >= config.graalCountersSize) {
                 throw new GraalInternalError("too many counters, reduce number of counters or increase GRAAL_COUNTERS_SIZE (current value: " + config.graalCountersSize + ")");
             }
-            ConstantLocationNode location = ConstantLocationNode.create(LocationIdentity.ANY_LOCATION, Kind.Long, config.graalCountersThreadOffset + Unsafe.ARRAY_LONG_INDEX_SCALE * index, graph);
-            ReadNode read = graph.add(new ReadNode(thread, location, StampFactory.forKind(Kind.Long), BarrierType.NONE, false));
+            ConstantLocationNode arrayLocation = ConstantLocationNode.create(LocationIdentity.ANY_LOCATION, Kind.Long, config.graalCountersThreadOffset, graph);
+            ReadNode readArray = graph.add(new ReadNode(thread, arrayLocation, StampFactory.forKind(wordKind), BarrierType.NONE, false));
+            ConstantLocationNode location = ConstantLocationNode.create(LocationIdentity.ANY_LOCATION, Kind.Long, Unsafe.ARRAY_LONG_INDEX_SCALE * index, graph);
+            ReadNode read = graph.add(new ReadNode(readArray, location, StampFactory.forKind(Kind.Long), BarrierType.NONE, false));
             IntegerAddNode add = graph.unique(new IntegerAddNode(Kind.Long, read, counter.getIncrement()));
-            WriteNode write = graph.add(new WriteNode(thread, add, location, BarrierType.NONE, false));
+            WriteNode write = graph.add(new WriteNode(readArray, add, location, BarrierType.NONE, false));
 
             graph.addBeforeFixed(counter, thread);
+            graph.addBeforeFixed(counter, readArray);
             graph.addBeforeFixed(counter, read);
             graph.addBeforeFixed(counter, write);
         }
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotResolvedJavaField.java	Tue Jan 28 19:37:26 2014 +0100
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotResolvedJavaField.java	Wed Jan 29 12:19:03 2014 +0100
@@ -198,9 +198,9 @@
             Object object = receiver.asObject();
 
             // Canonicalization may attempt to process an unsafe read before
-            // processing a guard (e.g. a type check) for this read
-            // so we need to type check the object being read
-            if (isInObject(object)) {
+            // processing a guard (e.g. a null check or a type check) for this read
+            // so we need to check the object being read
+            if (object != null && isInObject(object)) {
                 if (Modifier.isFinal(getModifiers())) {
                     Constant value = readValue(receiver);
                     if (assumeNonStaticFinalFieldsAsFinal(object.getClass()) || !value.isDefaultForKind()) {
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotResolvedJavaMethod.java	Tue Jan 28 19:37:26 2014 +0100
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotResolvedJavaMethod.java	Wed Jan 29 12:19:03 2014 +0100
@@ -157,10 +157,18 @@
         return getMetaspaceMethodConstant();
     }
 
+    /**
+     * Gets the complete set of modifiers for this method which includes the JVM specification
+     * modifiers as well as the HotSpot internal modifiers.
+     */
+    public int getAllModifiers() {
+        HotSpotVMConfig config = runtime().getConfig();
+        return unsafe.getInt(metaspaceMethod + config.methodAccessFlagsOffset);
+    }
+
     @Override
     public int getModifiers() {
-        HotSpotVMConfig config = runtime().getConfig();
-        return unsafe.getInt(metaspaceMethod + config.methodAccessFlagsOffset) & Modifier.methodModifiers();
+        return getAllModifiers() & Modifier.methodModifiers();
     }
 
     @Override
@@ -424,27 +432,23 @@
         return javaMethod == null ? null : javaMethod.getAnnotation(annotationClass);
     }
 
+    private static final int SYNTHETIC;
+    static {
+        try {
+            // Unfortunately, Modifier.SYNTHETIC is not public so we have
+            // to jump though hoops to get it.
+            Field field = Modifier.class.getDeclaredField("SYNTHETIC");
+            field.setAccessible(true);
+            SYNTHETIC = field.getInt(null);
+        } catch (IllegalArgumentException | IllegalAccessException | NoSuchFieldException | SecurityException e) {
+            throw GraalInternalError.shouldNotReachHere(e.toString());
+        }
+    }
+
     @Override
     public boolean isSynthetic() {
-        if (isConstructor()) {
-            Constructor<?> javaConstructor = toJavaConstructor();
-            return javaConstructor == null ? false : javaConstructor.isSynthetic();
-        }
-
-        // Cannot use toJava() as it ignores the return type
-        HotSpotSignature sig = getSignature();
-        JavaType[] sigTypes = MetaUtil.signatureToTypes(sig, null);
-        MetaAccessProvider metaAccess = runtime().getHostProviders().getMetaAccess();
-        for (Method method : holder.mirror().getDeclaredMethods()) {
-            if (method.getName().equals(name)) {
-                if (metaAccess.lookupJavaType(method.getReturnType()).equals(sig.getReturnType(holder))) {
-                    if (matches(metaAccess, sigTypes, method.getParameterTypes())) {
-                        return method.isSynthetic();
-                    }
-                }
-            }
-        }
-        return false;
+        int modifiers = getAllModifiers();
+        return (SYNTHETIC & modifiers) != 0;
     }
 
     public boolean isDefault() {
@@ -476,18 +480,6 @@
         return result;
     }
 
-    private static boolean matches(MetaAccessProvider metaAccess, JavaType[] sigTypes, Class<?>[] parameterTypes) {
-        if (parameterTypes.length == sigTypes.length) {
-            for (int i = 0; i < parameterTypes.length; i++) {
-                if (!metaAccess.lookupJavaType(parameterTypes[i]).equals(sigTypes[i])) {
-                    return false;
-                }
-            }
-            return true;
-        }
-        return false;
-    }
-
     private Method toJava() {
         try {
             return holder.mirror().getDeclaredMethod(name, signatureToTypes());
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/phases/OnStackReplacementPhase.java	Tue Jan 28 19:37:26 2014 +0100
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/phases/OnStackReplacementPhase.java	Wed Jan 29 12:19:03 2014 +0100
@@ -78,10 +78,7 @@
                 ProxyNode proxy = (ProxyNode) usage;
                 proxy.replaceAndDelete(proxy.value());
             }
-            FixedNode next = osr.next();
-            osr.setNext(null);
-            ((FixedWithNextNode) osr.predecessor()).setNext(next);
-            GraphUtil.killWithUnusedFloatingInputs(osr);
+            GraphUtil.removeFixedWithUnusedInputs(osr);
             Debug.dump(graph, "OnStackReplacement loop peeling result");
         } while (true);
 
--- a/graal/com.oracle.graal.java/src/com/oracle/graal/java/GraphBuilderPhase.java	Tue Jan 28 19:37:26 2014 +0100
+++ b/graal/com.oracle.graal.java/src/com/oracle/graal/java/GraphBuilderPhase.java	Wed Jan 29 12:19:03 2014 +0100
@@ -1711,7 +1711,11 @@
                 ResolvedJavaType resolvedCatchType = (ResolvedJavaType) catchType;
                 for (ResolvedJavaType skippedType : graphBuilderConfig.getSkippedExceptionTypes()) {
                     if (skippedType.isAssignableFrom(resolvedCatchType)) {
-                        append(new DeoptimizeNode(InvalidateReprofile, UnreachedCode));
+                        Block nextBlock = block.successors.size() == 1 ? unwindBlock(block.deoptBci) : block.successors.get(1);
+                        ValueNode exception = frameState.stackAt(0);
+                        FixedNode trueSuccessor = currentGraph.add(new DeoptimizeNode(InvalidateReprofile, UnreachedCode));
+                        FixedNode nextDispatch = createTarget(nextBlock, frameState);
+                        append(new IfNode(currentGraph.unique(new InstanceOfNode((ResolvedJavaType) catchType, exception, null)), trueSuccessor, nextDispatch, 0));
                         return;
                     }
                 }
--- a/graal/com.oracle.graal.lir.ptx/src/com/oracle/graal/lir/ptx/PTXControlFlow.java	Tue Jan 28 19:37:26 2014 +0100
+++ b/graal/com.oracle.graal.lir.ptx/src/com/oracle/graal/lir/ptx/PTXControlFlow.java	Wed Jan 29 12:19:03 2014 +0100
@@ -86,9 +86,9 @@
         @Override
         public void emitCode(CompilationResultBuilder crb, PTXMacroAssembler masm) {
             if (crb.isSuccessorEdge(trueDestination)) {
-                masm.bra(masm.nameOf(falseDestination.label()), predRegNum);
+                masm.bra(masm.nameOf(falseDestination.label()), predRegNum, false);
             } else {
-                masm.bra(masm.nameOf(trueDestination.label()));
+                masm.bra(masm.nameOf(trueDestination.label()), predRegNum, true);
                 if (!crb.isSuccessorEdge(falseDestination)) {
                     masm.jmp(falseDestination.label());
                 }
@@ -238,7 +238,7 @@
                         default:
                             throw new GraalInternalError("switch only supported for int, long and object");
                     }
-                    masm.bra(masm.nameOf(target), predRegNum);
+                    masm.bra(masm.nameOf(target), predRegNum, true);
                 }
             };
             strategy.run(closure);
@@ -281,7 +281,7 @@
 
             // Jump to default target if index is not within the jump table
             if (defaultTarget != null) {
-                masm.bra(masm.nameOf(defaultTarget.label()), predRegNum);
+                masm.bra(masm.nameOf(defaultTarget.label()), predRegNum, true);
             }
 
             // address of jump table
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/LoopBeginNode.java	Tue Jan 28 19:37:26 2014 +0100
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/LoopBeginNode.java	Wed Jan 29 12:19:03 2014 +0100
@@ -31,6 +31,7 @@
 import com.oracle.graal.graph.spi.*;
 import com.oracle.graal.nodes.extended.*;
 import com.oracle.graal.nodes.spi.*;
+import com.oracle.graal.nodes.util.*;
 
 public class LoopBeginNode extends MergeNode implements IterableNodeType, LIRLowerable {
 
@@ -184,7 +185,11 @@
     public void removeExits() {
         for (LoopExitNode loopexit : loopExits().snapshot()) {
             loopexit.removeProxies();
+            FrameState stateAfter = loopexit.stateAfter();
             graph().replaceFixedWithFixed(loopexit, graph().add(new BeginNode()));
+            if (stateAfter != null && stateAfter.isAlive() && stateAfter.usages().isEmpty()) {
+                GraphUtil.killWithUnusedFloatingInputs(stateAfter);
+            }
         }
     }
 
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/LoadFieldNode.java	Tue Jan 28 19:37:26 2014 +0100
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/LoadFieldNode.java	Wed Jan 29 12:19:03 2014 +0100
@@ -74,6 +74,9 @@
                 return phi;
             }
         }
+        if (!isStatic() && object().isNullConstant()) {
+            return graph().add(new DeoptimizeNode(DeoptimizationAction.None, DeoptimizationReason.NullCheckException));
+        }
         return this;
     }
 
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/MonitorEnterNode.java	Tue Jan 28 19:37:26 2014 +0100
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/MonitorEnterNode.java	Wed Jan 29 12:19:03 2014 +0100
@@ -23,6 +23,7 @@
 package com.oracle.graal.nodes.java;
 
 import com.oracle.graal.api.meta.*;
+import com.oracle.graal.graph.*;
 import com.oracle.graal.nodes.*;
 import com.oracle.graal.nodes.extended.*;
 import com.oracle.graal.nodes.spi.*;
@@ -30,7 +31,7 @@
 /**
  * The {@code MonitorEnterNode} represents the acquisition of a monitor.
  */
-public final class MonitorEnterNode extends AccessMonitorNode implements Virtualizable, Lowerable, MonitorEnter, MemoryCheckpoint.Single {
+public final class MonitorEnterNode extends AccessMonitorNode implements Virtualizable, Lowerable, IterableNodeType, MonitorEnter, MemoryCheckpoint.Single {
 
     /**
      * Creates a new MonitorEnterNode.
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/util/GraphUtil.java	Tue Jan 28 19:37:26 2014 +0100
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/util/GraphUtil.java	Wed Jan 29 12:19:03 2014 +0100
@@ -137,6 +137,13 @@
         }
     }
 
+    public static void removeFixedWithUnusedInputs(FixedWithNextNode fixed) {
+        FixedNode next = fixed.next();
+        fixed.setNext(null);
+        fixed.replaceAtPredecessor(next);
+        killWithUnusedFloatingInputs(fixed);
+    }
+
     public static void checkRedundantPhi(PhiNode phiNode) {
         if (phiNode.isDeleted() || phiNode.valueCount() == 1) {
             return;
--- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/LockEliminationPhase.java	Tue Jan 28 19:37:26 2014 +0100
+++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/LockEliminationPhase.java	Wed Jan 29 12:19:03 2014 +0100
@@ -36,19 +36,8 @@
             if (next instanceof MonitorEnterNode) {
                 MonitorEnterNode monitorEnterNode = (MonitorEnterNode) next;
                 if (monitorEnterNode.object() == node.object()) {
-                    FixedNode monitorEnterSuccessor = monitorEnterNode.next();
-                    monitorEnterNode.setNext(null);
-                    ((FixedWithNextNode) node.predecessor()).setNext(monitorEnterSuccessor);
-                    FrameState stateAfterFirst = node.stateAfter();
-                    FrameState stateAfterSecond = monitorEnterNode.stateAfter();
-                    node.safeDelete();
-                    monitorEnterNode.safeDelete();
-                    if (stateAfterFirst.usages().isEmpty()) {
-                        GraphUtil.killWithUnusedFloatingInputs(stateAfterFirst);
-                    }
-                    if (stateAfterSecond.usages().isEmpty()) {
-                        GraphUtil.killWithUnusedFloatingInputs(stateAfterSecond);
-                    }
+                    GraphUtil.removeFixedWithUnusedInputs(monitorEnterNode);
+                    GraphUtil.removeFixedWithUnusedInputs(node);
                 }
             }
         }
--- a/graal/com.oracle.graal.phases/src/com/oracle/graal/phases/util/GraphOrder.java	Tue Jan 28 19:37:26 2014 +0100
+++ b/graal/com.oracle.graal.phases/src/com/oracle/graal/phases/util/GraphOrder.java	Wed Jan 29 12:19:03 2014 +0100
@@ -55,7 +55,7 @@
                         if (input instanceof FrameState && node instanceof StateSplit && input == ((StateSplit) node).stateAfter()) {
                             // nothing to do - after frame states are known, allowed cycles
                         } else {
-                            assert false : "cycle detected: " + node + " -> " + input;
+                            assert false : "unexpected cycle detected at input " + node + " -> " + input;
                         }
                     }
                 }
@@ -81,7 +81,7 @@
 
     private static void visitForward(ArrayList<Node> nodes, NodeBitMap visited, Node node, boolean floatingOnly) {
         if (node != null && !visited.isMarked(node)) {
-            assert !floatingOnly || !(node instanceof FixedNode) : "unexpected reference to fixed node: " + node;
+            assert !floatingOnly || !(node instanceof FixedNode) : "unexpected reference to fixed node: " + node + " (this indicates an unexpected cycle)";
             visited.mark(node);
             FrameState stateAfter = null;
             if (node instanceof StateSplit) {
--- a/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/SnippetTemplate.java	Tue Jan 28 19:37:26 2014 +0100
+++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/SnippetTemplate.java	Wed Jan 29 12:19:03 2014 +0100
@@ -569,11 +569,7 @@
                     LoopTransformations.fullUnroll(loop, phaseContext, new CanonicalizerPhase(true));
                     new CanonicalizerPhase(true).applyIncremental(snippetCopy, phaseContext, mark);
                 }
-                FixedNode explodeLoopNext = explodeLoop.next();
-                explodeLoop.clearSuccessors();
-                explodeLoop.replaceAtPredecessor(explodeLoopNext);
-                explodeLoop.replaceAtUsages(null);
-                GraphUtil.killCFG(explodeLoop);
+                GraphUtil.removeFixedWithUnusedInputs(explodeLoop);
                 exploded = true;
             }
         } while (exploded);
--- a/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/nodes/MacroNode.java	Tue Jan 28 19:37:26 2014 +0100
+++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/nodes/MacroNode.java	Wed Jan 29 12:19:03 2014 +0100
@@ -24,8 +24,6 @@
 
 import static java.lang.reflect.Modifier.*;
 
-import java.lang.reflect.*;
-
 import com.oracle.graal.api.meta.*;
 import com.oracle.graal.debug.*;
 import com.oracle.graal.debug.Debug.Scope;
@@ -47,6 +45,7 @@
     private final int bci;
     private final ResolvedJavaMethod targetMethod;
     private final JavaType returnType;
+    private final InvokeKind invokeKind;
 
     protected MacroNode(Invoke invoke) {
         super(invoke.asNode().stamp(), invoke.stateAfter());
@@ -55,6 +54,7 @@
         this.bci = invoke.bci();
         this.targetMethod = methodCallTarget.targetMethod();
         this.returnType = methodCallTarget.returnType();
+        this.invokeKind = methodCallTarget.invokeKind();
     }
 
     public int getBci() {
@@ -148,17 +148,21 @@
         }
     }
 
-    private InvokeNode replaceWithInvoke() {
+    protected InvokeNode replaceWithInvoke() {
         InvokeNode invoke = createInvoke();
         graph().replaceFixedWithFixed(this, invoke);
         return invoke;
     }
 
     protected InvokeNode createInvoke() {
-        InvokeKind invokeKind = Modifier.isStatic(targetMethod.getModifiers()) ? InvokeKind.Static : InvokeKind.Special;
         MethodCallTargetNode callTarget = graph().add(new MethodCallTargetNode(invokeKind, targetMethod, arguments.toArray(new ValueNode[arguments.size()]), returnType));
         InvokeNode invoke = graph().add(new InvokeNode(callTarget, bci));
-        invoke.setStateAfter(stateAfter());
+        if (stateAfter() != null) {
+            invoke.setStateAfter(stateAfter().duplicate());
+            if (kind() != Kind.Void) {
+                invoke.stateAfter().replaceFirstInput(this, invoke);
+            }
+        }
         return invoke;
     }
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.truffle.test/src/com/oracle/graal/truffle/test/ControlFlowExceptionPartialEvaluationTest.java	Wed Jan 29 12:19:03 2014 +0100
@@ -0,0 +1,102 @@
+/*
+ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.graal.truffle.test;
+
+import org.junit.*;
+
+import com.oracle.graal.truffle.test.nodes.*;
+import com.oracle.truffle.api.frame.*;
+import com.oracle.truffle.api.nodes.*;
+
+@Ignore("Currently ignored due to problems with code coverage tools.")
+public class ControlFlowExceptionPartialEvaluationTest extends PartialEvaluationTest {
+
+    public static Object constant42() {
+        return 42;
+    }
+
+    @Test
+    public void catchControlFlowException() {
+        FrameDescriptor fd = new FrameDescriptor();
+        AbstractTestNode result = new CatchControlFlowExceptionTestNode(new ThrowControlFlowExceptionTestNode());
+        assertPartialEvalEquals("constant42", new RootTestNode(fd, "catchControlFlowException", result));
+    }
+
+    @Test
+    public void catchSlowPathAndControlFlowException() {
+        FrameDescriptor fd = new FrameDescriptor();
+        AbstractTestNode result = new CatchSlowPathAndControlFlowExceptionTestNode(new ThrowControlFlowExceptionTestNode());
+        assertPartialEvalEquals("constant42", new RootTestNode(fd, "catchSlowPathAndControlFlowException", result));
+    }
+
+    public static class ThrowControlFlowExceptionTestNode extends AbstractTestNode {
+
+        @Override
+        public int execute(VirtualFrame frame) {
+            throw new ControlFlowException();
+        }
+    }
+
+    public static class CatchControlFlowExceptionTestNode extends AbstractTestNode {
+
+        @Child private AbstractTestNode child;
+
+        public CatchControlFlowExceptionTestNode(AbstractTestNode child) {
+            this.child = adoptChild(child);
+        }
+
+        @Override
+        public int execute(VirtualFrame frame) {
+            try {
+                return child.execute(frame);
+            } catch (ControlFlowException e) {
+                return 42;
+            }
+        }
+    }
+
+    public static class CatchSlowPathAndControlFlowExceptionTestNode extends AbstractTestNode {
+
+        @Child private AbstractTestNode child;
+
+        public CatchSlowPathAndControlFlowExceptionTestNode(AbstractTestNode child) {
+            this.child = adoptChild(child);
+        }
+
+        @Override
+        public int execute(VirtualFrame frame) {
+            try {
+                return executeChild(frame);
+            } catch (SlowPathException spe) {
+                return -1;
+            } catch (ControlFlowException e) {
+                return 42;
+            }
+        }
+
+        @SuppressWarnings("unused")
+        private int executeChild(VirtualFrame frame) throws SlowPathException {
+            return child.execute(frame);
+        }
+    }
+}
--- a/graal/com.oracle.graal.truffle.test/src/com/oracle/graal/truffle/test/PartialEvaluationTest.java	Tue Jan 28 19:37:26 2014 +0100
+++ b/graal/com.oracle.graal.truffle.test/src/com/oracle/graal/truffle/test/PartialEvaluationTest.java	Wed Jan 29 12:19:03 2014 +0100
@@ -27,7 +27,6 @@
 import org.junit.*;
 
 import com.oracle.graal.api.code.*;
-import com.oracle.graal.api.runtime.*;
 import com.oracle.graal.compiler.test.*;
 import com.oracle.graal.debug.*;
 import com.oracle.graal.debug.Debug.Scope;
@@ -39,9 +38,7 @@
 import com.oracle.graal.phases.*;
 import com.oracle.graal.phases.common.*;
 import com.oracle.graal.phases.tiers.*;
-import com.oracle.graal.phases.util.*;
 import com.oracle.graal.printer.*;
-import com.oracle.graal.runtime.*;
 import com.oracle.graal.truffle.*;
 import com.oracle.graal.virtual.phases.ea.*;
 import com.oracle.truffle.api.*;
@@ -50,15 +47,12 @@
 public class PartialEvaluationTest extends GraalCompilerTest {
 
     private static final long UNROLL_LIMIT = 100;
-    private final PartialEvaluator partialEvaluator;
+    private final TruffleCompilerImpl truffleCompiler;
 
     public PartialEvaluationTest() {
         // Make sure Truffle runtime is initialized.
         Assert.assertTrue(Truffle.getRuntime() instanceof GraalTruffleRuntime);
-        Replacements truffleReplacements = ((GraalTruffleRuntime) Truffle.getRuntime()).getReplacements();
-        Providers providers = getProviders().copyWith(truffleReplacements);
-        TruffleCache truffleCache = new TruffleCache(providers, GraphBuilderConfiguration.getDefault(), TruffleCompilerImpl.Optimizations);
-        this.partialEvaluator = new PartialEvaluator(Graal.getRequiredCapability(RuntimeProvider.class), providers, truffleCache);
+        this.truffleCompiler = new TruffleCompilerImpl();
 
         DebugEnvironment.initialize(System.out);
     }
@@ -70,7 +64,7 @@
     protected InstalledCode assertPartialEvalEquals(String methodName, RootNode root, Arguments arguments) {
         Assumptions assumptions = new Assumptions(true);
         StructuredGraph actual = partialEval(root, arguments, assumptions, true);
-        InstalledCode result = new TruffleCompilerImpl().compileMethodHelper(actual, GraphBuilderConfiguration.getDefault(), assumptions, root.toString(), getSpeculationLog());
+        InstalledCode result = truffleCompiler.compileMethodHelper(actual, assumptions, root.toString(), getSpeculationLog());
         StructuredGraph expected = parseForComparison(methodName);
         removeFrameStates(actual);
         Assert.assertEquals(getCanonicalGraphString(expected, true), getCanonicalGraphString(actual, true));
@@ -102,7 +96,7 @@
 
         try (Scope s = Debug.scope("TruffleCompilation", new TruffleDebugJavaMethod(compilable))) {
 
-            StructuredGraph resultGraph = partialEvaluator.createGraph(compilable, assumptions);
+            StructuredGraph resultGraph = truffleCompiler.getPartialEvaluator().createGraph(compilable, assumptions);
             CanonicalizerPhase canonicalizer = new CanonicalizerPhase(canonicalizeReads);
             PhaseContext context = new PhaseContext(getProviders(), assumptions);
 
--- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/PartialEvaluator.java	Tue Jan 28 19:37:26 2014 +0100
+++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/PartialEvaluator.java	Wed Jan 29 12:19:03 2014 +0100
@@ -68,16 +68,16 @@
     private final Providers providers;
     private final ResolvedJavaMethod executeHelperMethod;
     private final CanonicalizerPhase canonicalizer;
-    private final ResolvedJavaType[] skippedExceptionTypes;
+    private final GraphBuilderConfiguration config;
     private Set<Constant> constantReceivers;
     private final GraphCache cache;
     private final TruffleCache truffleCache;
 
-    public PartialEvaluator(RuntimeProvider runtime, Providers providers, TruffleCache truffleCache) {
+    public PartialEvaluator(RuntimeProvider runtime, Providers providers, TruffleCache truffleCache, GraphBuilderConfiguration config) {
         this.providers = providers;
         CustomCanonicalizer customCanonicalizer = new PartialEvaluatorCanonicalizer(providers.getMetaAccess(), providers.getConstantReflection());
         this.canonicalizer = new CanonicalizerPhase(!ImmutableCode.getValue(), customCanonicalizer);
-        this.skippedExceptionTypes = TruffleCompilerImpl.getSkippedExceptionTypes(providers.getMetaAccess());
+        this.config = config;
         this.cache = runtime.getGraphCache();
         this.truffleCache = truffleCache;
         try {
@@ -98,9 +98,6 @@
             constantReceivers = new HashSet<>();
         }
 
-        final GraphBuilderConfiguration config = GraphBuilderConfiguration.getDefault();
-        config.setSkippedExceptionTypes(skippedExceptionTypes);
-
         final StructuredGraph graph = new StructuredGraph(executeHelperMethod);
 
         try (Scope s = Debug.scope("createGraph", graph)) {
--- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/TruffleCompilerImpl.java	Tue Jan 28 19:37:26 2014 +0100
+++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/TruffleCompilerImpl.java	Wed Jan 29 12:19:03 2014 +0100
@@ -36,7 +36,6 @@
 import com.oracle.graal.api.meta.*;
 import com.oracle.graal.api.runtime.*;
 import com.oracle.graal.compiler.*;
-import com.oracle.graal.compiler.CompilerThreadFactory.*;
 import com.oracle.graal.compiler.target.*;
 import com.oracle.graal.debug.*;
 import com.oracle.graal.debug.Debug.Scope;
@@ -65,7 +64,7 @@
     private final Suites suites;
     private final PartialEvaluator partialEvaluator;
     private final Backend backend;
-    private final ResolvedJavaType[] skippedExceptionTypes;
+    private final GraphBuilderConfiguration config;
     private final RuntimeProvider runtime;
     private final TruffleCache truffleCache;
     private final ThreadPoolExecutor compileQueue;
@@ -81,10 +80,9 @@
         Replacements truffleReplacements = ((GraalTruffleRuntime) Truffle.getRuntime()).getReplacements();
         this.providers = backend.getProviders().copyWith(truffleReplacements);
         this.suites = backend.getSuites().getDefaultSuites();
-        this.skippedExceptionTypes = getSkippedExceptionTypes(providers.getMetaAccess());
 
         // Create compilation queue.
-        CompilerThreadFactory factory = new CompilerThreadFactory("TruffleCompilerThread", new DebugConfigAccess() {
+        CompilerThreadFactory factory = new CompilerThreadFactory("TruffleCompilerThread", new CompilerThreadFactory.DebugConfigAccess() {
             public GraalDebugConfig getDebugConfig() {
                 if (Debug.isEnabled()) {
                     GraalDebugConfig debugConfig = DebugEnvironment.initialize(TTY.out().out());
@@ -97,18 +95,21 @@
         });
         compileQueue = new ThreadPoolExecutor(1, 1, 0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue<Runnable>(), factory);
 
-        final GraphBuilderConfiguration config = GraphBuilderConfiguration.getEagerDefault();
-        config.setSkippedExceptionTypes(skippedExceptionTypes);
-        this.truffleCache = new TruffleCache(providers, config, TruffleCompilerImpl.Optimizations);
+        ResolvedJavaType[] skippedExceptionTypes = getSkippedExceptionTypes(providers.getMetaAccess());
+        GraphBuilderConfiguration eagerConfig = GraphBuilderConfiguration.getEagerDefault();
+        eagerConfig.setSkippedExceptionTypes(skippedExceptionTypes);
+        this.truffleCache = new TruffleCache(providers, eagerConfig, TruffleCompilerImpl.Optimizations);
 
-        this.partialEvaluator = new PartialEvaluator(runtime, providers, truffleCache);
+        this.config = GraphBuilderConfiguration.getDefault();
+        this.config.setSkippedExceptionTypes(skippedExceptionTypes);
+        this.partialEvaluator = new PartialEvaluator(runtime, providers, truffleCache, config);
 
         if (Debug.isEnabled()) {
             DebugEnvironment.initialize(System.out);
         }
     }
 
-    static ResolvedJavaType[] getSkippedExceptionTypes(MetaAccessProvider metaAccess) {
+    private static ResolvedJavaType[] getSkippedExceptionTypes(MetaAccessProvider metaAccess) {
         ResolvedJavaType[] skippedExceptionTypes = new ResolvedJavaType[SKIPPED_EXCEPTION_CLASSES.length];
         for (int i = 0; i < SKIPPED_EXCEPTION_CLASSES.length; i++) {
             skippedExceptionTypes[i] = metaAccess.lookupJavaType(SKIPPED_EXCEPTION_CLASSES[i]);
@@ -135,8 +136,6 @@
 
     private InstalledCode compileMethodImpl(final OptimizedCallTarget compilable) {
         final StructuredGraph graph;
-        final GraphBuilderConfiguration config = GraphBuilderConfiguration.getDefault();
-        config.setSkippedExceptionTypes(skippedExceptionTypes);
         GraphCache graphCache = runtime.getGraphCache();
         if (graphCache != null) {
             graphCache.removeStaleGraphs();
@@ -156,7 +155,7 @@
         }
         long timePartialEvaluationFinished = System.nanoTime();
         int nodeCountPartialEval = graph.getNodeCount();
-        InstalledCode compiledMethod = compileMethodHelper(graph, config, assumptions, compilable.toString(), compilable.getSpeculationLog());
+        InstalledCode compiledMethod = compileMethodHelper(graph, assumptions, compilable.toString(), compilable.getSpeculationLog());
         long timeCompilationFinished = System.nanoTime();
         int nodeCountLowered = graph.getNodeCount();
 
@@ -210,7 +209,7 @@
         }
     }
 
-    public InstalledCode compileMethodHelper(StructuredGraph graph, GraphBuilderConfiguration config, Assumptions assumptions, String name, SpeculationLog speculationLog) {
+    public InstalledCode compileMethodHelper(StructuredGraph graph, Assumptions assumptions, String name, SpeculationLog speculationLog) {
         try (Scope s = Debug.scope("TruffleFinal")) {
             Debug.dump(graph, "After TruffleTier");
         } catch (Throwable e) {
@@ -222,7 +221,7 @@
             CodeCacheProvider codeCache = providers.getCodeCache();
             CallingConvention cc = getCallingConvention(codeCache, Type.JavaCallee, graph.method(), false);
             CompilationResult compilationResult = new CompilationResult(name);
-            result = compileGraph(graph, cc, graph.method(), providers, backend, codeCache.getTarget(), null, createGraphBuilderSuite(config), OptimisticOptimizations.ALL, getProfilingInfo(graph),
+            result = compileGraph(graph, cc, graph.method(), providers, backend, codeCache.getTarget(), null, createGraphBuilderSuite(), OptimisticOptimizations.ALL, getProfilingInfo(graph),
                             speculationLog, suites, false, compilationResult, CompilationResultBuilderFactory.Default);
         } catch (Throwable e) {
             throw Debug.handle(e);
@@ -261,7 +260,7 @@
         return installedCode;
     }
 
-    private PhaseSuite<HighTierContext> createGraphBuilderSuite(GraphBuilderConfiguration config) {
+    private PhaseSuite<HighTierContext> createGraphBuilderSuite() {
         PhaseSuite<HighTierContext> suite = backend.getSuites().getDefaultGraphBuilderSuite().copy();
         ListIterator<BasePhase<? super HighTierContext>> iterator = suite.findPhase(GraphBuilderPhase.class);
         iterator.remove();
@@ -279,4 +278,8 @@
             }
         }
     }
+
+    public PartialEvaluator getPartialEvaluator() {
+        return partialEvaluator;
+    }
 }
--- a/mxtool/mx.py	Tue Jan 28 19:37:26 2014 +0100
+++ b/mxtool/mx.py	Wed Jan 29 12:19:03 2014 +0100
@@ -1565,6 +1565,9 @@
 
         return cmp(self.value, other.value)
 
+    def __hash__(self):
+        return self.value.__hash__()
+
 """
 A version specification as defined in JSR-56
 """
@@ -2742,10 +2745,7 @@
     slm.open('sourceLookupDirector')
     slm.open('sourceContainers', {'duplicates' : 'false'})
 
-    # Every Java program depends on the JRE
-    memento = XMLDoc().element('classpathContainer', {'path' : 'org.eclipse.jdt.launching.JRE_CONTAINER'}).xml(standalone='no')
-    slm.element('classpathContainer', {'memento' : memento, 'typeId':'org.eclipse.jdt.launching.sourceContainer.classpathContainer'})
-
+    javaCompliance = None
     for dep in deps:
         if dep.isLibrary():
             if hasattr(dep, 'eclipse.container'):
@@ -2757,6 +2757,15 @@
         else:
             memento = XMLDoc().element('javaProject', {'name' : dep.name}).xml(standalone='no')
             slm.element('container', {'memento' : memento, 'typeId':'org.eclipse.jdt.launching.sourceContainer.javaProject'})
+            if javaCompliance is None or dep.javaCompliance < javaCompliance:
+                javaCompliance = dep.javaCompliance
+
+    if javaCompliance:
+        memento = XMLDoc().element('classpathContainer', {'path' : 'org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-' + str(javaCompliance)}).xml(standalone='no')
+        slm.element('classpathContainer', {'memento' : memento, 'typeId':'org.eclipse.jdt.launching.sourceContainer.classpathContainer'})
+    else:
+        memento = XMLDoc().element('classpathContainer', {'path' : 'org.eclipse.jdt.launching.JRE_CONTAINER'}).xml(standalone='no')
+        slm.element('classpathContainer', {'memento' : memento, 'typeId':'org.eclipse.jdt.launching.sourceContainer.classpathContainer'})
 
     slm.close('sourceContainers')
     slm.close('sourceLookupDirector')
@@ -2933,7 +2942,7 @@
             out.element('classpathentry', {'kind' : 'src', 'path' : 'src_gen'})
             files.append(genDir)
 
-        # Every Java program depends on the JRE
+        # Every Java program depends on a JRE
         out.element('classpathentry', {'kind' : 'con', 'path' : 'org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-' + str(p.javaCompliance)})
 
         if exists(join(p.dir, 'plugin.xml')):  # eclipse plugin project
--- a/src/share/vm/graal/graalCompilerToVM.cpp	Tue Jan 28 19:37:26 2014 +0100
+++ b/src/share/vm/graal/graalCompilerToVM.cpp	Wed Jan 29 12:19:03 2014 +0100
@@ -553,7 +553,7 @@
   //------------------------------------------------------------------------------------------------
 
   set_int("graalCountersThreadOffset", in_bytes(JavaThread::graal_counters_offset()));
-  set_int("graalCountersSize", (jint) GRAAL_COUNTERS_SIZE);
+  set_int("graalCountersSize", (jint) GraalCounterSize);
 
 #undef set_boolean
 #undef set_int
@@ -816,7 +816,7 @@
 C2V_END
 
 C2V_VMENTRY(jlongArray, collectCounters, (JNIEnv *env, jobject))
-  typeArrayOop arrayOop = oopFactory::new_longArray(GRAAL_COUNTERS_SIZE, CHECK_NULL);
+  typeArrayOop arrayOop = oopFactory::new_longArray(GraalCounterSize, CHECK_NULL);
   JavaThread::collect_counters(arrayOop);
   return (jlongArray) JNIHandles::make_local(arrayOop);
 C2V_END
--- a/src/share/vm/graal/graalGlobals.hpp	Tue Jan 28 19:37:26 2014 +0100
+++ b/src/share/vm/graal/graalGlobals.hpp	Wed Jan 29 12:19:03 2014 +0100
@@ -55,6 +55,12 @@
   product(intx, TraceGraal, 0,                                              \
           "Trace level for Graal")                                          \
                                                                             \
+  product(intx, GraalCounterSize, 0,                                        \
+          "Reserved size for benchmark counters")                           \
+                                                                            \
+  product(bool, GraalCountersExcludeCompiler, true,                         \
+          "Exclude Graal compiler threads from benchmark counters")         \
+                                                                            \
   product(bool, GraalDeferredInitBarriers, true,                            \
           "Defer write barriers of young objects")                          \
                                                                             \
--- a/src/share/vm/runtime/thread.cpp	Tue Jan 28 19:37:26 2014 +0100
+++ b/src/share/vm/runtime/thread.cpp	Wed Jan 29 12:19:03 2014 +0100
@@ -1418,31 +1418,27 @@
 
 #ifdef GRAAL
 
-#if GRAAL_COUNTERS_SIZE > 0
-jlong JavaThread::_graal_old_thread_counters[GRAAL_COUNTERS_SIZE];
+jlong* JavaThread::_graal_old_thread_counters;
 
 bool graal_counters_include(oop threadObj) {
-  return !GRAAL_COUNTERS_EXCLUDE_COMPILER_THREADS || threadObj == NULL || threadObj->klass() != SystemDictionary::CompilerThread_klass();
+  return !GraalCountersExcludeCompiler || threadObj == NULL || threadObj->klass() != SystemDictionary::CompilerThread_klass();
 }
 
 void JavaThread::collect_counters(typeArrayOop array) {
-  MutexLocker tl(Threads_lock);
-  for (int i = 0; i < array->length(); i++) {
-    array->long_at_put(i, _graal_old_thread_counters[i]);
-  }
-  for (JavaThread* tp = Threads::first(); tp != NULL; tp = tp->next()) {
-    if (graal_counters_include(tp->threadObj())) {
-      for (int i = 0; i < array->length(); i++) {
-        array->long_at_put(i, array->long_at(i) + tp->_graal_counters[i]);
+  if (GraalCounterSize > 0) {
+    MutexLocker tl(Threads_lock);
+    for (int i = 0; i < array->length(); i++) {
+      array->long_at_put(i, _graal_old_thread_counters[i]);
+    }
+    for (JavaThread* tp = Threads::first(); tp != NULL; tp = tp->next()) {
+      if (graal_counters_include(tp->threadObj())) {
+        for (int i = 0; i < array->length(); i++) {
+          array->long_at_put(i, array->long_at(i) + tp->_graal_counters[i]);
+        }
       }
     }
   }
 }
-#else
-void JavaThread::collect_counters(typeArrayOop array) {
-  // empty
-}
-#endif // GRAAL_COUNTERS_SIZE > 0
 
 #endif // GRAAL
 
@@ -1486,11 +1482,12 @@
   _graal_alternate_call_target = NULL;
   _graal_implicit_exception_pc = NULL;
   _graal_compiling = false;
-#if GRAAL_COUNTERS_SIZE > 0
-  for (int i = 0; i < GRAAL_COUNTERS_SIZE; i++) {
-    _graal_counters[i] = 0;
+  if (GraalCounterSize > 0) {
+    _graal_counters = NEW_C_HEAP_ARRAY(jlong, GraalCounterSize, mtInternal);
+    memset(_graal_counters, 0, sizeof(jlong) * GraalCounterSize);
+  } else {
+    _graal_counters = NULL;
   }
-#endif // GRAAL_COUNTER_SIZE > 0
 #endif // GRAAL
   (void)const_cast<oop&>(_exception_oop = NULL);
   _exception_pc  = 0;
@@ -1680,13 +1677,14 @@
   if (_thread_profiler != NULL) delete _thread_profiler;
   if (_thread_stat != NULL) delete _thread_stat;
 
-#if defined(GRAAL) && (GRAAL_COUNTERS_SIZE > 0)
-  if (graal_counters_include(threadObj())) {
-    for (int i = 0; i < GRAAL_COUNTERS_SIZE; i++) {
+#ifdef GRAAL
+  if (GraalCounterSize > 0 && graal_counters_include(threadObj())) {
+    for (int i = 0; i < GraalCounterSize; i++) {
       _graal_old_thread_counters[i] += _graal_counters[i];
     }
+    FREE_C_HEAP_ARRAY(jlong, _graal_counters, mtInternal);
   }
-#endif
+#endif // GRAAL
 }
 
 
@@ -3458,6 +3456,15 @@
   // Initialize global data structures and create system classes in heap
   vm_init_globals();
 
+#ifdef GRAAL
+  if (GraalCounterSize > 0) {
+    JavaThread::_graal_old_thread_counters = NEW_C_HEAP_ARRAY(jlong, GraalCounterSize, mtInternal);
+    memset(JavaThread::_graal_old_thread_counters, 0, sizeof(jlong) * GraalCounterSize);
+  } else {
+    JavaThread::_graal_old_thread_counters = NULL;
+  }
+#endif // GRAAL
+
   // Attach the main thread to this os thread
   JavaThread* main_thread = new JavaThread();
   main_thread->set_thread_state(_thread_in_vm);
@@ -4109,6 +4116,12 @@
 
   delete thread;
 
+#ifdef GRAAL
+  if (GraalCounterSize > 0) {
+    FREE_C_HEAP_ARRAY(jlong, JavaThread::_graal_old_thread_counters, mtInternal);
+  }
+#endif // GRAAL
+
   // exit_globals() will delete tty
   exit_globals();
 
--- a/src/share/vm/runtime/thread.hpp	Tue Jan 28 19:37:26 2014 +0100
+++ b/src/share/vm/runtime/thread.hpp	Wed Jan 29 12:19:03 2014 +0100
@@ -922,16 +922,10 @@
   address   _graal_implicit_exception_pc;  // pc at which the most recent implicit exception occurred
   bool      _graal_compiling;
 
-  // number of counters, increase as needed. 0 == disabled
-#define GRAAL_COUNTERS_SIZE (0)
-#define GRAAL_COUNTERS_EXCLUDE_COMPILER_THREADS (true)
-
-#if GRAAL_COUNTERS_SIZE > 0
-  jlong     _graal_counters[GRAAL_COUNTERS_SIZE];
-  static jlong _graal_old_thread_counters[GRAAL_COUNTERS_SIZE];
-#endif // GRAAL_COUNTERS_SIZE > 0
+  jlong*    _graal_counters;
 
  public:
+  static jlong* _graal_old_thread_counters;
   static void collect_counters(typeArrayOop array);
  private:
 #endif // GRAAL
@@ -1394,11 +1388,7 @@
 #ifdef GRAAL
   static ByteSize graal_alternate_call_target_offset() { return byte_offset_of(JavaThread, _graal_alternate_call_target); }
   static ByteSize graal_implicit_exception_pc_offset() { return byte_offset_of(JavaThread, _graal_implicit_exception_pc); }
-#if GRAAL_COUNTERS_SIZE > 0
   static ByteSize graal_counters_offset()        { return byte_offset_of(JavaThread, _graal_counters      ); }
-#else
-  static ByteSize graal_counters_offset()        { return in_ByteSize(0); }
-#endif // GRAAL_COUNTERS_SIZE > 0
 #endif // GRAAL
   static ByteSize exception_oop_offset()         { return byte_offset_of(JavaThread, _exception_oop       ); }
   static ByteSize exception_pc_offset()          { return byte_offset_of(JavaThread, _exception_pc        ); }