changeset 22755:a48f9b3e01f5

Merge with f74225bf6671d84f00ccf48c3a01040bfa1f6b3b
author Michael Van De Vanter <michael.van.de.vanter@oracle.com>
date Sat, 03 Oct 2015 17:25:59 -0700
parents 1fc7ee8c9443 (current diff) f74225bf6671 (diff)
children c2ce8dd9be05
files
diffstat 19 files changed, 406 insertions(+), 54 deletions(-) [+]
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/UnbalancedMonitorsTest.java	Sat Oct 03 17:25:59 2015 -0700
@@ -0,0 +1,312 @@
+/*
+ * Copyright (c) 2015, 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 jdk.internal.jvmci.code.BailoutException;
+import jdk.internal.jvmci.meta.ResolvedJavaMethod;
+import jdk.internal.org.objectweb.asm.ClassWriter;
+import jdk.internal.org.objectweb.asm.Label;
+import jdk.internal.org.objectweb.asm.MethodVisitor;
+import jdk.internal.org.objectweb.asm.Opcodes;
+
+import org.junit.Test;
+
+import com.oracle.graal.graphbuilderconf.GraphBuilderConfiguration;
+import com.oracle.graal.graphbuilderconf.GraphBuilderConfiguration.Plugins;
+import com.oracle.graal.graphbuilderconf.InvocationPlugins;
+import com.oracle.graal.java.GraphBuilderPhase;
+import com.oracle.graal.nodes.StructuredGraph;
+import com.oracle.graal.nodes.StructuredGraph.AllowAssumptions;
+import com.oracle.graal.phases.OptimisticOptimizations;
+
+/**
+ * Exercise handling of unbalanced monitor operations by the parser. Algorithmically Graal assumes
+ * that locks are statically block structured but that isn't something enforced by the bytecodes. In
+ * HotSpot a dataflow is performed to ensure they are properly structured and methods with
+ * unstructured locking aren't compiled and fall back to the interpreter. Having the Graal parser
+ * handle this directly is simplifying for targets of Graal since they don't have to provide a data
+ * flow that checks this property.
+ */
+public class UnbalancedMonitorsTest extends GraalCompilerTest implements Opcodes {
+    private static final String NAME = "com.oracle.graal.compiler.test.UnbalancedMonitorsTest$UnbalancedMonitors";
+    private static AsmLoader LOADER = new AsmLoader(UnbalancedMonitorsTest.class.getClassLoader());
+
+    @Test
+    public void runWrongOrder() throws Exception {
+        checkForBailout("wrongOrder");
+    }
+
+    @Test
+    public void runTooFewExits() throws Exception {
+        checkForBailout("tooFewExits");
+    }
+
+    @Test
+    public void runTooManyExits() throws Exception {
+        checkForBailout("tooManyExits");
+    }
+
+    @Test
+    public void runTooFewExitsExceptional() throws Exception {
+        checkForBailout("tooFewExitsExceptional");
+    }
+
+    @Test
+    public void runTooManyExitsExceptional() throws Exception {
+        checkForBailout("tooManyExitsExceptional");
+    }
+
+    private void checkForBailout(String name) throws ClassNotFoundException {
+        ResolvedJavaMethod method = getResolvedJavaMethod(LOADER.findClass(NAME), name);
+        try {
+            StructuredGraph graph = new StructuredGraph(method, AllowAssumptions.NO);
+            GraphBuilderConfiguration graphBuilderConfig = GraphBuilderConfiguration.getEagerDefault(new Plugins(new InvocationPlugins(getMetaAccess())));
+            graphBuilderConfig = graphBuilderConfig.withOmitAllExceptionEdges(false);
+            OptimisticOptimizations optimisticOpts = OptimisticOptimizations.NONE;
+
+            GraphBuilderPhase.Instance graphBuilder = new GraphBuilderPhase.Instance(getMetaAccess(), getProviders().getStampProvider(), null, graphBuilderConfig, optimisticOpts, null);
+            graphBuilder.apply(graph);
+        } catch (BailoutException e) {
+            if (e.getMessage().contains("unbalanced monitors")) {
+                return;
+            }
+            throw e;
+        }
+        assertTrue("should have bailed out", false);
+    }
+
+    // @formatter:off
+    // Template class used with Bytecode Outline to generate ASM code
+    //    public static class UnbalancedMonitors {
+    //
+    //        public UnbalancedMonitors() {
+    //        }
+    //
+    //        public Object wrongOrder(Object a, Object b) {
+    //            synchronized (a) {
+    //                synchronized (b) {
+    //                    return b;
+    //                }
+    //            }
+    //        }
+    //
+    //        public Object tooFewExits(Object a, Object b) {
+    //            synchronized (a) {
+    //                synchronized (b) {
+    //                    return b;
+    //                }
+    //            }
+    //        }
+    //
+    //        public boolean tooFewExitsExceptional(Object a, Object b) {
+    //            synchronized (a) {
+    //                synchronized (b) {
+    //                    return b.equals(a);
+    //                }
+    //            }
+    //        }
+    //    }
+    // @formatter:on
+
+    public static byte[] generateClass() {
+
+        ClassWriter cw = new ClassWriter(0);
+
+        cw.visit(52, ACC_SUPER | ACC_PUBLIC, "com/oracle/graal/compiler/test/UnbalancedMonitorsTest$UnbalancedMonitors", null, "java/lang/Object", null);
+
+        cw.visitSource("UnbalancedMonitorsTest.java", null);
+
+        cw.visitInnerClass("com/oracle/graal/compiler/test/UnbalancedMonitorsTest$UnbalancedMonitors", "com/oracle/graal/compiler/test/UnbalancedMonitorsTest", "UnbalancedMonitors", ACC_STATIC);
+
+        visitConstructor(cw);
+        visitWrongOrder(cw);
+        visitBlockStructured(cw, true, false);
+        visitBlockStructured(cw, true, true);
+        visitBlockStructured(cw, false, false);
+        visitBlockStructured(cw, false, true);
+        cw.visitEnd();
+
+        return cw.toByteArray();
+    }
+
+    private static void visitBlockStructured(ClassWriter cw, boolean normalReturnError, boolean tooMany) {
+        String name = (tooMany ? "tooMany" : "tooFew") + "Exits" + (normalReturnError ? "" : "Exceptional");
+        // Generate too many or too few exits down the either the normal or exceptional return paths
+        int exceptionalExitCount = normalReturnError ? 1 : (tooMany ? 2 : 0);
+        int normalExitCount = normalReturnError ? (tooMany ? 2 : 0) : 1;
+        MethodVisitor mv;
+        mv = cw.visitMethod(ACC_PUBLIC, name, "(Ljava/lang/Object;Ljava/lang/Object;)Z", null, null);
+        mv.visitCode();
+        Label l0 = new Label();
+        Label l1 = new Label();
+        Label l2 = new Label();
+        mv.visitTryCatchBlock(l0, l1, l2, null);
+        Label l3 = new Label();
+        mv.visitTryCatchBlock(l2, l3, l2, null);
+        Label l4 = new Label();
+        Label l5 = new Label();
+        Label l6 = new Label();
+        mv.visitTryCatchBlock(l4, l5, l6, null);
+        Label l7 = new Label();
+        mv.visitTryCatchBlock(l2, l7, l6, null);
+        Label l8 = new Label();
+        mv.visitLabel(l8);
+        mv.visitVarInsn(ALOAD, 1);
+        mv.visitInsn(DUP);
+        mv.visitVarInsn(ASTORE, 3);
+        mv.visitInsn(MONITORENTER);
+        mv.visitLabel(l4);
+        mv.visitVarInsn(ALOAD, 2);
+        mv.visitInsn(DUP);
+        mv.visitVarInsn(ASTORE, 4);
+        mv.visitInsn(MONITORENTER);
+        mv.visitLabel(l0);
+        mv.visitVarInsn(ALOAD, 2);
+        mv.visitVarInsn(ALOAD, 1);
+        mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Object", "equals", "(Ljava/lang/Object;)Z", false);
+        mv.visitVarInsn(ALOAD, 4);
+        mv.visitInsn(MONITOREXIT);
+        mv.visitLabel(l1);
+        for (int i = 0; i < normalExitCount; i++) {
+            mv.visitVarInsn(ALOAD, 3);
+            mv.visitInsn(MONITOREXIT);
+        }
+        mv.visitLabel(l5);
+        mv.visitInsn(IRETURN);
+        mv.visitLabel(l2);
+        mv.visitFrame(Opcodes.F_FULL, 5, new Object[]{"com/oracle/graal/compiler/test/UnbalancedMonitorsTest$UnbalancedMonitors", "java/lang/Object", "java/lang/Object", "java/lang/Object",
+                        "java/lang/Object"}, 1, new Object[]{"java/lang/Throwable"});
+        mv.visitVarInsn(ALOAD, 4);
+        mv.visitInsn(MONITOREXIT);
+        mv.visitLabel(l3);
+        mv.visitInsn(ATHROW);
+        mv.visitLabel(l6);
+        mv.visitFrame(Opcodes.F_FULL, 4, new Object[]{"com/oracle/graal/compiler/test/UnbalancedMonitorsTest$UnbalancedMonitors", "java/lang/Object", "java/lang/Object", "java/lang/Object"}, 1,
+                        new Object[]{"java/lang/Throwable"});
+        for (int i = 0; i < exceptionalExitCount; i++) {
+            mv.visitVarInsn(ALOAD, 3);
+            mv.visitInsn(MONITOREXIT);
+        }
+        mv.visitLabel(l7);
+        mv.visitInsn(ATHROW);
+        Label l9 = new Label();
+        mv.visitLabel(l9);
+        mv.visitMaxs(2, 5);
+        mv.visitEnd();
+    }
+
+    private static void visitWrongOrder(ClassWriter cw) {
+        MethodVisitor mv;
+        mv = cw.visitMethod(ACC_PUBLIC, "wrongOrder", "(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;", null, null);
+        mv.visitCode();
+        Label l0 = new Label();
+        Label l1 = new Label();
+        Label l2 = new Label();
+        mv.visitTryCatchBlock(l0, l1, l2, null);
+        Label l3 = new Label();
+        mv.visitTryCatchBlock(l2, l3, l2, null);
+        Label l4 = new Label();
+        Label l5 = new Label();
+        Label l6 = new Label();
+        mv.visitTryCatchBlock(l4, l5, l6, null);
+        Label l7 = new Label();
+        mv.visitTryCatchBlock(l2, l7, l6, null);
+        Label l8 = new Label();
+        mv.visitLabel(l8);
+        mv.visitVarInsn(ALOAD, 1);
+        mv.visitInsn(DUP);
+        mv.visitVarInsn(ASTORE, 3);
+        mv.visitInsn(MONITORENTER);
+        mv.visitLabel(l4);
+        mv.visitVarInsn(ALOAD, 2);
+        mv.visitInsn(DUP);
+        mv.visitVarInsn(ASTORE, 4);
+        mv.visitInsn(MONITORENTER);
+        mv.visitLabel(l0);
+        mv.visitVarInsn(ALOAD, 2);
+        mv.visitVarInsn(ALOAD, 3);
+        mv.visitInsn(MONITOREXIT);
+        mv.visitLabel(l1);
+        // Swapped exit order with exit above
+        mv.visitVarInsn(ALOAD, 4);
+        mv.visitInsn(MONITOREXIT);
+        mv.visitLabel(l5);
+        mv.visitInsn(ARETURN);
+        mv.visitLabel(l2);
+        mv.visitFrame(Opcodes.F_FULL, 5, new Object[]{"com/oracle/graal/compiler/test/UnbalancedMonitorsTest$UnbalancedMonitors", "java/lang/Object", "java/lang/Object", "java/lang/Object",
+                        "java/lang/Object"}, 1, new Object[]{"java/lang/Throwable"});
+        mv.visitVarInsn(ALOAD, 4);
+        mv.visitInsn(MONITOREXIT);
+        mv.visitLabel(l3);
+        mv.visitInsn(ATHROW);
+        mv.visitLabel(l6);
+        mv.visitFrame(Opcodes.F_FULL, 4, new Object[]{"com/oracle/graal/compiler/test/UnbalancedMonitorsTest$UnbalancedMonitors", "java/lang/Object", "java/lang/Object", "java/lang/Object"}, 1,
+                        new Object[]{"java/lang/Throwable"});
+        mv.visitVarInsn(ALOAD, 3);
+        mv.visitInsn(MONITOREXIT);
+        mv.visitLabel(l7);
+        mv.visitInsn(ATHROW);
+        Label l9 = new Label();
+        mv.visitLabel(l9);
+        mv.visitMaxs(2, 5);
+        mv.visitEnd();
+    }
+
+    private static void visitConstructor(ClassWriter cw) {
+        MethodVisitor mv;
+        mv = cw.visitMethod(ACC_PUBLIC, "<init>", "()V", null, null);
+        mv.visitCode();
+        Label l0 = new Label();
+        mv.visitLabel(l0);
+        mv.visitVarInsn(ALOAD, 0);
+        mv.visitMethodInsn(INVOKESPECIAL, "java/lang/Object", "<init>", "()V", false);
+        Label l1 = new Label();
+        mv.visitLabel(l1);
+        mv.visitInsn(RETURN);
+        Label l2 = new Label();
+        mv.visitLabel(l2);
+        mv.visitMaxs(1, 1);
+        mv.visitEnd();
+    }
+
+    public static class AsmLoader extends ClassLoader {
+        Class<?> loaded;
+
+        public AsmLoader(ClassLoader parent) {
+            super(parent);
+        }
+
+        @Override
+        protected Class<?> findClass(String name) throws ClassNotFoundException {
+            if (name.equals(NAME)) {
+                if (loaded != null) {
+                    return loaded;
+                }
+                byte[] bytes = generateClass();
+                return (loaded = defineClass(name, bytes, 0, bytes.length));
+            } else {
+                return super.findClass(name);
+            }
+        }
+    }
+}
--- a/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotBackendFactory.java	Sat Oct 03 16:58:15 2015 -0700
+++ b/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotBackendFactory.java	Sat Oct 03 17:25:59 2015 -0700
@@ -40,6 +40,7 @@
 import jdk.internal.jvmci.hotspot.HotSpotMetaAccessProvider;
 import jdk.internal.jvmci.hotspot.HotSpotVMConfig;
 import jdk.internal.jvmci.inittimer.InitTimer;
+import jdk.internal.jvmci.meta.ConstantReflectionProvider;
 import jdk.internal.jvmci.meta.Value;
 import jdk.internal.jvmci.runtime.JVMCIBackend;
 import jdk.internal.jvmci.service.ServiceProvider;
@@ -108,13 +109,13 @@
                 foreignCalls = createForeignCalls(jvmciRuntime, graalRuntime, metaAccess, codeCache, nativeABICallerSaveRegisters);
             }
             try (InitTimer rt = timer("create Lowerer provider")) {
-                lowerer = createLowerer(graalRuntime, metaAccess, foreignCalls, registers, target);
+                lowerer = createLowerer(graalRuntime, metaAccess, foreignCalls, registers, constantReflection, target);
             }
             HotSpotStampProvider stampProvider = new HotSpotStampProvider();
             Providers p = new Providers(metaAccess, codeCache, constantReflection, foreignCalls, lowerer, null, stampProvider);
 
             try (InitTimer rt = timer("create SnippetReflection provider")) {
-                snippetReflection = createSnippetReflection(graalRuntime);
+                snippetReflection = createSnippetReflection(graalRuntime, constantReflection);
             }
             try (InitTimer rt = timer("create Replacements provider")) {
                 replacements = createReplacements(config, p, snippetReflection);
@@ -167,13 +168,13 @@
                         registers.getHeapBaseRegister()));
     }
 
-    protected HotSpotSnippetReflectionProvider createSnippetReflection(HotSpotGraalRuntimeProvider runtime) {
-        return new HotSpotSnippetReflectionProvider(runtime);
+    protected HotSpotSnippetReflectionProvider createSnippetReflection(HotSpotGraalRuntimeProvider runtime, ConstantReflectionProvider constantReflection) {
+        return new HotSpotSnippetReflectionProvider(runtime, constantReflection);
     }
 
     protected HotSpotLoweringProvider createLowerer(HotSpotGraalRuntimeProvider runtime, HotSpotMetaAccessProvider metaAccess, HotSpotForeignCallsProvider foreignCalls,
-                    HotSpotRegistersProvider registers, TargetDescription target) {
-        return new AMD64HotSpotLoweringProvider(runtime, metaAccess, foreignCalls, registers, target);
+                    HotSpotRegistersProvider registers, ConstantReflectionProvider constantReflection, TargetDescription target) {
+        return new AMD64HotSpotLoweringProvider(runtime, metaAccess, foreignCalls, registers, constantReflection, target);
     }
 
     protected Value[] createNativeABICallerSaveRegisters(HotSpotVMConfig config, RegisterConfig regConfig) {
--- a/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotLIRGenerator.java	Sat Oct 03 16:58:15 2015 -0700
+++ b/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotLIRGenerator.java	Sat Oct 03 17:25:59 2015 -0700
@@ -338,6 +338,18 @@
     }
 
     /**
+     * Allocate a stack slot for saving a register.
+     */
+    protected StackSlotValue allocateSaveRegisterLocation(Register register) {
+        PlatformKind kind = target().arch.getLargestStorableKind(register.getRegisterCategory());
+        if (kind.getVectorLength() > 1) {
+            // we don't use vector registers, so there is no need to save them
+            kind = AMD64Kind.DOUBLE;
+        }
+        return getResult().getFrameMapBuilder().allocateSpillSlot(LIRKind.value(kind));
+    }
+
+    /**
      * Adds a node to the graph that saves all allocatable registers to the stack.
      *
      * @param supportsRemove determines if registers can be pruned
--- a/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotLoweringProvider.java	Sat Oct 03 16:58:15 2015 -0700
+++ b/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotLoweringProvider.java	Sat Oct 03 17:25:59 2015 -0700
@@ -24,6 +24,7 @@
 
 import jdk.internal.jvmci.code.TargetDescription;
 import jdk.internal.jvmci.hotspot.HotSpotVMConfig;
+import jdk.internal.jvmci.meta.ConstantReflectionProvider;
 import jdk.internal.jvmci.meta.MetaAccessProvider;
 
 import com.oracle.graal.compiler.common.spi.ForeignCallsProvider;
@@ -41,8 +42,8 @@
     private AMD64ConvertSnippets.Templates convertSnippets;
 
     public AMD64HotSpotLoweringProvider(HotSpotGraalRuntimeProvider runtime, MetaAccessProvider metaAccess, ForeignCallsProvider foreignCalls, HotSpotRegistersProvider registers,
-                    TargetDescription target) {
-        super(runtime, metaAccess, foreignCalls, registers, target);
+                    ConstantReflectionProvider constantReflection, TargetDescription target) {
+        super(runtime, metaAccess, foreignCalls, registers, constantReflection, target);
     }
 
     @Override
--- a/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotBackendFactory.java	Sat Oct 03 16:58:15 2015 -0700
+++ b/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotBackendFactory.java	Sat Oct 03 17:25:59 2015 -0700
@@ -36,6 +36,7 @@
 import jdk.internal.jvmci.hotspot.HotSpotJVMCIRuntimeProvider;
 import jdk.internal.jvmci.hotspot.HotSpotMetaAccessProvider;
 import jdk.internal.jvmci.hotspot.HotSpotVMConfig;
+import jdk.internal.jvmci.meta.ConstantReflectionProvider;
 import jdk.internal.jvmci.meta.Value;
 import jdk.internal.jvmci.runtime.JVMCIBackend;
 import jdk.internal.jvmci.service.ServiceProvider;
@@ -86,10 +87,10 @@
         HotSpotConstantReflectionProvider constantReflection = new HotSpotGraalConstantReflectionProvider(jvmciRuntime);
         Value[] nativeABICallerSaveRegisters = createNativeABICallerSaveRegisters(config, codeCache.getRegisterConfig());
         HotSpotForeignCallsProvider foreignCalls = new SPARCHotSpotForeignCallsProvider(jvmciRuntime, runtime, metaAccess, codeCache, nativeABICallerSaveRegisters);
-        LoweringProvider lowerer = createLowerer(runtime, metaAccess, foreignCalls, registers, target);
+        LoweringProvider lowerer = createLowerer(runtime, metaAccess, foreignCalls, registers, constantReflection, target);
         HotSpotStampProvider stampProvider = new HotSpotStampProvider();
         Providers p = new Providers(metaAccess, codeCache, constantReflection, foreignCalls, lowerer, null, stampProvider);
-        HotSpotSnippetReflectionProvider snippetReflection = new HotSpotSnippetReflectionProvider(runtime);
+        HotSpotSnippetReflectionProvider snippetReflection = new HotSpotSnippetReflectionProvider(runtime, constantReflection);
         HotSpotReplacementsImpl replacements = new HotSpotReplacementsImpl(p, snippetReflection, config, target);
         HotSpotWordTypes wordTypes = new HotSpotWordTypes(metaAccess, target.wordJavaKind);
         Plugins plugins = createGraphBuilderPlugins(config, metaAccess, constantReflection, foreignCalls, stampProvider, snippetReflection, replacements, wordTypes);
@@ -117,8 +118,8 @@
     }
 
     protected HotSpotLoweringProvider createLowerer(HotSpotGraalRuntimeProvider runtime, HotSpotMetaAccessProvider metaAccess, HotSpotForeignCallsProvider foreignCalls,
-                    HotSpotRegistersProvider registers, TargetDescription target) {
-        return new SPARCHotSpotLoweringProvider(runtime, metaAccess, foreignCalls, registers, target);
+                    HotSpotRegistersProvider registers, ConstantReflectionProvider constantReflection, TargetDescription target) {
+        return new SPARCHotSpotLoweringProvider(runtime, metaAccess, foreignCalls, registers, constantReflection, target);
     }
 
     protected HotSpotRegistersProvider createRegisters() {
--- a/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotLoweringProvider.java	Sat Oct 03 16:58:15 2015 -0700
+++ b/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotLoweringProvider.java	Sat Oct 03 17:25:59 2015 -0700
@@ -23,6 +23,7 @@
 package com.oracle.graal.hotspot.sparc;
 
 import jdk.internal.jvmci.code.TargetDescription;
+import jdk.internal.jvmci.meta.ConstantReflectionProvider;
 import jdk.internal.jvmci.meta.MetaAccessProvider;
 
 import com.oracle.graal.compiler.common.spi.ForeignCallsProvider;
@@ -36,8 +37,8 @@
 public class SPARCHotSpotLoweringProvider extends DefaultHotSpotLoweringProvider {
 
     public SPARCHotSpotLoweringProvider(HotSpotGraalRuntimeProvider runtime, MetaAccessProvider metaAccess, ForeignCallsProvider foreignCalls, HotSpotRegistersProvider registers,
-                    TargetDescription target) {
-        super(runtime, metaAccess, foreignCalls, registers, target);
+                    ConstantReflectionProvider constantReflection, TargetDescription target) {
+        super(runtime, metaAccess, foreignCalls, registers, constantReflection, target);
     }
 
     @Override
--- a/graal/com.oracle.graal.hotspot.test/src/com/oracle/graal/hotspot/test/AheadOfTimeCompilationTest.java	Sat Oct 03 16:58:15 2015 -0700
+++ b/graal/com.oracle.graal.hotspot.test/src/com/oracle/graal/hotspot/test/AheadOfTimeCompilationTest.java	Sat Oct 03 17:25:59 2015 -0700
@@ -30,8 +30,8 @@
 import jdk.internal.jvmci.code.CallingConvention;
 import jdk.internal.jvmci.code.CallingConvention.Type;
 import jdk.internal.jvmci.code.CompilationResult;
-import jdk.internal.jvmci.hotspot.HotSpotObjectConstantImpl;
 import jdk.internal.jvmci.hotspot.HotSpotResolvedObjectType;
+import jdk.internal.jvmci.meta.JavaConstant;
 import jdk.internal.jvmci.meta.JavaKind;
 import jdk.internal.jvmci.meta.ResolvedJavaMethod;
 import jdk.internal.jvmci.options.OptionValue;
@@ -119,9 +119,8 @@
 
         NodeIterable<ConstantNode> filter = getConstantNodes(result);
         assertDeepEquals(1, filter.count());
-        HotSpotObjectConstantImpl c = (HotSpotObjectConstantImpl) filter.first().asConstant();
-        Assert.assertEquals(Class.class, c.getObjectClass());
-        Assert.assertTrue(c.isEqualTo(AheadOfTimeCompilationTest.class));
+        JavaConstant c = filter.first().asJavaConstant();
+        Assert.assertEquals(getSnippetReflection().asObject(Class.class, c), AheadOfTimeCompilationTest.class);
 
         assertDeepEquals(0, result.getNodes().filter(FloatingReadNode.class).count());
         assertDeepEquals(0, result.getNodes().filter(ReadNode.class).count());
@@ -148,9 +147,8 @@
         StructuredGraph result = compile("getPrimitiveClassObject", false);
         NodeIterable<ConstantNode> filter = getConstantNodes(result);
         assertDeepEquals(1, filter.count());
-        HotSpotObjectConstantImpl c = (HotSpotObjectConstantImpl) filter.first().asConstant();
-        Assert.assertEquals(Class.class, c.getObjectClass());
-        Assert.assertTrue(c.isEqualTo(Integer.TYPE));
+        JavaConstant c = filter.first().asJavaConstant();
+        Assert.assertEquals(getSnippetReflection().asObject(Class.class, c), Integer.TYPE);
 
         assertDeepEquals(0, result.getNodes().filter(FloatingReadNode.class).count());
         assertDeepEquals(0, result.getNodes().filter(ReadNode.class).count());
@@ -176,9 +174,8 @@
 
         NodeIterable<ConstantNode> filter = getConstantNodes(result);
         assertDeepEquals(1, filter.count());
-        HotSpotObjectConstantImpl c = (HotSpotObjectConstantImpl) filter.first().asConstant();
-        Assert.assertEquals(String.class, c.getObjectClass());
-        Assert.assertTrue(c.isEqualTo("test string"));
+        JavaConstant c = filter.first().asJavaConstant();
+        Assert.assertEquals(getSnippetReflection().asObject(String.class, c), "test string");
 
         assertDeepEquals(0, result.getNodes().filter(FloatingReadNode.class).count());
         assertDeepEquals(0, result.getNodes().filter(ReadNode.class).count());
@@ -210,8 +207,8 @@
         ConstantNode constant = getConstantNodes(result).first();
         assertDeepEquals(JavaKind.Object, constant.getStackKind());
 
-        HotSpotObjectConstantImpl c = (HotSpotObjectConstantImpl) constant.asConstant();
-        Assert.assertTrue(c.isEqualTo(Boolean.TRUE));
+        JavaConstant c = constant.asJavaConstant();
+        Assert.assertEquals(getSnippetReflection().asObject(Boolean.class, c), Boolean.TRUE);
     }
 
     @SuppressWarnings("try")
--- a/graal/com.oracle.graal.hotspot.test/src/com/oracle/graal/hotspot/test/InstalledCodeExecuteHelperTest.java	Sat Oct 03 16:58:15 2015 -0700
+++ b/graal/com.oracle.graal.hotspot.test/src/com/oracle/graal/hotspot/test/InstalledCodeExecuteHelperTest.java	Sat Oct 03 17:25:59 2015 -0700
@@ -25,7 +25,6 @@
 import static java.lang.reflect.Modifier.isStatic;
 import jdk.internal.jvmci.code.InvalidInstalledCodeException;
 import jdk.internal.jvmci.hotspot.HotSpotInstalledCode;
-import jdk.internal.jvmci.hotspot.HotSpotObjectConstantImpl;
 import jdk.internal.jvmci.meta.JavaConstant;
 import jdk.internal.jvmci.meta.JavaType;
 import jdk.internal.jvmci.meta.ResolvedJavaMethod;
@@ -84,7 +83,7 @@
             assert parameterTypes.length == args.length;
             for (int i = 0; i < argsToBind.length; i++) {
                 ParameterNode param = graph.getParameter(i);
-                JavaConstant c = HotSpotObjectConstantImpl.forBoxedValue(parameterTypes[i].getJavaKind(), argsToBind[i]);
+                JavaConstant c = getSnippetReflection().forBoxed(parameterTypes[i].getJavaKind(), argsToBind[i]);
                 ConstantNode replacement = ConstantNode.forConstant(c, getMetaAccess(), graph);
                 param.replaceAtUsages(replacement);
             }
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/DefaultHotSpotLoweringProvider.java	Sat Oct 03 16:58:15 2015 -0700
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/DefaultHotSpotLoweringProvider.java	Sat Oct 03 17:25:59 2015 -0700
@@ -42,10 +42,10 @@
 import jdk.internal.jvmci.code.CallingConvention;
 import jdk.internal.jvmci.code.TargetDescription;
 import jdk.internal.jvmci.common.JVMCIError;
-import jdk.internal.jvmci.hotspot.HotSpotObjectConstantImpl;
 import jdk.internal.jvmci.hotspot.HotSpotResolvedJavaField;
 import jdk.internal.jvmci.hotspot.HotSpotResolvedJavaMethod;
 import jdk.internal.jvmci.hotspot.HotSpotVMConfig;
+import jdk.internal.jvmci.meta.ConstantReflectionProvider;
 import jdk.internal.jvmci.meta.JavaConstant;
 import jdk.internal.jvmci.meta.JavaKind;
 import jdk.internal.jvmci.meta.JavaType;
@@ -155,6 +155,7 @@
     protected final HotSpotGraalRuntimeProvider runtime;
     protected final ForeignCallsProvider foreignCalls;
     protected final HotSpotRegistersProvider registers;
+    protected final ConstantReflectionProvider constantReflection;
 
     protected CheckCastDynamicSnippets.Templates checkcastDynamicSnippets;
     protected InstanceOfSnippets.Templates instanceofSnippets;
@@ -167,11 +168,12 @@
     protected ArrayCopySnippets.Templates arraycopySnippets;
 
     public DefaultHotSpotLoweringProvider(HotSpotGraalRuntimeProvider runtime, MetaAccessProvider metaAccess, ForeignCallsProvider foreignCalls, HotSpotRegistersProvider registers,
-                    TargetDescription target) {
+                    ConstantReflectionProvider constantReflection, TargetDescription target) {
         super(metaAccess, target);
         this.runtime = runtime;
         this.foreignCalls = foreignCalls;
         this.registers = registers;
+        this.constantReflection = constantReflection;
     }
 
     public void initialize(HotSpotProviders providers, HotSpotVMConfig config) {
@@ -532,7 +534,7 @@
                 } else {
                     throw JVMCIError.shouldNotReachHere();
                 }
-                FloatingNode exceptionNode = ConstantNode.forConstant(HotSpotObjectConstantImpl.forObject(exception), metaAccess, graph);
+                FloatingNode exceptionNode = ConstantNode.forConstant(constantReflection.forObject(exception), metaAccess, graph);
                 graph.replaceFixedWithFloating(node, exceptionNode);
 
             } else {
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotSnippetReflectionProvider.java	Sat Oct 03 16:58:15 2015 -0700
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotSnippetReflectionProvider.java	Sat Oct 03 17:25:59 2015 -0700
@@ -24,8 +24,8 @@
 
 import static jdk.internal.jvmci.hotspot.HotSpotVMConfig.config;
 import jdk.internal.jvmci.hotspot.HotSpotObjectConstant;
-import jdk.internal.jvmci.hotspot.HotSpotObjectConstantImpl;
 import jdk.internal.jvmci.hotspot.HotSpotVMConfig;
+import jdk.internal.jvmci.meta.ConstantReflectionProvider;
 import jdk.internal.jvmci.meta.JavaConstant;
 import jdk.internal.jvmci.meta.JavaKind;
 import jdk.internal.jvmci.meta.MetaAccessProvider;
@@ -37,14 +37,16 @@
 public class HotSpotSnippetReflectionProvider implements SnippetReflectionProvider {
 
     private final HotSpotGraalRuntimeProvider runtime;
+    private final ConstantReflectionProvider constantReflection;
 
-    public HotSpotSnippetReflectionProvider(HotSpotGraalRuntimeProvider runtime) {
+    public HotSpotSnippetReflectionProvider(HotSpotGraalRuntimeProvider runtime, ConstantReflectionProvider constantReflection) {
         this.runtime = runtime;
+        this.constantReflection = constantReflection;
     }
 
     @Override
     public JavaConstant forObject(Object object) {
-        return HotSpotObjectConstantImpl.forObject(object);
+        return constantReflection.forObject(object);
     }
 
     @Override
@@ -67,7 +69,11 @@
 
     @Override
     public JavaConstant forBoxed(JavaKind kind, Object value) {
-        return HotSpotObjectConstantImpl.forBoxedValue(kind, value);
+        if (kind == JavaKind.Object) {
+            return forObject(value);
+        } else {
+            return JavaConstant.forBoxedPrimitive(value);
+        }
     }
 
     public Object getSubstitutionGuardParameter(Class<?> type) {
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/query/GetRootNameNode.java	Sat Oct 03 16:58:15 2015 -0700
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/query/GetRootNameNode.java	Sat Oct 03 17:25:59 2015 -0700
@@ -22,10 +22,9 @@
  */
 package com.oracle.graal.hotspot.replacements.query;
 
-import jdk.internal.jvmci.hotspot.HotSpotObjectConstantImpl;
 import jdk.internal.jvmci.hotspot.HotSpotResolvedObjectType;
 import jdk.internal.jvmci.meta.Constant;
-import jdk.internal.jvmci.meta.JavaKind;
+import jdk.internal.jvmci.meta.ConstantReflectionProvider;
 import jdk.internal.jvmci.meta.ResolvedJavaMethod;
 
 import com.oracle.graal.compiler.common.type.StampFactory;
@@ -46,10 +45,10 @@
     }
 
     @Override
-    public void onInlineICG(InstrumentationNode instrumentation, FixedNode position) {
+    public void onInlineICG(InstrumentationNode instrumentation, FixedNode position, ConstantReflectionProvider constantReflection) {
         ResolvedJavaMethod method = graph().method();
         String root = method.getDeclaringClass().toJavaName() + "." + method.getName() + method.getSignature().toMethodDescriptor();
-        Constant constant = HotSpotObjectConstantImpl.forBoxedValue(JavaKind.Object, root);
+        Constant constant = constantReflection.forObject(root);
         ConstantNode constantNode = graph().unique(new ConstantNode(constant, stamp()));
         graph().replaceFixedWithFloating(this, constantNode);
     }
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/query/GetRuntimePathNode.java	Sat Oct 03 16:58:15 2015 -0700
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/query/GetRuntimePathNode.java	Sat Oct 03 17:25:59 2015 -0700
@@ -22,6 +22,7 @@
  */
 package com.oracle.graal.hotspot.replacements.query;
 
+import jdk.internal.jvmci.meta.ConstantReflectionProvider;
 import jdk.internal.jvmci.meta.JavaKind;
 
 import com.oracle.graal.compiler.common.type.StampFactory;
@@ -63,7 +64,7 @@
     }
 
     @Override
-    public void onInlineICG(InstrumentationNode instrumentation, FixedNode position) {
+    public void onInlineICG(InstrumentationNode instrumentation, FixedNode position, ConstantReflectionProvider constantReflection) {
         if (instrumentation.target() instanceof AbstractMergeNode) {
             AbstractMergeNode merge = (AbstractMergeNode) instrumentation.target();
 
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/query/IsMethodInlinedNode.java	Sat Oct 03 16:58:15 2015 -0700
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/query/IsMethodInlinedNode.java	Sat Oct 03 17:25:59 2015 -0700
@@ -22,6 +22,7 @@
  */
 package com.oracle.graal.hotspot.replacements.query;
 
+import jdk.internal.jvmci.meta.ConstantReflectionProvider;
 import jdk.internal.jvmci.meta.JavaKind;
 
 import com.oracle.graal.compiler.common.type.StampFactory;
@@ -49,7 +50,7 @@
     }
 
     @Override
-    public void onInlineICG(InstrumentationNode instrumentation, FixedNode position) {
+    public void onInlineICG(InstrumentationNode instrumentation, FixedNode position, ConstantReflectionProvider constantReflection) {
         graph().replaceFixedWithFloating(this, ConstantNode.forBoolean(original != System.identityHashCode(instrumentation.graph()), graph()));
     }
 
--- a/graal/com.oracle.graal.java/src/com/oracle/graal/java/BytecodeParser.java	Sat Oct 03 16:58:15 2015 -0700
+++ b/graal/com.oracle.graal.java/src/com/oracle/graal/java/BytecodeParser.java	Sat Oct 03 17:25:59 2015 -0700
@@ -1972,9 +1972,6 @@
         }
 
         synchronizedEpilogue(BytecodeFrame.AFTER_BCI, x, kind);
-        if (frameState.lockDepth(false) != 0) {
-            throw bailout("unbalanced monitors");
-        }
     }
 
     protected void genMonitorEnter(ValueNode x, int bci) {
@@ -1985,6 +1982,9 @@
     }
 
     protected void genMonitorExit(ValueNode x, ValueNode escapedReturnValue, int bci) {
+        if (frameState.lockDepth(false) == 0) {
+            throw bailout("unbalanced monitors: too many exits");
+        }
         MonitorIdNode monitorId = frameState.peekMonitorId();
         ValueNode lockedObject = frameState.popLock();
         if (GraphUtil.originalValue(lockedObject) != GraphUtil.originalValue(x)) {
@@ -2520,6 +2520,9 @@
             genMonitorExit(methodSynchronizedObject, currentReturnValue, bci);
             assert !frameState.rethrowException();
         }
+        if (frameState.lockDepth(false) != 0) {
+            throw bailout("unbalanced monitors: too few exits exiting frame");
+        }
     }
 
     private void createExceptionDispatch(ExceptionDispatchBlock block) {
@@ -2646,6 +2649,9 @@
 
             try {
                 processBytecode(bci, opcode);
+            } catch (BailoutException e) {
+                // Don't wrap bailouts as parser errors
+                throw e;
             } catch (Throwable e) {
                 throw asParserError(e);
             }
--- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/query/InlineICGPhase.java	Sat Oct 03 16:58:15 2015 -0700
+++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/query/InlineICGPhase.java	Sat Oct 03 17:25:59 2015 -0700
@@ -68,7 +68,7 @@
             instrumentationNode.inlineAt(instrumentationNode);
 
             for (GraalQueryNode query : graph.getNodes().filter(GraalQueryNode.class)) {
-                query.onInlineICG(instrumentationNode, instrumentationNode);
+                query.onInlineICG(instrumentationNode, instrumentationNode, context.getConstantReflection());
             }
 
             GraphUtil.unlinkFixedNode(instrumentationNode);
--- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/query/nodes/GraalQueryNode.java	Sat Oct 03 16:58:15 2015 -0700
+++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/query/nodes/GraalQueryNode.java	Sat Oct 03 17:25:59 2015 -0700
@@ -22,6 +22,8 @@
  */
 package com.oracle.graal.phases.common.query.nodes;
 
+import jdk.internal.jvmci.meta.ConstantReflectionProvider;
+
 import com.oracle.graal.compiler.common.type.Stamp;
 import com.oracle.graal.graph.NodeClass;
 import com.oracle.graal.nodeinfo.NodeInfo;
@@ -40,7 +42,8 @@
     public void onExtractICG(@SuppressWarnings("unused") InstrumentationNode instrumentation) {
     }
 
-    public void onInlineICG(@SuppressWarnings("unused") InstrumentationNode instrumentation, @SuppressWarnings("unused") FixedNode position) {
+    public void onInlineICG(@SuppressWarnings("unused") InstrumentationNode instrumentation, @SuppressWarnings("unused") FixedNode position,
+                    @SuppressWarnings("unused") ConstantReflectionProvider constantReflection) {
     }
 
 }
--- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/TruffleConstantReflectionProvider.java	Sat Oct 03 16:58:15 2015 -0700
+++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/TruffleConstantReflectionProvider.java	Sat Oct 03 17:25:59 2015 -0700
@@ -120,6 +120,10 @@
         return graalConstantReflection.forString(value);
     }
 
+    public JavaConstant forObject(Object value) {
+        return graalConstantReflection.forObject(value);
+    }
+
     public ResolvedJavaType asJavaType(Constant constant) {
         return graalConstantReflection.asJavaType(constant);
     }
--- a/mx.graal/mx_graal.py	Sat Oct 03 16:58:15 2015 -0700
+++ b/mx.graal/mx_graal.py	Sat Oct 03 17:25:59 2015 -0700
@@ -33,8 +33,14 @@
 import re
 
 import mx
-import mx_jvmci
-from mx_jvmci import JvmciJDKDeployedDist, run_vm, VM, Task, get_vm, isJVMCIEnabled, get_jvmci_jdk, get_jvmci_jdk_dir, buildvms
+from mx_jvmci import JvmciJDKDeployedDist, add_bootclasspath_prepend
+from mx_jvmci import jdkDeployedDists #pylint: disable=unused-import
+
+try:
+    from mx_jvmci import run_vm, VM, Task, get_vm, \
+    isJVMCIEnabled, relativeVmLibDirInJdk, get_jvmci_jdk, get_jvmci_jdk_dir, buildvms
+except ImportError:
+    pass
 from mx_unittest import unittest
 import mx_gate
 
@@ -69,7 +75,7 @@
             with open(graalProperties, 'w') as fp:
                 fp.write(os.linesep.join(content))
 
-mx_jvmci.jdkDeployedDists += [
+jdkDeployedDists += [
     JvmciJDKDeployedDist('GRAAL_NODEINFO'),
     JvmciJDKDeployedDist('GRAAL_API'),
     JvmciJDKDeployedDist('GRAAL_COMPILER'),
@@ -468,7 +474,7 @@
 
 def jdkartifactstats(args):
     """show stats about JDK deployed Graal artifacts"""
-    jdkDir = mx_jvmci.get_jvmci_jdk_dir()
+    jdkDir = get_jvmci_jdk_dir()
     artifacts = {}
     for root, _, filenames in os.walk(join(jdkDir, 'jre', 'lib')):
         for f in filenames:
@@ -508,7 +514,7 @@
             t1, t2, t3 = totals
             print '{:10,}  {:10,}  {:10,}  {}'.format(t1, t2, t3, category)
 
-    jvmLib = join(jdkDir, mx_jvmci.relativeVmLibDirInJdk(), get_vm(), mx.add_lib_suffix(mx.add_lib_prefix('jvm')))
+    jvmLib = join(jdkDir, relativeVmLibDirInJdk(), get_vm(), mx.add_lib_suffix(mx.add_lib_prefix('jvm')))
     print
     if exists(jvmLib):
         print '{:10,}  {}'.format(os.path.getsize(jvmLib), jvmLib)
@@ -531,4 +537,4 @@
 
 
 def mx_post_parse_cmd_line(opts):
-    mx_jvmci.add_bootclasspath_prepend(mx.distribution('truffle:TRUFFLE_API'))
+    add_bootclasspath_prepend(mx.distribution('truffle:TRUFFLE_API'))
--- a/mx.graal/suite.py	Sat Oct 03 16:58:15 2015 -0700
+++ b/mx.graal/suite.py	Sat Oct 03 17:25:59 2015 -0700
@@ -6,7 +6,7 @@
     "suites": [
             {
                "name" : "jvmci",
-               "version" : "cefe66df34551309bdda19adcb8ab4b226483e32",
+               "version" : "8ed4037e828628c8a957ed1ec9cdfdd694c64d91",
                "urls" : [
                     {"url" : "http://lafo.ssw.uni-linz.ac.at/hg/graal-jvmci-8", "kind" : "hg"},
                     {"url" : "https://curio.ssw.jku.at/nexus/content/repositories/snapshots", "kind" : "binary"},
@@ -14,7 +14,7 @@
             },
             {
                "name" : "truffle",
-               "version" : "1e4021a273b1e2e4767be88308642fdb9dffb8dd",
+               "version" : "371045b1312d412bafa29882e6c3f7bfe6c0f8f1",
                "urls" : [
                     {"url" : "http://lafo.ssw.uni-linz.ac.at/hg/truffle", "kind" : "hg"},
                     {"url" : "https://curio.ssw.jku.at/nexus/content/repositories/snapshots", "kind" : "binary"},