changeset 6400:e7b50827698e

Merge.
author Lukas Stadler <lukas.stadler@jku.at>
date Fri, 14 Sep 2012 15:28:05 +0200
parents 6ad5bf2efb5e (current diff) 4f7b8550daf8 (diff)
children 3b3af8fc32a7
files graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/snippets/DirectStoreNode.java graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/snippets/GetObjectAddressNode.java
diffstat 14 files changed, 241 insertions(+), 162 deletions(-) [+]
line wrap: on
line diff
--- a/graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/RuntimeCall.java	Fri Sep 14 15:26:57 2012 +0200
+++ b/graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/RuntimeCall.java	Fri Sep 14 15:28:05 2012 +0200
@@ -48,7 +48,7 @@
     ArithmeticSin(Double, Double),
     GenericCallback(Object, Object, Object),
     LogPrimitive(Void, Int, Long, Boolean),
-    LogObject(Void, Object, Boolean, Boolean);
+    LogObject(Void, Object, Int);
 
     public final Kind resultKind;
     public final Kind[] arguments;
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/DirectStoreNode.java	Fri Sep 14 15:28:05 2012 +0200
@@ -0,0 +1,63 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.graal.hotspot.nodes;
+
+import com.oracle.graal.api.code.*;
+import com.oracle.graal.api.meta.*;
+import com.oracle.graal.nodes.*;
+import com.oracle.graal.nodes.extended.*;
+import com.oracle.graal.nodes.spi.*;
+import com.oracle.graal.nodes.type.*;
+
+/**
+ * A special purpose store node that differs from {@link UnsafeStoreNode} in that
+ * it is not a {@link StateSplit} and takes a computed address instead of an object.
+ */
+public class DirectStoreNode extends FixedWithNextNode implements LIRLowerable {
+    @Input private ValueNode address;
+    @Input private ValueNode value;
+
+    public DirectStoreNode(ValueNode address, ValueNode value) {
+        super(StampFactory.forVoid());
+        this.address = address;
+        this.value = value;
+    }
+
+    @SuppressWarnings("unused")
+    @NodeIntrinsic
+    public static void store(long address, long value) {
+        throw new UnsupportedOperationException();
+    }
+
+    @SuppressWarnings("unused")
+    @NodeIntrinsic
+    public static void store(long address, boolean value) {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public void generate(LIRGeneratorTool gen) {
+        Value v = gen.operand(value);
+        gen.emitStore(new Address(v.getKind(), gen.operand(address)), v, false);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/GetObjectAddressNode.java	Fri Sep 14 15:28:05 2012 +0200
@@ -0,0 +1,56 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.graal.hotspot.nodes;
+
+import com.oracle.graal.api.meta.*;
+import com.oracle.graal.nodes.*;
+import com.oracle.graal.nodes.spi.*;
+import com.oracle.graal.nodes.type.*;
+
+/**
+ * Intrinsification for getting the address of an object.
+ * The code path(s) between a call to {@link #get(Object)} and all uses
+ * of the returned value must be atomic. The only exception to this is
+ * if the usage is not an attempt to dereference the value.
+ */
+public class GetObjectAddressNode extends FixedWithNextNode implements LIRLowerable {
+    @Input private ValueNode object;
+
+    public GetObjectAddressNode(ValueNode obj) {
+        super(StampFactory.forKind(Kind.Long));
+        this.object = obj;
+    }
+
+    @SuppressWarnings("unused")
+    @NodeIntrinsic
+    public static long get(Object array) {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public void generate(LIRGeneratorTool gen) {
+        Value obj = gen.newVariable(gen.target().wordKind);
+        gen.emitMove(gen.operand(object), obj);
+        gen.setResult(this, obj);
+    }
+}
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/snippets/ArrayCopySnippets.java	Fri Sep 14 15:26:57 2012 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/snippets/ArrayCopySnippets.java	Fri Sep 14 15:28:05 2012 +0200
@@ -25,6 +25,7 @@
 
 import com.oracle.graal.api.meta.*;
 import com.oracle.graal.hotspot.*;
+import com.oracle.graal.hotspot.nodes.*;
 import com.oracle.graal.nodes.*;
 import com.oracle.graal.nodes.extended.*;
 import com.oracle.graal.nodes.spi.*;
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/snippets/DirectStoreNode.java	Fri Sep 14 15:26:57 2012 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,63 +0,0 @@
-/*
- * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-package com.oracle.graal.hotspot.snippets;
-
-import com.oracle.graal.api.code.*;
-import com.oracle.graal.api.meta.*;
-import com.oracle.graal.nodes.*;
-import com.oracle.graal.nodes.extended.*;
-import com.oracle.graal.nodes.spi.*;
-import com.oracle.graal.nodes.type.*;
-
-/**
- * A special purpose store node that differs from {@link UnsafeStoreNode} in that
- * it is not a {@link StateSplit} and takes a computed address instead of an object.
- */
-class DirectStoreNode extends FixedWithNextNode implements LIRLowerable {
-    @Input private ValueNode address;
-    @Input private ValueNode value;
-
-    public DirectStoreNode(ValueNode address, ValueNode value) {
-        super(StampFactory.forVoid());
-        this.address = address;
-        this.value = value;
-    }
-
-    @SuppressWarnings("unused")
-    @NodeIntrinsic
-    public static void store(long address, long value) {
-        throw new UnsupportedOperationException();
-    }
-
-    @SuppressWarnings("unused")
-    @NodeIntrinsic
-    public static void store(long address, boolean value) {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public void generate(LIRGeneratorTool gen) {
-        Value v = gen.operand(value);
-        gen.emitStore(new Address(v.getKind(), gen.operand(address)), v, false);
-    }
-}
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/snippets/GetObjectAddressNode.java	Fri Sep 14 15:26:57 2012 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,56 +0,0 @@
-/*
- * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-package com.oracle.graal.hotspot.snippets;
-
-import com.oracle.graal.api.meta.*;
-import com.oracle.graal.nodes.*;
-import com.oracle.graal.nodes.spi.*;
-import com.oracle.graal.nodes.type.*;
-
-/**
- * Intrinsification for getting the address of an object.
- * The code path(s) between a call to {@link #get(Object)} and all uses
- * of the returned value must be atomic. The only exception to this is
- * if the usage is not an attempt to dereference the value.
- */
-class GetObjectAddressNode extends FixedWithNextNode implements LIRLowerable {
-    @Input private ValueNode object;
-
-    public GetObjectAddressNode(ValueNode obj) {
-        super(StampFactory.forKind(Kind.Long));
-        this.object = obj;
-    }
-
-    @SuppressWarnings("unused")
-    @NodeIntrinsic
-    public static long get(Object array) {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public void generate(LIRGeneratorTool gen) {
-        Value obj = gen.newVariable(gen.target().wordKind);
-        gen.emitMove(gen.operand(object), obj);
-        gen.setResult(this, obj);
-    }
-}
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/snippets/HotSpotSnippetUtils.java	Fri Sep 14 15:26:57 2012 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/snippets/HotSpotSnippetUtils.java	Fri Sep 14 15:28:05 2012 +0200
@@ -96,6 +96,15 @@
         return HotSpotGraalRuntime.getInstance().getConfig().unlockedMask;
     }
 
+    /**
+     * Mask for a biasable, locked or unlocked mark word.
+     * <pre>
+     * +----------------------------------+-+-+
+     * |                                 1|1|1|
+     * +----------------------------------+-+-+
+     * </pre>
+     *
+     */
     @Fold
     static int biasedLockMaskInPlace() {
         return HotSpotGraalRuntime.getInstance().getConfig().biasedLockMaskInPlace;
@@ -106,6 +115,15 @@
         return HotSpotGraalRuntime.getInstance().getConfig().epochMaskInPlace;
     }
 
+    /**
+     * Pattern for a biasable, unlocked mark word.
+     * <pre>
+     * +----------------------------------+-+-+
+     * |                                 1|0|1|
+     * +----------------------------------+-+-+
+     * </pre>
+     *
+     */
     @Fold
     static int biasedLockPattern() {
         return HotSpotGraalRuntime.getInstance().getConfig().biasedLockPattern;
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/snippets/MonitorSnippets.java	Fri Sep 14 15:26:57 2012 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/snippets/MonitorSnippets.java	Fri Sep 14 15:28:05 2012 +0200
@@ -41,7 +41,8 @@
 import com.oracle.graal.nodes.java.*;
 import com.oracle.graal.nodes.spi.*;
 import com.oracle.graal.snippets.*;
-import com.oracle.graal.snippets.Snippet.*;
+import com.oracle.graal.snippets.Snippet.ConstantParameter;
+import com.oracle.graal.snippets.Snippet.Parameter;
 import com.oracle.graal.snippets.SnippetTemplate.AbstractTemplates;
 import com.oracle.graal.snippets.SnippetTemplate.Arguments;
 import com.oracle.graal.snippets.SnippetTemplate.Key;
@@ -55,18 +56,21 @@
  */
 public class MonitorSnippets implements SnippetsInterface {
 
-    private static final boolean LOG = Boolean.getBoolean("graal.monitorsnippets.log");
+    /**
+     * Monitor operations on objects whose type contains this substring will be logged.
+     */
+    private static final String LOG_TYPE = System.getProperty("graal.monitorsnippets.log");
 
-    private static void log(String action, Object object) {
-        if (LOG) {
+    private static void log(boolean enabled, String action, Object object) {
+        if (enabled) {
             Log.print(action);
             Log.print(' ');
-            Log.printlnAddress(object);
+            Log.printlnObject(object);
         }
     }
 
     @Snippet
-    public static void monitorenter(@Parameter("object") Object object) {
+    public static void monitorenter(@Parameter("object") Object object, @ConstantParameter("logEnabled") boolean logEnabled) {
         verifyOop(object);
 
         // Load the mark word - this includes a null-check on object
@@ -79,10 +83,10 @@
             // whether the epoch is still valid.
             // Note that the runtime guarantees sufficient alignment of JavaThread
             // pointers to allow age to be placed into low bits.
-            final Word biasedLockMark = mark.and(biasedLockMaskInPlace());
+            final Word biasableLockBits = mark.and(biasedLockMaskInPlace());
 
             // First check to see whether biasing is enabled for this object
-            if (biasedLockMark.toLong() != biasedLockPattern()) {
+            if (biasableLockBits.toLong() != biasedLockPattern()) {
                 // Biasing not enabled -> fall through to lightweight locking
             } else {
                 // The bias pattern is present in the object's mark word. Need to check
@@ -93,7 +97,7 @@
                 final Word tmp = prototypeMarkWord.or(thread).xor(mark).and(~ageMaskInPlace());
                 if (tmp == Word.zero()) {
                     // Object is already biased to current thread -> done
-                    log("+lock{bias}", object);
+                    log(logEnabled, "+lock{bias}", object);
                     return;
                 }
 
@@ -123,14 +127,14 @@
                         Word biasedMark = unbiasedMark.or(thread);
                         if (compareAndSwap(object, markOffset(), unbiasedMark, biasedMark) == unbiasedMark) {
                             // Object is now biased to current thread -> done
-                            log("+lock{bias}", object);
+                            log(logEnabled, "+lock{bias}", object);
                             return;
                         }
                         // If the biasing toward our thread failed, this means that
                         // another thread succeeded in biasing it toward itself and we
                         // need to revoke that bias. The revocation will occur in the
                         // interpreter runtime in the slow case.
-                        log("+lock{stub}", object);
+                        log(logEnabled, "+lock{stub}", object);
                         MonitorEnterStubCall.call(object, lock);
                         return;
                     } else {
@@ -143,13 +147,13 @@
                         Word biasedMark = prototypeMarkWord.or(thread);
                         if (compareAndSwap(object, markOffset(), mark, biasedMark) == mark) {
                             // Object is now biased to current thread -> done
-                            log("+lock{bias}", object);
+                            log(logEnabled, "+lock{bias}", object);
                             return;
                         }
                         // If the biasing toward our thread failed, then another thread
                         // succeeded in biasing it toward itself and we need to revoke that
                         // bias. The revocation will occur in the runtime in the slow case.
-                        log("+lock{stub}", object);
+                        log(logEnabled, "+lock{stub}", object);
                         MonitorEnterStubCall.call(object, lock);
                         return;
                     }
@@ -200,16 +204,16 @@
             final Word stackPointer = asWord(register(stackPointerReg(), wordKind()));
             if (currentMark.minus(stackPointer).and(alignedMask.minus(pageSize())) != Word.zero()) {
                 // Most likely not a recursive lock, go into a slow runtime call
-                log("+lock{stub}", object);
+                log(logEnabled, "+lock{stub}", object);
                 MonitorEnterStubCall.call(object, lock);
                 return;
             } else {
                 // Recursively locked => write 0 to the lock slot
                 storeWord(lock, lockDisplacedMarkOffset(), 0, Word.zero());
-                log("+lock{recursive}", object);
+                log(logEnabled, "+lock{recursive}", object);
             }
         } else {
-            log("+lock{cas}", object);
+            log(logEnabled, "+lock{cas}", object);
         }
     }
 
@@ -222,7 +226,7 @@
      * Calls straight out to the monitorenter stub.
      */
     @Snippet
-    public static void monitorenterStub(@Parameter("object") Object object, @ConstantParameter("checkNull") boolean checkNull) {
+    public static void monitorenterStub(@Parameter("object") Object object, @ConstantParameter("checkNull") boolean checkNull, @ConstantParameter("logEnabled") boolean logEnabled) {
         verifyOop(object);
         if (checkNull && object == null) {
             DeoptimizeNode.deopt(DeoptimizationAction.InvalidateReprofile, DeoptimizationReason.NullCheckException);
@@ -230,12 +234,12 @@
         // BeginLockScope nodes do not read from object so a use of object
         // cannot float about the null check above
         final Word lock = beginLockScope(object, false, wordKind());
-        log("+lock{stub}", object);
+        log(logEnabled, "+lock{stub}", object);
         MonitorEnterStubCall.call(object, lock);
     }
 
     @Snippet
-    public static void monitorexit(@Parameter("object") Object object) {
+    public static void monitorexit(@Parameter("object") Object object, @ConstantParameter("logEnabled") boolean logEnabled) {
         if (useBiasedLocking()) {
             // Check for biased locking unlock case, which is a no-op
             // Note: we do not have to check the thread ID for two reasons.
@@ -246,7 +250,7 @@
             final Word mark = asWord(loadObject(object, 0, markOffset(), true));
             if (mark.and(biasedLockMaskInPlace()).toLong() == biasedLockPattern()) {
                 endLockScope(object, false);
-                log("-lock{bias}", object);
+                log(logEnabled, "-lock{bias}", object);
                 return;
             }
         }
@@ -258,19 +262,19 @@
 
         if (displacedMark == Word.zero()) {
             // Recursive locking => done
-            log("-lock{recursive}", object);
+            log(logEnabled, "-lock{recursive}", object);
         } else {
             verifyOop(object);
             // Test if object's mark word is pointing to the displaced mark word, and if so, restore
             // the displaced mark in the object - if the object's mark word is not pointing to
-            // the displaced mark word, get the object mark word instead
+            // the displaced mark word, do unlocking via runtime call.
             if (DirectCompareAndSwapNode.compareAndSwap(object, markOffset(), lock, displacedMark) != lock) {
               // The object's mark word was not pointing to the displaced header,
-              // we do unlocking via runtime call
-                log("-lock{stub}", object);
+              // we do unlocking via runtime call.
+                log(logEnabled, "-lock{stub}", object);
                 MonitorExitStubCall.call(object);
             } else {
-                log("-lock{cas}", object);
+                log(logEnabled, "-lock{cas}", object);
             }
         }
         endLockScope(object, false);
@@ -280,9 +284,9 @@
      * Calls straight out to the monitorexit stub.
      */
     @Snippet
-    public static void monitorexitStub(@Parameter("object") Object object) {
+    public static void monitorexitStub(@Parameter("object") Object object, @ConstantParameter("logEnabled") boolean logEnabled) {
         verifyOop(object);
-        log("-lock{stub}", object);
+        log(logEnabled, "-lock{stub}", object);
         MonitorExitStubCall.call(object);
         endLockScope(object, false);
     }
@@ -304,15 +308,30 @@
 
         public Templates(CodeCacheProvider runtime, boolean useFastLocking) {
             super(runtime, MonitorSnippets.class);
-            monitorenter = snippet("monitorenter", Object.class);
-            monitorexit = snippet("monitorexit", Object.class);
-            monitorenterStub = snippet("monitorenterStub", Object.class, boolean.class);
-            monitorexitStub = snippet("monitorexitStub", Object.class);
+            monitorenter = snippet("monitorenter", Object.class, boolean.class);
+            monitorexit = snippet("monitorexit", Object.class, boolean.class);
+            monitorenterStub = snippet("monitorenterStub", Object.class, boolean.class, boolean.class);
+            monitorexitStub = snippet("monitorexitStub", Object.class, boolean.class);
             monitorenterEliminated = snippet("monitorenterEliminated", Object.class);
             monitorexitEliminated = snippet("monitorexitEliminated", Object.class);
             this.useFastLocking = useFastLocking;
         }
 
+        static boolean isLoggingEnabledFor(ValueNode object) {
+            ResolvedJavaType type = object.objectStamp().type();
+            if (LOG_TYPE == null) {
+                return false;
+            } else {
+                if (LOG_TYPE.length() == 0) {
+                    return true;
+                }
+                if (type == null) {
+                    return false;
+                }
+                return (type.name().contains(LOG_TYPE));
+            }
+        }
+
         public void lower(MonitorEnterNode monitorenterNode, @SuppressWarnings("unused") LoweringTool tool) {
             FrameState stateAfter = monitorenterNode.stateAfter();
             ResolvedJavaMethod method = monitorenterNode.eliminated() ? monitorenterEliminated : useFastLocking ? monitorenter : monitorenterStub;
@@ -321,6 +340,9 @@
             if (method == monitorenterStub) {
                 key.add("checkNull", checkNull);
             }
+            if (!monitorenterNode.eliminated()) {
+                key.add("logEnabled", isLoggingEnabledFor(monitorenterNode.object()));
+            }
             Arguments arguments = arguments("object", monitorenterNode.object());
             SnippetTemplate template = cache.get(key);
             Map<Node, Node> nodes = template.instantiate(runtime, monitorenterNode, arguments);
@@ -336,6 +358,9 @@
             FrameState stateAfter = monitorexitNode.stateAfter();
             ResolvedJavaMethod method = monitorexitNode.eliminated() ? monitorexitEliminated : useFastLocking ? monitorexit : monitorexitStub;
             Key key = new Key(method);
+            if (!monitorexitNode.eliminated()) {
+                key.add("logEnabled", isLoggingEnabledFor(monitorexitNode.object()));
+            }
             Arguments arguments = arguments("object", monitorexitNode.object());
             SnippetTemplate template = cache.get(key);
             Map<Node, Node> nodes = template.instantiate(runtime, monitorexitNode, arguments);
--- a/graal/com.oracle.graal.printer/src/com/oracle/graal/printer/BinaryGraphPrinter.java	Fri Sep 14 15:26:57 2012 +0200
+++ b/graal/com.oracle.graal.printer/src/com/oracle/graal/printer/BinaryGraphPrinter.java	Fri Sep 14 15:28:05 2012 +0200
@@ -241,6 +241,13 @@
         }
     }
 
+    private static String getClassName(Class<?> klass) {
+        if (!klass.isArray()) {
+            return klass.getName();
+        }
+        return getClassName(klass.getComponentType()) + "[]";
+    }
+
     private void addPoolEntry(Object object) throws IOException {
         int index = constantPool.add(object);
         writeByte(POOL_NEW);
@@ -248,7 +255,7 @@
         if (object instanceof Class<?>) {
             Class<?> klass = (Class< ? >) object;
             writeByte(POOL_CLASS);
-            writeString(klass.getName());
+            writeString(getClassName(klass));
             if (klass.isEnum()) {
                 writeByte(ENUM_KLASS);
                 Object[] enumConstants = klass.getEnumConstants();
--- a/graal/com.oracle.graal.snippets/src/com/oracle/graal/snippets/Log.java	Fri Sep 14 15:26:57 2012 +0200
+++ b/graal/com.oracle.graal.snippets/src/com/oracle/graal/snippets/Log.java	Fri Sep 14 15:28:05 2012 +0200
@@ -33,9 +33,14 @@
  */
 public final class Log {
 
+    // Note: Must be kept in sync with constants in c1_Runtime1.hpp
+    private static final int LOG_OBJECT_NEWLINE = 0x01;
+    private static final int LOG_OBJECT_STRING  = 0x02;
+    private static final int LOG_OBJECT_ADDRESS = 0x04;
+
     @SuppressWarnings("unused")
     @NodeIntrinsic(RuntimeCallNode.class)
-    private static void log(@ConstantNodeParameter RuntimeCall logObject, Object object, boolean newline, boolean string) {
+    private static void log(@ConstantNodeParameter RuntimeCall logObject, Object object, int flags) {
         throw new UnsupportedOperationException("This method may only be compiled with the Graal compiler");
     }
 
@@ -94,11 +99,15 @@
     }
 
     public static void print(String value) {
-        log(RuntimeCall.LogObject, value, false, true);
+        log(RuntimeCall.LogObject, value, LOG_OBJECT_STRING);
     }
 
     public static void printAddress(Object o) {
-        log(RuntimeCall.LogObject, o, false, false);
+        log(RuntimeCall.LogObject, o, LOG_OBJECT_ADDRESS);
+    }
+
+    public static void printObject(Object o) {
+        log(RuntimeCall.LogObject, o, 0);
     }
 
     public static void println(boolean value) {
@@ -150,11 +159,15 @@
     }
 
     public static void println(String value) {
-        log(RuntimeCall.LogObject, value, true, true);
+        log(RuntimeCall.LogObject, value, LOG_OBJECT_NEWLINE | LOG_OBJECT_STRING);
     }
 
     public static void printlnAddress(Object o) {
-        log(RuntimeCall.LogObject, o, true, false);
+        log(RuntimeCall.LogObject, o, LOG_OBJECT_NEWLINE | LOG_OBJECT_ADDRESS);
+    }
+
+    public static void printlnObject(Object o) {
+        log(RuntimeCall.LogObject, o, LOG_OBJECT_NEWLINE);
     }
 
     public static void println() {
--- a/src/cpu/x86/vm/c1_Runtime1_x86.cpp	Fri Sep 14 15:26:57 2012 +0200
+++ b/src/cpu/x86/vm/c1_Runtime1_x86.cpp	Fri Sep 14 15:28:05 2012 +0200
@@ -1933,7 +1933,7 @@
       __ enter();
       oop_maps = new OopMapSet();
       OopMap* oop_map = save_live_registers(sasm, 0);
-      int call_offset = __ call_RT(noreg, noreg, (address)graal_log_object, j_rarg0, j_rarg1, j_rarg2);
+      int call_offset = __ call_RT(noreg, noreg, (address)graal_log_object, j_rarg0, j_rarg1);
       oop_maps->add_gc_map(call_offset, oop_map);
       restore_live_registers(sasm);
       __ leave();
--- a/src/share/vm/c1/c1_Runtime1.cpp	Fri Sep 14 15:26:57 2012 +0200
+++ b/src/share/vm/c1/c1_Runtime1.cpp	Fri Sep 14 15:28:05 2012 +0200
@@ -750,9 +750,17 @@
 #endif
 JRT_END
 
-JRT_ENTRY(void, Runtime1::graal_log_object(JavaThread* thread, oop obj, jboolean newline, jboolean string))
+JRT_ENTRY(void, Runtime1::graal_log_object(JavaThread* thread, oop obj, jint flags))
+  bool string = flags & LOG_OBJECT_STRING;
+  bool address = flags & LOG_OBJECT_ADDRESS;
+  bool newline = flags & LOG_OBJECT_NEWLINE;
   if (!string) {
-    tty->print("%p", obj);
+    if (!address && obj->is_oop_or_null(true)) {
+      char buf[400];
+      tty->print("%s@%p", obj->klass()->klass_part()->name()->as_C_string(buf, 400), obj);
+    } else {
+      tty->print("%p", obj);
+    }
   } else {
     assert(obj != NULL && java_lang_String::is_instance(obj), "must be");
 
--- a/src/share/vm/c1/c1_Runtime1.hpp	Fri Sep 14 15:26:57 2012 +0200
+++ b/src/share/vm/c1/c1_Runtime1.hpp	Fri Sep 14 15:28:05 2012 +0200
@@ -207,7 +207,14 @@
   static void graal_monitorenter(JavaThread* thread, oopDesc* obj, BasicLock* lock);
   static void graal_monitorexit (JavaThread* thread, oopDesc* obj, BasicLock* lock);
   static void graal_log_primitive(JavaThread* thread, jchar typeChar, jlong value, jboolean newline);
-  static void graal_log_object(JavaThread* thread, oop msg, jboolean newline, jboolean string);
+
+  // Note: Must be kept in sync with constants in com.oracle.graal.snippets.Log
+  enum {
+    LOG_OBJECT_NEWLINE = 0x01,
+    LOG_OBJECT_STRING  = 0x02,
+    LOG_OBJECT_ADDRESS = 0x04
+  };
+  static void graal_log_object(JavaThread* thread, oop msg, jint flags);
 #endif
 
   static void deoptimize(JavaThread* thread);
--- a/src/share/vm/graal/graalCodeInstaller.cpp	Fri Sep 14 15:26:57 2012 +0200
+++ b/src/share/vm/graal/graalCodeInstaller.cpp	Fri Sep 14 15:28:05 2012 +0200
@@ -448,7 +448,7 @@
   methodOop method = getMethodFromHotSpotMethod(hotspot_method);
   jint bci = BytecodePosition::bci(frame);
   bool reexecute;
-  if (bci == -1) {
+  if (bci == -1 || bci == -2){
      reexecute = false;
   } else {
     Bytecodes::Code code = Bytecodes::java_code_at(method, method->bcp_from(bci));