changeset 5763:a3d71693e0ce

removed bytecode disassembly from CodeCacheRuntime into separate BytecodeDisassembler class removed VM call for doing bytecode disassembly added support for explicitly excluding classes from JaCoCo (put '// JaCoCo Exclude' somewhere in the source file) added node intrinsics to MaterializeNode added snippets for the UnsignedMath classes each file opened by CFGPrinter now includes a unique id in its name to avoid a race of multiple threads writing to the same file the IdealGraphPrinter uses the new BytecodeDisassembler mechanism teh UnsignedMath class is exclude from JaCoCo processing as it is used in snippets
author Doug Simon <doug.simon@oracle.com>
date Wed, 04 Jul 2012 21:57:49 +0200
parents b30cced39597
children 66ec0bc36a37
files graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/CodeCacheProvider.java graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/bridge/CompilerToVM.java graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/bridge/CompilerToVMImpl.java graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/bridge/VMToCompilerImpl.java graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotRuntime.java graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/snippets/NewObjectSnippets.java graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/snippets/UnsignedMathSnippets.java graal/com.oracle.graal.java/src/com/oracle/graal/java/BytecodeDisassembler.java graal/com.oracle.graal.java/src/com/oracle/graal/java/GraphBuilderPhase.java graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/IfNode.java graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/MaterializeNode.java graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/NormalizeCompareNode.java graal/com.oracle.graal.printer/src/com/oracle/graal/printer/BasicIdealGraphPrinter.java graal/com.oracle.graal.printer/src/com/oracle/graal/printer/CFGPrinterObserver.java graal/com.oracle.graal.printer/src/com/oracle/graal/printer/IdealGraphPrinter.java graal/com.oracle.graal.snippets/src/com/oracle/graal/snippets/WordTypeRewriterPhase.java graal/com.oracle.max.criutils/src/com/oracle/max/criutils/UnsignedMath.java src/share/vm/graal/graalCompilerToVM.cpp
diffstat 18 files changed, 414 insertions(+), 86 deletions(-) [+]
line wrap: on
line diff
--- a/graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/CodeCacheProvider.java	Wed Jul 04 21:56:48 2012 +0200
+++ b/graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/CodeCacheProvider.java	Wed Jul 04 21:57:49 2012 +0200
@@ -44,14 +44,6 @@
     String disassemble(CodeInfo code, CompilationResult tm);
 
     /**
-     * Returns the disassembly of the given method in a {@code javap}-like format.
-     *
-     * @param method the method that should be disassembled
-     * @return the disassembly. This will be of length 0 if the runtime does not support disassembling.
-     */
-    String disassemble(ResolvedJavaMethod method);
-
-    /**
      * Gets the register configuration to use when compiling a given method.
      *
      * @param method the top level method of a compilation
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/bridge/CompilerToVM.java	Wed Jul 04 21:56:48 2012 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/bridge/CompilerToVM.java	Wed Jul 04 21:57:49 2012 +0200
@@ -105,8 +105,6 @@
 
     String disassembleNative(byte[] code, long address);
 
-    String disassembleJava(HotSpotResolvedJavaMethod method);
-
     StackTraceElement JavaMethod_toStackTraceElement(HotSpotResolvedJavaMethod method, int bci);
 
     Object executeCompiledMethod(HotSpotCompiledMethod method, Object arg1, Object arg2, Object arg3);
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/bridge/CompilerToVMImpl.java	Wed Jul 04 21:56:48 2012 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/bridge/CompilerToVMImpl.java	Wed Jul 04 21:57:49 2012 +0200
@@ -150,9 +150,6 @@
     public native String disassembleNative(byte[] code, long address);
 
     @Override
-    public native String disassembleJava(HotSpotResolvedJavaMethod method);
-
-    @Override
     public native StackTraceElement JavaMethod_toStackTraceElement(HotSpotResolvedJavaMethod method, int bci);
 
     @Override
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/bridge/VMToCompilerImpl.java	Wed Jul 04 21:56:48 2012 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/bridge/VMToCompilerImpl.java	Wed Jul 04 21:57:49 2012 +0200
@@ -48,7 +48,7 @@
  */
 public class VMToCompilerImpl implements VMToCompiler {
 
-    private final HotSpotGraalRuntime compiler;
+    private final HotSpotGraalRuntime graalRuntime;
     private IntrinsifyArrayCopyPhase intrinsifyArrayCopy;
 
     public final HotSpotTypePrimitive typeBoolean;
@@ -68,7 +68,7 @@
     private PrintStream log = System.out;
 
     public VMToCompilerImpl(HotSpotGraalRuntime compiler) {
-        this.compiler = compiler;
+        this.graalRuntime = compiler;
 
         typeBoolean = new HotSpotTypePrimitive(Kind.Boolean);
         typeChar = new HotSpotTypePrimitive(Kind.Char);
@@ -105,9 +105,10 @@
             Debug.setConfig(hotspotDebugConfig);
         }
         // Install intrinsics.
-        final HotSpotRuntime runtime = (HotSpotRuntime) compiler.getCompiler().runtime;
+        GraalCompiler compiler = graalRuntime.getCompiler();
+        final HotSpotRuntime runtime = (HotSpotRuntime) compiler.runtime;
         if (GraalOptions.Intrinsify) {
-            Debug.scope("InstallSnippets", new DebugDumpScope("InstallSnippets"), new Runnable() {
+            Debug.scope("InstallSnippets", new Object[] {new DebugDumpScope("InstallSnippets"), compiler}, new Runnable() {
 
                 @Override
                 public void run() {
@@ -214,16 +215,16 @@
         CompilationStatistics.clear("bootstrap");
 
         TTY.println(" in %d ms", System.currentTimeMillis() - startTime);
-        if (compiler.getCache() != null) {
-            compiler.getCache().clear();
+        if (graalRuntime.getCache() != null) {
+            graalRuntime.getCache().clear();
         }
         System.gc();
         CompilationStatistics.clear("bootstrap2");
-        MethodEntryCounters.printCounters(compiler);
+        MethodEntryCounters.printCounters(graalRuntime);
     }
 
     private void enqueue(Method m) throws Throwable {
-        JavaMethod javaMethod = compiler.getRuntime().getResolvedJavaMethod(m);
+        JavaMethod javaMethod = graalRuntime.getRuntime().getResolvedJavaMethod(m);
         assert !Modifier.isAbstract(((HotSpotResolvedJavaMethod) javaMethod).accessFlags()) && !Modifier.isNative(((HotSpotResolvedJavaMethod) javaMethod).accessFlags()) : javaMethod;
         compileMethod((HotSpotResolvedJavaMethod) javaMethod, 0, false, 10);
     }
@@ -285,7 +286,7 @@
             }
         }
         CompilationStatistics.clear("final");
-        MethodEntryCounters.printCounters(compiler);
+        MethodEntryCounters.printCounters(graalRuntime);
         HotSpotXirGenerator.printCounters(TTY.out().out());
         CheckCastSnippets.printCounters(TTY.out().out());
     }
@@ -374,7 +375,7 @@
 
             final OptimisticOptimizations optimisticOpts = new OptimisticOptimizations(method);
             int id = compileTaskIds.incrementAndGet();
-            CompilationTask task = CompilationTask.create(compiler, createPhasePlan(optimisticOpts), optimisticOpts, method, id, priority);
+            CompilationTask task = CompilationTask.create(graalRuntime, createPhasePlan(optimisticOpts), optimisticOpts, method, id, priority);
             if (blocking) {
                 task.runCompilation();
             } else {
@@ -483,7 +484,7 @@
 
     public PhasePlan createPhasePlan(OptimisticOptimizations optimisticOpts) {
         PhasePlan phasePlan = new PhasePlan();
-        GraphBuilderPhase graphBuilderPhase = new GraphBuilderPhase(compiler.getRuntime(), GraphBuilderConfiguration.getDefault(), optimisticOpts);
+        GraphBuilderPhase graphBuilderPhase = new GraphBuilderPhase(graalRuntime.getRuntime(), GraphBuilderConfiguration.getDefault(), optimisticOpts);
         phasePlan.addPhase(PhasePosition.AFTER_PARSING, graphBuilderPhase);
         if (GraalOptions.Intrinsify) {
             phasePlan.addPhase(PhasePosition.HIGH_LEVEL, intrinsifyArrayCopy);
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotRuntime.java	Wed Jul 04 21:56:48 2012 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotRuntime.java	Wed Jul 04 21:57:49 2012 +0200
@@ -180,11 +180,6 @@
     }
 
     @Override
-    public String disassemble(ResolvedJavaMethod method) {
-        return compiler.getCompilerToVM().disassembleJava((HotSpotResolvedJavaMethod) method);
-    }
-
-    @Override
     public ResolvedJavaType getResolvedJavaType(Kind kind) {
         return (ResolvedJavaType) compiler.getCompilerToVM().getType(kind.toJavaClass());
     }
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/snippets/NewObjectSnippets.java	Wed Jul 04 21:56:48 2012 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/snippets/NewObjectSnippets.java	Wed Jul 04 21:57:49 2012 +0200
@@ -29,6 +29,7 @@
 import static com.oracle.graal.snippets.SnippetTemplate.Arguments.*;
 import static com.oracle.graal.snippets.nodes.ExplodeLoopNode.*;
 import static com.oracle.max.asm.target.amd64.AMD64.*;
+import static com.oracle.max.criutils.UnsignedMath.*;
 
 import com.oracle.graal.api.code.*;
 import com.oracle.graal.api.meta.*;
@@ -47,7 +48,6 @@
 import com.oracle.graal.snippets.SnippetTemplate.Arguments;
 import com.oracle.graal.snippets.SnippetTemplate.Cache;
 import com.oracle.graal.snippets.SnippetTemplate.Key;
-import com.oracle.max.criutils.*;
 
 /**
  * Snippets used for implementing NEW, ANEWARRAY and NEWARRAY.
@@ -126,7 +126,7 @@
                     @ConstantParameter("log2ElementSize") int log2ElementSize,
                     @ConstantParameter("type") ResolvedJavaType type,
                     @ConstantParameter("wordKind") Kind wordKind) {
-        if (UnsignedMath.aboveOrEqual(length, MAX_ARRAY_FAST_PATH_ALLOCATION_LENGTH)) {
+        if (!belowThan(length, MAX_ARRAY_FAST_PATH_ALLOCATION_LENGTH)) {
             // This handles both negative array sizes and very large array sizes
             DeoptimizeNode.deopt(DeoptimizationAction.InvalidateReprofile, DeoptimizationReason.RuntimeConstraint);
         }
@@ -268,7 +268,7 @@
                 ConstantNode size = ConstantNode.forInt(-1, graph);
                 InitializeArrayNode initializeNode = graph.add(new InitializeArrayNode(zero, lengthNode, size, arrayType));
                 graph.replaceFixedWithFixed(newArrayNode, initializeNode);
-            } else if (length != null && UnsignedMath.belowThan(length, MAX_ARRAY_FAST_PATH_ALLOCATION_LENGTH)) {
+            } else if (length != null && belowThan(length, MAX_ARRAY_FAST_PATH_ALLOCATION_LENGTH)) {
                 // Calculate aligned size
                 int size = getArraySize(length, alignment, headerSize, log2ElementSize);
                 ConstantNode sizeNode = ConstantNode.forInt(size, graph);
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/snippets/UnsignedMathSnippets.java	Wed Jul 04 21:57:49 2012 +0200
@@ -0,0 +1,86 @@
+/*
+ * 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.hotspot.snippets;
+
+import static com.oracle.graal.nodes.MaterializeNode.*;
+import static com.oracle.graal.nodes.calc.Condition.*;
+
+import com.oracle.graal.snippets.*;
+import com.oracle.max.criutils.*;
+
+/**
+ * Snippets for {@link UnsignedMath}.
+ */
+@ClassSubstitution(UnsignedMath.class)
+public class UnsignedMathSnippets implements SnippetsInterface {
+
+    public static boolean aboveThan(int a, int b) {
+        return materialize(BT, b, a);
+    }
+
+    public static boolean aboveOrEqual(int a, int b) {
+        return !materialize(BT, a, b);
+    }
+
+    /**
+     * Unsigned comparison belowThan for two numbers.
+     */
+    public static boolean belowThan(int a, int b) {
+        return materialize(BT, a, b);
+    }
+
+    /**
+     * Unsigned comparison belowOrEqual for two numbers.
+     */
+    public static boolean belowOrEqual(int a, int b) {
+        return !materialize(BT, b, a);
+    }
+
+    /**
+     * Unsigned comparison aboveThan for two numbers.
+     */
+    public static boolean aboveThan(long a, long b) {
+        return materialize(BT, b, a);
+    }
+
+    /**
+     * Unsigned comparison aboveOrEqual for two numbers.
+     */
+    public static boolean aboveOrEqual(long a, long b) {
+        return !materialize(BT, a, b);
+    }
+
+    /**
+     * Unsigned comparison belowThan for two numbers.
+     */
+    public static boolean belowThan(long a, long b) {
+        return materialize(BT, a, b);
+    }
+
+    /**
+     * Unsigned comparison belowOrEqual for two numbers.
+     */
+    public static boolean belowOrEqual(long a, long b) {
+        return !materialize(BT, b, a);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.java/src/com/oracle/graal/java/BytecodeDisassembler.java	Wed Jul 04 21:57:49 2012 +0200
@@ -0,0 +1,231 @@
+/*
+ * 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.java;
+
+import static com.oracle.graal.bytecode.Bytecodes.*;
+
+import com.oracle.graal.api.meta.*;
+import com.oracle.graal.bytecode.*;
+
+/**
+ * Utility for producing a {@code javap}-like disassembly of bytecode.
+ */
+public class BytecodeDisassembler {
+
+    /**
+     * Specifies if the disassembly for a single instruction can span multiple lines.
+     */
+    private final boolean multiline;
+
+    public BytecodeDisassembler(boolean multiline) {
+        this.multiline = multiline;
+    }
+
+    public BytecodeDisassembler() {
+        this(true);
+    }
+
+    /**
+     * Disassembles the bytecode of a given method in a {@code javap}-like format.
+     *
+     * @return {@code null} if {@code method} has no bytecode (e.g., it is native or abstract)
+     */
+    public String disassemble(ResolvedJavaMethod method) {
+        if (method.code() == null) {
+            return null;
+        }
+        ConstantPool cp = method.getConstantPool();
+        BytecodeStream stream = new BytecodeStream(method.code());
+        StringBuilder buf = new StringBuilder();
+        int opcode = stream.currentBC();
+        while (opcode != Bytecodes.END) {
+            int bci = stream.currentBCI();
+            String mnemonic = Bytecodes.nameOf(opcode);
+            buf.append(String.format("%4d: %-14s", bci, mnemonic));
+            if (stream.nextBCI() > bci + 1) {
+                switch (opcode) {
+                    case BIPUSH         : buf.append(stream.readByte()); break;
+                    case SIPUSH         : buf.append(stream.readShort()); break;
+                    case NEW            :
+                    case CHECKCAST      :
+                    case INSTANCEOF     :
+                    case ANEWARRAY      : {
+                        int cpi = stream.readCPI();
+                        JavaType type = cp.lookupType(cpi, opcode);
+                        buf.append(String.format("#%-10d // %s", cpi, MetaUtil.toJavaName(type)));
+                        break;
+                    }
+                    case GETSTATIC      :
+                    case PUTSTATIC      :
+                    case GETFIELD       :
+                    case PUTFIELD       : {
+                        int cpi = stream.readCPI();
+                        JavaField field = cp.lookupField(cpi, opcode);
+                        String fieldDesc = field.holder().name().equals(method.holder().name()) ? MetaUtil.format("%n:%T", field) : MetaUtil.format("%H.%n:%T", field);
+                        buf.append(String.format("#%-10d // %s", cpi, fieldDesc));
+                        break;
+                    }
+                    case INVOKEVIRTUAL  :
+                    case INVOKESPECIAL  :
+                    case INVOKESTATIC   : {
+                        int cpi = stream.readCPI();
+                        JavaMethod callee = cp.lookupMethod(cpi, opcode);
+                        String calleeDesc = callee.holder().name().equals(method.holder().name()) ? MetaUtil.format("%n:(%P)%R", callee) : MetaUtil.format("%H.%n:(%P)%R", callee);
+                        buf.append(String.format("#%-10d // %s", cpi, calleeDesc));
+                        break;
+                    }
+                    case INVOKEINTERFACE: {
+                        int cpi = stream.readCPI();
+                        JavaMethod callee = cp.lookupMethod(cpi, opcode);
+                        String calleeDesc = callee.holder().name().equals(method.holder().name()) ? MetaUtil.format("%n:(%P)%R", callee) : MetaUtil.format("%H.%n:(%P)%R", callee);
+                        buf.append(String.format("#%-10s // %s", cpi + ", " + stream.readUByte(bci + 3), calleeDesc));
+                        break;
+                    }
+                    case LDC            :
+                    case LDC_W          :
+                    case LDC2_W         : {
+                        int cpi = stream.readCPI();
+                        Object constant = cp.lookupConstant(cpi);
+                        String desc = null;
+                        if (constant instanceof Constant) {
+                            Constant c = ((Constant) constant);
+                            switch (c.kind) {
+                                case Int :
+                                    desc = String.valueOf(c.asInt());
+                                    break;
+                                case Float:
+                                    desc = String.valueOf(c.asFloat());
+                                    break;
+                                case Object:
+                                    desc = Kind.Object.format(c.asObject());
+                                    break;
+                                case Double :
+                                    desc = String.valueOf(c.asDouble());
+                                    break;
+                                case Long :
+                                    desc = String.valueOf(c.asLong());
+                                    break;
+                                default:
+                                    desc = c.toString();
+                                    break;
+                            }
+                        } else {
+                            desc = constant.toString();
+                        }
+                        if (!multiline) {
+                            desc.replaceAll("\\n", "");
+                        }
+                        buf.append(String.format("#%-10d // %s", cpi, desc));
+                        break;
+                    }
+                    case RET            :
+                    case ILOAD          :
+                    case LLOAD          :
+                    case FLOAD          :
+                    case DLOAD          :
+                    case ALOAD          :
+                    case ISTORE         :
+                    case LSTORE         :
+                    case FSTORE         :
+                    case DSTORE         :
+                    case ASTORE         : {
+                        buf.append(String.format("%d", stream.readLocalIndex()));
+                        break;
+                    }
+                    case IFEQ           :
+                    case IFNE           :
+                    case IFLT           :
+                    case IFGE           :
+                    case IFGT           :
+                    case IFLE           :
+                    case IF_ICMPEQ      :
+                    case IF_ICMPNE      :
+                    case IF_ICMPLT      :
+                    case IF_ICMPGE      :
+                    case IF_ICMPGT      :
+                    case IF_ICMPLE      :
+                    case IF_ACMPEQ      :
+                    case IF_ACMPNE      :
+                    case GOTO           :
+                    case JSR            :
+                    case IFNULL         :
+                    case IFNONNULL      :
+                    case GOTO_W         :
+                    case JSR_W          : {
+                        buf.append(String.format("%d", stream.readBranchDest()));
+                        break;
+                    }
+                    case LOOKUPSWITCH   :
+                    case TABLESWITCH    : {
+                        BytecodeSwitch bswitch = opcode == LOOKUPSWITCH ? new BytecodeLookupSwitch(stream, bci) : new BytecodeTableSwitch(stream, bci);
+                        if (multiline) {
+                            buf.append("{ // " + bswitch.numberOfCases());
+                            for (int i = 0; i < bswitch.numberOfCases(); i++) {
+                                buf.append(String.format("%n           %7d: %d", bswitch.keyAt(i), bswitch.targetAt(i)));
+                            }
+                            buf.append(String.format("%n           default: %d", bswitch.defaultTarget()));
+                            buf.append(String.format("%n      }"));
+                        } else {
+                            buf.append("[" + bswitch.numberOfCases()).append("] {");
+                            for (int i = 0; i < bswitch.numberOfCases(); i++) {
+                                buf.append(String.format("%d: %d", bswitch.keyAt(i), bswitch.targetAt(i)));
+                                if (i != bswitch.numberOfCases() - 1) {
+                                    buf.append(", ");
+                                }
+                            }
+                            buf.append(String.format("} default: %d", bswitch.defaultTarget()));
+                        }
+                        break;
+                    }
+                    case NEWARRAY       : {
+                        int code = stream.readLocalIndex();
+                        // Checkstyle: stop
+                        switch (code) {
+                            case 4:  buf.append("boolean"); break;
+                            case 5:  buf.append("char"); break;
+                            case 6:  buf.append("float"); break;
+                            case 7:  buf.append("double"); break;
+                            case 8:  buf.append("byte"); break;
+                            case 9:  buf.append("short"); break;
+                            case 10: buf.append("int"); break;
+                            case 11: buf.append("long"); break;
+                        }
+                        // Checkstyle: resume
+
+                        break;
+                    }
+                    case MULTIANEWARRAY : {
+                        int cpi = stream.readCPI();
+                        JavaType type = cp.lookupType(cpi, opcode);
+                        buf.append(String.format("#%-10s // %s", cpi + ", " + stream.readUByte(bci + 3), MetaUtil.toJavaName(type)));
+                        break;
+                    }
+                }
+            }
+            buf.append(String.format("%n"));
+            stream.next();
+            opcode = stream.currentBC();
+        }
+        return buf.toString();
+    }
+}
--- a/graal/com.oracle.graal.java/src/com/oracle/graal/java/GraphBuilderPhase.java	Wed Jul 04 21:56:48 2012 +0200
+++ b/graal/com.oracle.graal.java/src/com/oracle/graal/java/GraphBuilderPhase.java	Wed Jul 04 21:57:49 2012 +0200
@@ -649,7 +649,7 @@
             ResolvedJavaType resolvedType = (ResolvedJavaType) type;
             ConstantNode hub = appendConstant(resolvedType.getEncoding(JavaType.Representation.ObjectHub));
             InstanceOfNode instanceOfNode = new InstanceOfNode(hub, (ResolvedJavaType) type, object, getProfileForTypeCheck(resolvedType));
-            frameState.ipush(append(MaterializeNode.create(currentGraph.unique(instanceOfNode), currentGraph)));
+            frameState.ipush(append(MaterializeNode.create(currentGraph.unique(instanceOfNode))));
         } else {
             BlockPlaceholderNode successor = currentGraph.add(new BlockPlaceholderNode());
             DeoptimizeNode deopt = currentGraph.add(new DeoptimizeNode(DeoptimizationAction.InvalidateRecompile, DeoptimizationReason.Unresolved, graphId));
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/IfNode.java	Wed Jul 04 21:56:48 2012 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/IfNode.java	Wed Jul 04 21:57:49 2012 +0200
@@ -146,7 +146,7 @@
                                 return;
                             }
                             if (trueValue.isConstant() && falseValue.isConstant()) {
-                                MaterializeNode materialize = MaterializeNode.create(compare(), graph(), trueValue, falseValue);
+                                MaterializeNode materialize = MaterializeNode.create(compare(), trueValue, falseValue);
                                 ((StructuredGraph) graph()).replaceFloating(singlePhi, materialize);
                                 removeEmptyIf(tool);
                                 return;
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/MaterializeNode.java	Wed Jul 04 21:56:48 2012 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/MaterializeNode.java	Wed Jul 04 21:57:49 2012 +0200
@@ -27,18 +27,59 @@
 
 public final class MaterializeNode extends ConditionalNode {
 
+    private static CompareNode createCompareNode(Condition condition, ValueNode x, ValueNode y) {
+        assert x.kind() == y.kind();
+        assert condition.isCanonical() : "condition is not canonical: " + condition;
+
+        assert !x.kind().isFloatOrDouble();
+        CompareNode comparison;
+        if (condition == Condition.EQ) {
+            if (x.kind().isObject()) {
+                comparison = new ObjectEqualsNode(x, y);
+            } else {
+                assert x.kind().stackKind().isInt() || x.kind().isLong();
+                comparison = new IntegerEqualsNode(x, y);
+            }
+        } else if (condition == Condition.LT) {
+            assert x.kind().stackKind().isInt() || x.kind().isLong();
+            comparison = new IntegerLessThanNode(x, y);
+        } else {
+            assert condition == Condition.BT;
+            assert x.kind().stackKind().isInt() || x.kind().isLong();
+            comparison = new IntegerBelowThanNode(x, y);
+        }
+
+        return x.graph().unique(comparison);
+    }
+
+    private MaterializeNode(Condition condition, ValueNode x, ValueNode y) {
+        this(createCompareNode(condition, x, y), ConstantNode.forInt(1, x.graph()), ConstantNode.forInt(0, x.graph()));
+    }
+
     private MaterializeNode(BooleanNode condition, ValueNode trueValue, ValueNode falseValue) {
         super(condition, trueValue, falseValue);
     }
 
-    public static MaterializeNode create(BooleanNode condition, Graph graph, ValueNode trueValue, ValueNode falseValue) {
+    public static MaterializeNode create(BooleanNode condition, ValueNode trueValue, ValueNode falseValue) {
+        Graph graph = condition.graph();
         MaterializeNode result = new MaterializeNode(condition, trueValue, falseValue);
         return graph.unique(result);
 
     }
 
-    public static MaterializeNode create(BooleanNode condition, Graph graph) {
-        return create(condition, graph, ConstantNode.forInt(1, graph), ConstantNode.forInt(0, graph));
+    public static MaterializeNode create(BooleanNode condition) {
+        return create(condition, ConstantNode.forInt(1, condition.graph()), ConstantNode.forInt(0, condition.graph()));
     }
 
+    @NodeIntrinsic
+    @SuppressWarnings("unused")
+    public static boolean materialize(@ConstantNodeParameter Condition condition, int x, int y) {
+        throw new UnsupportedOperationException("This method may only be compiled with the Graal compiler");
+    }
+
+    @NodeIntrinsic
+    @SuppressWarnings("unused")
+    public static boolean materialize(@ConstantNodeParameter Condition condition, long x, long y) {
+        throw new UnsupportedOperationException("This method may only be compiled with the Graal compiler");
+    }
 }
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/NormalizeCompareNode.java	Wed Jul 04 21:56:48 2012 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/NormalizeCompareNode.java	Wed Jul 04 21:57:49 2012 +0200
@@ -58,8 +58,8 @@
             lessComp = graph.unique(new IntegerLessThanNode(x(), y()));
         }
 
-        MaterializeNode equalValue = MaterializeNode.create(equalComp, graph, ConstantNode.forInt(0, graph), ConstantNode.forInt(1, graph));
-        MaterializeNode value =  MaterializeNode.create(lessComp, graph, ConstantNode.forInt(-1, graph), equalValue);
+        MaterializeNode equalValue = MaterializeNode.create(equalComp, ConstantNode.forInt(0, graph), ConstantNode.forInt(1, graph));
+        MaterializeNode value =  MaterializeNode.create(lessComp, ConstantNode.forInt(-1, graph), equalValue);
 
         graph.replaceFloating(this, value);
     }
--- a/graal/com.oracle.graal.printer/src/com/oracle/graal/printer/BasicIdealGraphPrinter.java	Wed Jul 04 21:56:48 2012 +0200
+++ b/graal/com.oracle.graal.printer/src/com/oracle/graal/printer/BasicIdealGraphPrinter.java	Wed Jul 04 21:57:49 2012 +0200
@@ -134,6 +134,12 @@
         stream.println("  ]]></bytecodes>");
     }
 
+    protected void printBytecodes(String disassembly) {
+        beginBytecodes();
+        stream.println(disassembly);
+        endBytecodes();
+    }
+
     protected void endMethod() {
         stream.println(" </method>");
     }
--- a/graal/com.oracle.graal.printer/src/com/oracle/graal/printer/CFGPrinterObserver.java	Wed Jul 04 21:56:48 2012 +0200
+++ b/graal/com.oracle.graal.printer/src/com/oracle/graal/printer/CFGPrinterObserver.java	Wed Jul 04 21:57:49 2012 +0200
@@ -24,6 +24,7 @@
 
 import java.io.*;
 import java.util.*;
+import java.util.concurrent.atomic.*;
 
 import com.oracle.graal.alloc.util.*;
 import com.oracle.graal.api.code.*;
@@ -46,6 +47,7 @@
 public class CFGPrinterObserver implements DebugDumpHandler {
 
     private CFGPrinter cfgPrinter;
+    private File cfgFile;
     private ResolvedJavaMethod curMethod;
     private List<String> curDecorators = Collections.emptyList();
 
@@ -63,7 +65,7 @@
      * in the current debug scope and opens a new compilation scope if this pair
      * does not match the current method and decorator pair.
      */
-    private void checkMethodScope() {
+    private boolean checkMethodScope() {
         ResolvedJavaMethod method = null;
         ArrayList<String> decorators = new ArrayList<>();
         for (Object o : Debug.context()) {
@@ -83,14 +85,22 @@
             }
         }
 
+        if (method == null) {
+            return false;
+        }
+
         if (method != curMethod || !curDecorators.equals(decorators)) {
             cfgPrinter.printCompilation(method);
-            TTY.println("CFGPrinter: Dumping method %s", method);
+            TTY.println("CFGPrinter: Dumping method %s to %s", method, cfgFile);
             curMethod = method;
             curDecorators = decorators;
         }
+        return true;
     }
 
+    private static final long timestamp = System.currentTimeMillis();
+    private static final AtomicInteger uniqueId = new AtomicInteger();
+
     public void dumpSandboxed(Object object, String message) {
         GraalCompiler compiler = Debug.contextLookup(GraalCompiler.class);
         if (compiler == null) {
@@ -98,17 +108,19 @@
         }
 
         if (cfgPrinter == null) {
-            File file = new File("compilations-" + System.currentTimeMillis() + ".cfg");
+            cfgFile = new File("compilations-" + timestamp + "_" + uniqueId.incrementAndGet() + ".cfg");
             try {
-                OutputStream out = new BufferedOutputStream(new FileOutputStream(file));
+                OutputStream out = new BufferedOutputStream(new FileOutputStream(cfgFile));
                 cfgPrinter = new CFGPrinter(out);
             } catch (FileNotFoundException e) {
-                throw new GraalInternalError("Could not open " + file.getAbsolutePath());
+                throw new GraalInternalError("Could not open " + cfgFile.getAbsolutePath());
             }
-            TTY.println("CFGPrinter: Output to file %s", file);
+            TTY.println("CFGPrinter: Output to file %s", cfgFile);
         }
 
-        checkMethodScope();
+        if (!checkMethodScope()) {
+            return;
+        }
 
         cfgPrinter.target = compiler.target;
         if (object instanceof LIR) {
@@ -126,7 +138,9 @@
         if (object instanceof BciBlockMapping) {
             BciBlockMapping blockMap = (BciBlockMapping) object;
             cfgPrinter.printCFG(message, blockMap);
-            cfgPrinter.printBytecodes(runtime.disassemble(blockMap.method));
+            if (blockMap.method.code() != null) {
+                cfgPrinter.printBytecodes(new BytecodeDisassembler(false).disassemble(blockMap.method));
+            }
 
         } else if (object instanceof LIR) {
             cfgPrinter.printCFG(message, cfgPrinter.lir.codeEmittingOrder());
--- a/graal/com.oracle.graal.printer/src/com/oracle/graal/printer/IdealGraphPrinter.java	Wed Jul 04 21:56:48 2012 +0200
+++ b/graal/com.oracle.graal.printer/src/com/oracle/graal/printer/IdealGraphPrinter.java	Wed Jul 04 21:57:49 2012 +0200
@@ -27,12 +27,12 @@
 import java.util.Map.Entry;
 
 import com.oracle.graal.api.meta.*;
-import com.oracle.graal.bytecode.*;
 import com.oracle.graal.compiler.schedule.*;
 import com.oracle.graal.graph.*;
 import com.oracle.graal.graph.Node.Verbosity;
 import com.oracle.graal.graph.NodeClass.NodeClassIterator;
 import com.oracle.graal.graph.NodeClass.Position;
+import com.oracle.graal.java.*;
 import com.oracle.graal.lir.cfg.*;
 import com.oracle.graal.nodes.*;
 
@@ -57,23 +57,8 @@
         printProperty("name", name);
         endProperties();
         beginMethod(name, shortName, bci);
-        if (method != null) {
-            beginBytecodes();
-            BytecodeStream bytecodes = new BytecodeStream(method.code());
-            while (bytecodes.currentBC() != Bytecodes.END) {
-                int startBCI = bytecodes.currentBCI();
-                String mnemonic = Bytecodes.nameOf(bytecodes.currentBC());
-                int[] extra = null;
-                if (bytecodes.nextBCI() > startBCI + 1) {
-                    extra = new int[bytecodes.nextBCI() - (startBCI + 1)];
-                    for (int i = 0; i < extra.length; i++) {
-                        extra[i] = bytecodes.readUByte(startBCI + 1 + i);
-                    }
-                }
-                printBytecode(startBCI, mnemonic, extra);
-                bytecodes.next();
-            }
-            endBytecodes();
+        if (method != null && method.code() != null) {
+            printBytecodes(new BytecodeDisassembler(false).disassemble(method));
         }
         endMethod();
     }
--- a/graal/com.oracle.graal.snippets/src/com/oracle/graal/snippets/WordTypeRewriterPhase.java	Wed Jul 04 21:56:48 2012 +0200
+++ b/graal/com.oracle.graal.snippets/src/com/oracle/graal/snippets/WordTypeRewriterPhase.java	Wed Jul 04 21:57:49 2012 +0200
@@ -199,7 +199,7 @@
         ValueNode a = mirror ? right : left;
         ValueNode b = mirror ? left : right;
 
-        MaterializeNode materialize = MaterializeNode.create(graph.unique(new IntegerBelowThanNode(a, b)), graph);
+        MaterializeNode materialize = MaterializeNode.create(graph.unique(new IntegerBelowThanNode(a, b)));
 
         ValueNode op;
         if (condition.canonicalNegate()) {
--- a/graal/com.oracle.max.criutils/src/com/oracle/max/criutils/UnsignedMath.java	Wed Jul 04 21:56:48 2012 +0200
+++ b/graal/com.oracle.max.criutils/src/com/oracle/max/criutils/UnsignedMath.java	Wed Jul 04 21:57:49 2012 +0200
@@ -22,6 +22,8 @@
  */
 package com.oracle.max.criutils;
 
+//JaCoCo Exclude
+
 /**
  * Utilities for unsigned comparisons.
  * All methods have correct, but slow, standard Java implementations so that
--- a/src/share/vm/graal/graalCompilerToVM.cpp	Wed Jul 04 21:56:48 2012 +0200
+++ b/src/share/vm/graal/graalCompilerToVM.cpp	Wed Jul 04 21:57:49 2012 +0200
@@ -929,25 +929,6 @@
   return JNIHandles::make_local(result());
 }
 
-// public String disassembleJava(HotSpotResolvedJavaMethod method);
-JNIEXPORT jobject JNICALL Java_com_oracle_graal_hotspot_bridge_CompilerToVMImpl_disassembleJava(JNIEnv *env, jobject, jobject hotspot_method) {
-  TRACE_graal_3("CompilerToVM::disassembleJava");
-
-  // Important: The bytecode printing functions are all NOT PRODUCT code, so this method returns an empty string for a product VM build.
-
-  VM_ENTRY_MARK;
-  ResourceMark rm;
-  HandleMark hm;
-
-  methodHandle method = getMethodFromHotSpotMethod(hotspot_method);
-  // Note: cannot use resource-allocated stringStream because print_code_on has its own ResourceMark.
-  bufferedStream(st);
-  method->print_codes_on(&st);
-
-  Handle result = java_lang_String::create_from_platform_dependent_str(st.as_string(), CHECK_NULL);
-  return JNIHandles::make_local(result());
-}
-
 // public StackTraceElement JavaMethod_toStackTraceElement(HotSpotResolvedJavaMethod method, int bci);
 JNIEXPORT jobject JNICALL Java_com_oracle_graal_hotspot_bridge_CompilerToVMImpl_JavaMethod_1toStackTraceElement(JNIEnv *env, jobject, jobject hotspot_method, int bci) {
   TRACE_graal_3("CompilerToVM::JavaMethod_toStackTraceElement");
@@ -1135,7 +1116,6 @@
   {CC"getConfiguration",                  CC"()"CONFIG,                                         FN_PTR(getConfiguration)},
   {CC"installMethod",                     CC"("TARGET_METHOD"Z"HS_CODE_INFO")"HS_COMP_METHOD,   FN_PTR(installMethod)},
   {CC"disassembleNative",                 CC"([BJ)"STRING,                                      FN_PTR(disassembleNative)},
-  {CC"disassembleJava",                   CC"("RESOLVED_METHOD")"STRING,                        FN_PTR(disassembleJava)},
   {CC"JavaMethod_toStackTraceElement",      CC"("RESOLVED_METHOD"I)"STACK_TRACE_ELEMENT,          FN_PTR(JavaMethod_1toStackTraceElement)},
   {CC"executeCompiledMethod",             CC"("HS_COMP_METHOD OBJECT OBJECT OBJECT")"OBJECT,    FN_PTR(executeCompiledMethod)},
   {CC"executeCompiledMethodVarargs",      CC"("HS_COMP_METHOD "["OBJECT")"OBJECT,               FN_PTR(executeCompiledMethodVarargs)},